无法解决匈牙利算法

时间:2014-11-12 18:29:26

标签: algorithm graph hungarian-algorithm

我试图实现一个函数来解决hungarian algorithm,我认为我有一些误解了算法。

出于测试目的,我使用谷歌的这个c ++ code应该有效。

但是当我测试这个14x11矩阵时,它说无法解决

  

[0 0 0 0 0 0 0 0 0 0 0]

     

[53 207 256 207 231 348 348 348 231 244 244]

     

[240 33 67 33 56 133 133 133 56 33 33]

     

[460 107 200 107 122 324 324 324 122 33 33]

     

[167 340 396 340 422 567 567 567 422 442 442]

     

[167 367 307 367 433 336 336 336 433 158 158]

     

[160 20 37 20 31 70 70 70 31 22 22]

     

[200 307 393 307 222 364 364 364 222 286 286]

     

[33 153 152 153 228 252 252 252 228 78 78]

     

[93 140 185 140 58 118 118 118 58 44 44]

     

[0 7 22 7 19 58 58 58 19 0 0]

     

[67 153 241 153 128 297 297 297 128 39 39]

     

[73 253 389 253 253 539 539 539 253 36 36]

     

[173 267 270 267 322 352 352 352 322 231 231]

用于创建数组的C ++代码:(如果有人想通过我提供的C ++示例来测试它)

  

int r [14 * 11] = {0,0,0,0,0,0,0,0,0,0,53,207,256,207,231,348,348,348, 231,244,244,240,33,67,33,56,133,133,133,56,33,33,460,107,200,107,122,324,324,324,122,33,33, 167,340,396,340,422,567,567,567,422,442,442,167,367,307,367,433,336,336,336,433,158,158,160,20,37, 20,31,70,70,70,31,22,22,200,307,393,307,222,364,364,364,222,286,286,33,153,152,153,228,252, 252,252,228,78,78,93,140,​​185,140,​​58,118,118,118,58,44,44,0,7,22,7,19,58,58,58,19, 0,0,67,153,241,153,128,297,297,297,128,39,39,73,253,389,253,253,539,539,539,253,36,36,173, 267,270,267,322,352,352,352,322,231,231};

如果我运行我的实现以减少零的数量(因此它们可以被最小行数覆盖 - 在顶层提供的wikihow链接中的第9步 - )我得到以下矩阵找到行和列唯一的0组合。

问题是无法解决,因为第10列和第11列(粗体)每个只有一个0并且它在同一行。

  

第1行:[240 140 225 140 206 339 339 339 206 215 215 0 0 0]

     

第2行:[254 0 37 0 43 58 58 58 43 38 38 67 67 67]

     

第3行:[0 107 158 107 151 206 206 206 151 182 182 0 0 0]

     

第4行:[0 253 245 253 304 235 235 235 304 402 402 220 220 220]

     

第5行:[300 27 56 27 11 0 0 0 11 0 0 227 227 227]

     

第6行:[300 0 145 0 0 230 230 230 0 284 284 227 227 227]

     

第7行:[80 120 188 120 176 269 269 269 176 193 193 0 0 0]

     

第8行:[207 0 0 0 151 143 143 143 151 96 96 167 167 167]

     

第9行:[229 9 95 9 0 110 110 110 0 159 159 22 22 22]

     

第10行:[147 0 40 0 148 221 221 221 148 171 171 0 0 0]

     

第11行:[240 133 203 133 187 282 282 282 187 215 215 0 0 0]

     

第12行:[189 3 0 3 94 58 58 58 94 192 192 16 16 16]

     

第13行:[367 87 36 87 153 0 0 0 153 379 379 200 200 200]

     

第14行:[194 0 82 0 11 115 115 115 11 112 112 127 127 127]

这种方法有什么限制吗?或者只是我,算法执行不好?在这种情况下,为什么"应该工作"例子不工作?

任何建议都会有所体现,或者如果您知道任何技巧或建议,以帮助找到覆盖零的最小行数,请告知我们。

提前致谢,

2 个答案:

答案 0 :(得分:1)

此方法有任何限制吗? 是。只有在每个步骤中进行了最大分配数量时,该线条绘制方法才能正常工作。 我并不特别想用手工来证明这一点,但我认为你使用的代码并没有达到这个特定矩阵的目的。我决定解决它(从缺乏文档中可以看出最好的拖延,并且它实际上没有用最小行数覆盖所有零的问题。它很难做出作业。

我在网上找到的匈牙利算法的每个实现都不起作用。不幸的是,他们互相复制而没有真正学习它背后的数学,因此他们都弄错了。我已经实现了类似于Munkres在他的文章"分配和运输问题算法"中描述的内容,发表于1957年。我的代码给出了结果:(0,1),(1,3),( 2,8),(3,2),(9,12),(10,11),(4,9),(8,7),(5,10),(6,6),(7, 0)最低费用为828.

您可以在此处查看我的代码:http://www.mediafire.com/view/1yss74lxb7kro2p/APS.h

ps:感谢您提供C ++数组。我不期待自己打字。

pps:这是你的矩阵,间隔适当:

  0   0   0   0   0   0   0   0   0   0   0
 53 207 256 207 231 348 348 348 231 244 244
240  33  67  33  56 133 133 133  56  33  33
460 107 200 107 122 324 324 324 122  33  33
167 340 396 340 422 567 567 567 422 442 442
167 367 307 367 433 336 336 336 433 158 158
160  20  37  20  31  70  70  70  31  22  22
200 307 393 307 222 364 364 364 222 286 286
 33 153 152 153 228 252 252 252 228  78  78
 93 140 185 140  58 118 118 118  58  44  44
  0   7  22   7  19  58  58  58  19   0   0
 67 153 241 153 128 297 297 297 128  39  39
 73 253 389 253 253 539 539 539 253  36  36
173 267 270 267 322 352 352 352 322 231 231

答案 1 :(得分:0)

请注意,在第(2)节提供的链接中,您要添加虚拟行或列以确保矩阵为方形。

现在你有一个方阵,有很多不同的匹配,它们将每一行与自己的列连在一起,反之亦然。解决方案或解决方案只是具有最低成本的这些匹配中的一种,因此总是应该有解决方案。