Skip to content

Instantly share code, notes, and snippets.

@iwat
Last active August 28, 2017 10:35
Show Gist options
  • Save iwat/7230798 to your computer and use it in GitHub Desktop.
Save iwat/7230798 to your computer and use it in GitHub Desktop.
PHP Port of CAT_BAXTER's Python Hungarian Algorithm O(N^3). See: http://pastebin.com/tn6v0HDr
<?php
function hungarian($matrix)
{
$h = count($matrix);
$w = count($matrix[0]);
if ($h < $w)
{
for ($i = $h; $i < $w; ++$i)
{
$matrix[$i] = array_fill(0, $w, INF);
}
}
elseif ($w < $h)
{
foreach ($matrix as &$row)
{
for ($i = $w; $i < $h; ++$i)
{
$row[$i] = INF;
}
}
}
$h = $w = max($h, $w);
$u = array_fill(0, $h, 0);
$v = array_fill(0, $w, 0);
$ind = array_fill(0, $w, -1);
foreach (range(0, $h - 1) as $i)
{
$links = array_fill(0, $w, -1);
$mins = array_fill(0, $w, INF);
$visited = array_fill(0, $w, false);
$markedI = $i;
$markedJ = -1;
$j = 0;
while (true)
{
$j = -1;
foreach (range(0, $h - 1) as $j1)
{
if (!$visited[$j1])
{
$cur = $matrix[$markedI][$j1] - $u[$markedI] - $v[$j1];
if ($cur < $mins[$j1])
{
$mins[$j1] = $cur;
$links[$j1] = $markedJ;
}
if ($j == -1 || $mins[$j1] < $mins[$j])
{
$j = $j1;
}
}
}
$delta = $mins[$j];
foreach (range(0, $w - 1) as $j1)
{
if ($visited[$j1])
{
$u[$ind[$j1]] += $delta;
$v[$j1] -= $delta;
}
else
{
$mins[$j1] -= $delta;
}
}
$u[$i] += $delta;
$visited[$j] = true;
$markedJ = $j;
$markedI = $ind[$j];
if ($markedI == -1)
{
break;
}
}
while (true)
{
if ($links[$j] != -1)
{
$ind[$j] = $ind[$links[$j]];
$j = $links[$j];
}
else
{
break;
}
}
$ind[$j] = $i;
}
$result = array();
foreach (range(0, $w - 1) as $j)
{
$result[$j] = $ind[$j];
}
return $result;
}
$m = [
[ INF, 7858, 8743, 17325, 18510, 9231, 4920, 7056, 9701, 5034, 7825],
[ 8128, INF, 5021, 13603, 19635, 11386, 7075, 8840, 1843, 7189, 9256],
[ 6809, 5364, INF, 8582, 14614, 10067, 5756, 5904, 7207, 3882, 4235],
[ 7849, 5515, 1040, INF, 15654, 11107, 6796, 4713, 7358, 4900, 5275],
[10918, 8365, 4109, 5808, INF, 14176, 9865, 7928, 931, 7991, 8344],
[ 336, 7285, 2830, 11412, 17444, INF, 4347, 6483, 6688, 4461, 7065],
[ 1053, 2938, 3823, 12405, 15835, 4311, INF, 2136, 4781, 114, 2905],
[ 8930, 802, 5823, 14405, 20437, 12188, 7877, INF, 2645, 7429, 10058],
[ 9987, 7434, 3178, 11760, 17792, 13245, 8934, 6997, INF, 7060, 7413],
[10518, 2824, 3709, 12291, 15721, 13776, 9465, 2022, 4667, INF, 7944],
[ 2574, 4459, 5344, 9561, 17356, 5832, 1521, 3657, 6302, 1635, INF]
];
print_r(hungarian($m));
@citerio
Copy link

citerio commented Jul 4, 2016

Hey, I don't understand how you build the $m matrix. If I have this matrix:
10 9 5
9 8 3
6 4 7

How Do I build the $m matrix? (INF gets me confused). Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment