获得最小移动以避免方形重叠的算法

时间:2018-02-04 15:16:11

标签: python python-3.x algorithm graph

我在化学优化程序中遇到的问题与以下问题相同。我找不到一个好的算法:

假设我得到N相同的自由移动具有已知初始经度,固定宽度和具有固定位置的M个相同“障碍物”的正方形。

是否有算法可以获得“最小”总水平移动的那些方格:

  1. 保留正方形
  2. 导致正方形和障碍物没有重叠(“不接触”);没有重叠     在广场之间。
  3. enter image description here

    “最小总移动量”通常描述之前和之后的位置差异。运动后。它可以是偏差之和,或均方根偏差等,以较容易的为准。

    它不一定是 最小值,但需要一个接近的值来进行良好的优化。

    我可能有多达50个方格和25个障碍,所以蛮力太慢了。

    我也找到this post。但它不适用于固定的障碍物,也不一定保持正方形的顺序。

3 个答案:

答案 0 :(得分:1)

O(|sq|^2 * |ob|)一般的复杂性。

ob = [1, 5, 6, 7, 10, 13]
sq = [-3, 0, 3, 6, 8, 14]

f(i, j)代表最佳解决方案,其中sq[i]之前的平方必须适合障碍物ob[j]的左侧。解决f(i, 0)包装1,2,3 ... 50个正方形障碍物为ob[0]的方格。然后,延伸到障碍ob[1],解决方案将是

f(i, 1) = min(
  f(k, 0) + cost of placing squares sq[k+1...i] between ob[0] and ob[1]
)
for all k

按每个j进行操作。

答案 1 :(得分:0)

这个感觉 NP-hard(虽然我不确定;证明尝试可能可能基于一些减少到Bin-packing )。

修改 好吧......也许有一个多项式解决方案(50/50对我来说;我知道它并没有多大帮助)。在这种情况下,以下方法将起作用,将足以有效地解决您的问题,但我们不确定通过一般的NP难度的代理问题来处理它是否是个好主意。

您可以通过(混合)整数编程来解决它,它可以用作精确解算器或提供经验证的近似值。

  • 一般的想法是引入N个连续变量来标记每个块的左侧位置
  • 添加约束:x_i + L <= x_i+1(对于所有连续的对;可能更多的冗余公式有助于:对于所有已排序的对)
    • 这将保留订单&amp;禁止重叠块
    • x:position
    • L:长度
  • 现在,为了不触及障碍,您需要指标约束和一些布尔逻辑:
    • y_i = 1 iff x_i + L <= O_j_s(适用于所有o; s =左手障碍物)
    • z_i = 1 iff O_j_e <= x_i + L(e = right-pos)
    • 禁止两者都是真的:y_i + z_i <= 1(对于所有我)
    • 指标约束将基于其他二元变量y, z
  • 如果目标是最小化轮班的总长度:
    • 目标只是所有x_i与每个块的起始位置之间差异的总和:线性目标!
    • 这个绝对值(需要)可以线性化(不引入离散变量);请参阅lpsolve关于绝对值的教程
  • 如果目标是减少轮班次数:
    • 更多指标约束(被移动&lt; - &gt;开始和结束之间的差异> 0)+这些指标 - 变量的总和 - &gt;线性目标!

这只是一个类似原型的想法。一个人必须仔细定义重叠意味着什么(包括,排他;然后在StackOverflow中描述了很多布尔方法:关键字:范围交集)。要制定指标约束,请查找整数编程指南或启动here

答案 2 :(得分:0)

这是一个关于近似解决方案的想法,也许这有助于开发更好的主意。

您可以先对您的矩形的可能位置进行离散化。对于您的示例,这些位置(间隔)可以是(-5,-3),( - 3,-1),(-1,1),(2,4),(7.5,9.5),(10,12) ,(13,15),...当然,你希望以一种在障碍物限制的空间内尽可能多地适合各种位置的方式进行离散化。

然后构建一个矩阵,其中包含每个块的距离(块必须移动)到每个可能的位置。

使用此矩阵,您可以使用Hungarian Algorithm计算从块到可能位置的最佳分配(产生最小移动)。

执行任务后,您可以通过尽可能多地移动它(直到碰到障碍物)来调整每个方框的位置。