【问题标题】:Fitting Lines into a Grid Matrix [Competition , Not HW]将线拟合到网格矩阵中 [竞争,不是硬件]
【发布时间】:2012-08-19 10:02:32
【问题描述】:

最近在“AmDocs”组织的一次比赛中,我遇到了以下问题:(问题的基本思想)

给定一个固定大小为 12x12 的矩阵。 给你六个长度为 6,5,5,4,3,2 的线段。 矩阵有空格和填充空格。 您必须返回 "Yes" 或 "No" ,是否所有 6 条线段都可以同时适合矩阵。 线条只能水平或垂直放置。

应该使用什么算法来解决这个问题?包装 ?背包?

【问题讨论】:

  • 你有时间限制吗?通常的回溯似乎很好地解决了这个任务

标签: algorithm matrix 2d dynamic-programming knapsack-problem


【解决方案1】:

只是一个想法:
遍历所有二维数组点并创建可用段的集合。在每个步骤中,您将分析 i-1 和 j-1 单元格,如果您有包含该单元格的段,您将增加它们的长度(显然您最多可以找到两个段)。
之后,您应该将数组放入可用的段中,因此在每次插入后,您应该分析所有剩余的段,如果其中任何一个与当前插入的段相交,您应该减小它们的大小或分成两个。

【讨论】:

    【解决方案2】:

    我会使用如下的贪心填充算法:

    for largest_line to smallest_line do
      for first_empty_square_in_matrix to last_empty_square_in_matrix do
        if line_fits_horizontal then
          place_line
          break
        else if_line_fits_vertical then
          place_line
          break
    if all_lines_placed then
      write('Yes')
    else
      write('No')
    

    要优化上述内容,您可能会注意到,如果长度为 n 的水平线无法适合位置 (i,j),那么您无需测试它是否适合水平 (i+1,j) 中的任何一个,(i+2,j)...(i+n,j)。

    【讨论】:

      【解决方案3】:

      我会将问题映射到 SAT 并使用 SAT 求解器。有一个非常自然的映射。定义变量:

      x_s_i_j_d = segment s starts at coordinates (i,j) and goes in direction d
      

      (d 是“右”或“下”)

      首先,遍历所有的段和起始位置,看看在给定起始矩阵的情况下哪些是可行的。 例如,M:

      000000000000
      111111111111
      ...
      

      如果段 1 的长度为 2,则 L_seg1_0_0_down = false,因为它遇到了一个填充的空间。

      然后,编写禁止两个交叉段的子句。如果段 1 和段 2 的长度都是 2,那么我们添加子句:

      (!L_seg1_0_0_right || !L_seg2_1_0_right)
      

      因为如果段 1 使用坐标 (0,0) 和 (1,0),那么段 2 也不能使用 (1,0)。

      最后,添加每个段必须至少使用一次的条件:

      (L_seg1_0_0_right || L_seg1_0_1_right || ...)
      

      对于 seg1 可以去的所有位置。然后把你最​​喜欢的 SAT 求解器扔给它。

      【讨论】:

      • +1,将其映射到 SAT 的想法很棒。它给出了求解方法,证明了这个问题是NP完全的,所以它没有多项式解。关于性能:你能想象结果表达式的大小吗?在逻辑表达式方面使用解决方案会大大减慢程序的速度。我认为通常的回溯会带来更好的性能
      • @dvvrd:这证明 NP 完备性,(硬)约简需要另辟蹊径。
      • @dvvrd:SAT 求解器中的回溯可能与直接解决方案中的回溯相同。
      • 当你把这个问题转到 SAT 上时,你会失去最初的语义。我的意思是,就 SAT 问题而言,对于这个问题来说,一些自然的优化是无法实现的
      猜你喜欢
      • 2014-11-22
      • 2016-04-23
      • 1970-01-01
      • 1970-01-01
      • 2019-03-21
      • 2016-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多