最大化矩阵的最小对角线元素的算法

时间:2013-10-14 23:23:46

标签: algorithm optimization matrix distance linear-programming

假设给出了一个方阵A.我们的目标是按行排列最大化最小对角线元素。换句话说,对于给定的矩阵A,我们有n个对角元素,因此我们有最小$ min {d_i} $。我们的目的是通过行排列到达具有最大最小对角线元素的矩阵。

这就像所有行排列的$ max min {d_i} $。

例如,假设A = [4 3 2 1; 1 4 3 2; 2 1 4 3; 2.5 3.5 4.5 1.5]。对角线是[4,4,4,1.5]。对角线的最小值为1.5。我们可以交换第3行和第4行来获得一个新矩阵\ tilde_A = [4 3 2 1; 1 4 3 2; 2.5 3.5 4.5 1.5; 2 1 4 3]。新的对角线是[4,4,4.5,3],新的最小值为3.理论上,这是我能得到的最好的结果,因为似乎没有更好的选择:3似乎是最大最小值{d_i}。 / p>

在我的问题中,n比1000大得多。我知道有n!行排列所以我不能在理论上经历每个排列。我知道贪心算法会有所帮助 - 我们从第一行开始。如果a_11不是第一列中的最小值,我们将a_11与第一列中的最大元素按行排列交换。然后我们通过比较a_22与第二列中的所有剩余元素(a_12除外)来查看第二行。如果它不是最小的,则交换a_22。 ......等我们一直这样做直到最后一排。

有没有更好的算法呢?

这类似于最小欧几里德匹配,但它们并不相同。

2 个答案:

答案 0 :(得分:3)

假设您想知道是否有比3更好的解决方案。

将矩阵更改为每个严格大于3的元素都为1:

4    3   2   1     1 0 0 0
1    4   3   2     0 1 0 0
2.5 3.5 4.5 1.5 -> 0 1 1 0
2    1   4   3     0 0 1 0

您的问题可以解释为试图在二分图中找到完美匹配,该二分矩阵具有biadjacency graph

在这种情况下,很容易看出无法改善结果,因为无法重新排序行以使最后一列中的对角线条目大于3。

对于更大的矩阵,有一些有效的算法可以确定maximal matchings in bipartite graphs

这表明了一种算法:

  1. 使用二分法查找生成的图形具有完美匹配的最大值
  2. 与最大值完美匹配的赋值将等于行的最佳排列
  3. 修改

    此Python代码说明了如何使用networkx library来确定图表是否与特定截止值具有完美匹配。

    import networkx as nx
    
    A = [[4,3,2,1],
         [1,4,3,2],
         [2,1,4,3],
         [2.5,3.5,4.5,1.5]]
    
    cutoff = 3
    G=nx.DiGraph()
    for i,row in enumerate(A):
        G.add_edge('start','row'+str(i),capacity=1.0)
        G.add_edge('col'+str(i),'end',capacity=1.0)
        for j,e in enumerate(row):
            if e>cutoff:
                G.add_edge('row'+str(i),'col'+str(j),capacity=1.0)
    
    if nx.max_flow(G,'start','end')<len(A):
        print 'No perfect matching'
    else:
        print 'Has a perfect matching'
    

    对于大小为1000 * 1000的随机矩阵,我的计算机需要大约1秒钟。

答案 1 :(得分:2)

如果第i行被移动到第j行,则$ x_ {ij} $为1,否则为零。

您对以下整数程序感兴趣:

max z

\ sum_ {i = 0} ^ n x_ {ij} = 1 \ forall j

\ sum_ {j = 0} ^ n x_ {ij} = 1 \ forall i

A [j,j] x_ {ij}&gt; = z

然后将其插入GLPK,Gurobi或CPLEX。或者,使用您自己的分支和绑定求解来解决IP。