我正在尝试使用Ford-Fulkerson解决数学问题,但我遇到了一些问题。
这是问题
I have a list of employees (Jack, John, Al, ...).
I have a list of roles (R1, R2, R3, ...).
I have a list of working positions (W1, W2, W3, ...).
Every employee has a set of roles, like Jack has R1 and R2, ...
Every working position has a set of roles that can support,
like to work in position W1 you need R1 or R2, ...
我需要找到最佳的员工配置 - 工作岗位,以确保每个工作岗位都有一名具有合适职责的员工(每个岗位一名员工)。
我尝试使用此算法http://www.geeksforgeeks.org/maximum-bipartite-matching/
我建立了一个矩阵,每个员工都有一行,每个工作岗位都有一列。如果X员工可以在Y位置工作,我放入X行,Y列值为1,否则我放0。
上面用PHP重写的算法很有效,直到员工人数<=位置数。
如果我的员工多于职位,算法计算时间往往会分散到无限。
以下是算法代码:
function maxMatch($matrix, $cols) {
$match = array();
foreach ($cols as $v => $item) {
$match[$item] = -1;
}
$result = 0;
foreach ($matrix as $u => $row) {
$seen = array();
foreach ($cols as $v => $item) {
$seen[$item] = 0;
}
if ($this->checkVertex($matrix, $u, $seen, $match)) {
print_r($match);
$result++;
}
}
return $match;
}
function checkVertex($matrix, $u, $seen, &$match) {
foreach ($matrix[$u] as $v => $row) {
if ($matrix[$u][$v] && !$seen[$v]) {
$seen[$v] = TRUE;
if ($match[$v] < 0 || $this->checkVertex($matrix, $match[$v], $seen, $match)) {
$match[$v] = $u;
return TRUE;
}
}
}
return FALSE;
}
一切都像上面链接中的算法,除了我传递$ cols数组,包含列的索引(因为它们是位置ID而不是数字排序)。
这是我创建矩阵的方式:
function createMatrix($year, $month, $day, $shift) {
global $sql;
$result = $sql->query("VERY HUGE SELECT FOR EMPLOYEES AND POSITIONS MATCH");
while ($row = $result->fetch_assoc()) {
$matrix[$row['employee']][$row['position']] = 1;
}
return $matrix;
}
因此我只在员工和职位匹配的地方放置1。
任何人都有任何关于如何解决问题的线索?提前致谢
答案 0 :(得分:0)
您按值传递seen
。这是不正确的。它应该通过引用传递。你现在拥有的实际上是某种回溯(原始算法时间复杂度证明是基于这样一个事实,即在深度优先搜索期间每个顶点最多可以被访问一次,而在当前的实现中并非如此)。这就是它运作缓慢的原因。通过引用传递seen
应该解决它。