矩阵上函数的离散优化

时间:2014-11-29 00:23:14

标签: algorithm optimization matrix mathematical-optimization

这是一个优化问题,我已经从我遇到的一个更具体的问题中简化了,但我不确定这个问题归类于何处,或者获得解决方案的方法(暴力,模拟退火,线性规划?)。任何帮助或参考表示赞赏!

我们有两个MxN矩阵 M1 M2 ,其中每个条目都是1或0。

我试图在尽可能少的时间内从矩阵M1到矩阵M2。

目标是最小化总时间,其中时间由以下定义:

  • 0 - > 1过渡= 1s
  • 1 - > 0过渡= 0.1秒

矩阵可以更改的唯一方法是选择一组行和列,并将拾取的行和列的交叉点上的所有元素切换为0/1,整个转换采用上面指定的时间

示例:

M1
1 1 1
1 1 0
1 0 0

M2
0 0 1
0 1 1
1 1 1

第一次迭代:

  1. 选择 M1 的第2行和第3行以及第2列和第3列。
  2. 将所有交叉元素转换为1

    • 需要1s
  3. M1
    1 1 1
    1 1 1
    1 1 1
    

    第二次迭代:

    1. 选择 M1 的第1行和第1列和第2列。
    2. 将所有交叉元素转换为0

      • 需要0.1秒
    3. M1
      0 0 1
      1 1 1
      1 1 1
      

      第三次迭代:

      1. 选择 M1 的第2行和第1列。
      2. 将所选元素转换为0

        • 需要0.1秒
      3. M1
        0 0 1
        0 1 1
        1 1 1
        

        此处,总时间为1.2秒。

1 个答案:

答案 0 :(得分:2)

对于给定的尺寸,这看起来甚至很难近似。无论如何,这里有几个想法。

当一个单元格需要从0更改为1时,我会写+,当需要在另一个方向上进行更改时,我会写-,当它出现时需要保持原样,我会写0或1(即目前无论如何)。所以例如OP问题中的问题实例看起来像

- - - 1
- - 1 +
- 1 + +
1 + + +

让我们考虑一个稍微容易的单调版本的问题,我们永远不会更改一个单元格两次。

  • 通常需要更多动作,但会给出有用的起点和上限。
  • 在此版本的问题中,我们执行移动的顺序并不重要。
  • 简单的变体可能更有效,例如启发式,例如执行少量的初始0-> 1移动,其中每个+单元改变为1并且其他单元也可能改变,接着是一系列1-> 0移动以改变/修复所有其他细胞

安全收缩问题

[编辑2014年11月12日:修正了以下第3条规则。不幸的是,它的使用频率可能会低得多。]

以下技巧永远不会导致解决方案变得不理想,并且可能会简化问题:

  • 删除任何不包含+的行或列 - 单元格或- - 单元格:不会移动任何行动。
  • 如果有任何相同的行或列,请将其折叠:无论您对此单个折叠的行或列执行什么操作,都可以单独对所有行或列执行操作。
  • 如果任何行只有一个+ - 单元格且没有1个单元格,您可以立即修复包含它的整个列中的所有+个单元格单个0-> 1移动,因为在单调问题中,不可能将该单元固定在与不同列中的任何+ - 单元相同的0-> 1移动中。同样,交换了行和列,并且使用单个- - 单元格而没有0个单元格。

多次应用这些规则可能会进一步简化。

一个非常简单的启发式

您可以在一次移动中更正+-个细胞的整个行或列。因此总是可以用2 * min(宽度,高度)移动来解决问题(2是因为我们可能需要0-> 1和1-> 0移动)。稍微好一点的方法是贪婪地找到需要更正的大多数单元格的行或列,并在一次移动中更正它,在行和列之间自由切换。

最佳移动

假设我们有两个+ - 单元(i,j)和(k,l),其中i <= k且j <= 1。它们可以在相同的0-> 1移动时完全改变它们的相对角和#34; (i,l)和(k,j)是+或1.还要注意,如果(i,j)和(k,l)中的任何一个或两个都是1(而不是+ ),那么他们仍然可以被包含在同一个动作中,即使这一动作对他们中的一个或两个都没有影响。因此,如果我们构建一个图G,其中我们有每个单元的顶点和两个顶点(i,j)和(k,l)之间的边,只要(i,j),(k,l),(i,l )和(k,j)都是+或1,此图中的clique对应于一组单元格,这些单元格可以在单个0-中全部更改为(或保留)1 &gt; 1动。为了找到最好的移动 - 也就是说,将最可能的0变为1的移动 - 我们并不想要图中最大尺寸的团队;我们真正想要的是包含最多+个单元顶点的集团。我们可以使用0/1变量x_i_j来表示会发现这个的ILP来表示顶点(i,j)是否在clique中:

Maximise the sum over all variables x_i_j such that (i, j) is a `+`-cell
Subject to
    x_i_j + x_k_l <= 1 for all i, j, k, l s.t. there is no edge (i, j)-(k, l)
    x_i_j in {0, 1} for all i, j

如果它们之间没有边缘,则约束会阻止两者都被包括在内,并且目标函数试图找到尽可能大的+子集 - 单元顶点满足它们。

当然,相同的程序适用于寻找1-> 0移动。

(你已经遇到了问题,只需构建这个尺寸的图形:N和M大约1000,有大约一百万个顶点,边缘高达一百万。并且找到一个最大值clique是一个NP难题,所以即使对于有数百个边缘的图表它也很慢......)

尽可能少的动作

类似的方法可以告诉我们所需的最小数量的0-> 1(或1-> 0)移动,并且同时为每个移动提供代表性单元。这次我们在同一个图G中寻找最大的independent set

Maximise the sum over all variables x_i_j such that (i, j) is a `+`-cell
Subject to
    x_i_j + x_k_l <= 1 for all i, j, k, l s.t. there is an edge (i, j)-(k, l)
    x_i_j in {0, 1} for all i, j

问题的所有改变都是&#34;没有边缘&#34;改为&#34;边缘&#34;。现在,这会找到一个(可能有多个)最大大小的+ - 单元顶点集,它们之间没有共享边。通过相同的0→1移动(也没有将0-单元或- - 单元改变为1,也不能改变这样的单元对,我们禁止在单调版本的问题中,因为它然后需要第二次改变),因此返回许多顶点,至少需要许多单独的0→1移动。而且因为我们已经要求最大独立集合,所以不再需要移动(如果需要更多移动,则会有一个更大的独立集合,其中包含许多顶点)。