假设给出了一个方阵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。 ......等我们一直这样做直到最后一排。
有没有更好的算法呢?
这类似于最小欧几里德匹配,但它们并不相同。
答案 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。
这表明了一种算法:
此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。