问题陈述
我们有一个雇主想要采访N人,因此会有N个面试时段。每个人都有自由忙碌的时间表。给出一个算法,如果可能的话,将N个人调度到N个插槽中,如果不可能,则返回标志/错误/等。什么是最快的运行时复杂性?
我的方法到目前为止
天真:有N!安排N人的方法。浏览所有这些,对于每个排列,检查它是否可行。 O(n!)回溯:
这是O(n!)最糟糕的情况,我认为 - 这不是更好。
可能有D.P.解决方案 - 但我还没有看到它。
其他想法
问题可以用NxN矩阵表示,其中行是“槽”,列是“人”,值为“1”表示空闲,“0”表示忙。然后,我们在这个矩阵中寻找一个行列交换的Identity Matrix。步骤1& 2正在寻找只有一个“1”的行或列。 (如果矩阵的秩是= N,那表示存在解决方案。但相反的情况并不成立) 另一种看待它的方法是将矩阵视为未加权的有向图边缘矩阵。然后,每个节点代表1个候选和1个时隙。然后我们寻找一组边,以便图中的每个节点都有一个输出边和一个输入边。或者,对于2x节点,它将是一个二分图。
矩阵示例:
1 1 1 1
0 1 1 0
1 0 0 1
1 0 0 1
答案 0 :(得分:12)
正如您所指出的那样,问题等同于在二分图中找到最大匹配的问题(一组顶点是人的集合,另一组是插槽,一个人之间存在边缘如果此人可用于此插槽,则为一个插槽。)
使用Hopcroft-Karp algorithm可以解决此问题。
复杂性O(n ^(5/2))在最坏的情况下,如果图形稀疏则更好。
答案 1 :(得分:12)
对于约束规划方法,它可以以不同的方式建模,例如使用矩阵方法和基于集合的方法。
基于集合的方法在高级CP语言MiniZinc中显示如下。 s是每个时段可用的人(使用set notation);决策变量是数组x(每次都应分配给哪个人)。
include "globals.mzn"; int: n = 4; % free persons per time slot array[1..n] of set of int: s = [{1,2,3,4}, {2,3}, {1,4}, {1,4}]; % decision variables % the assignment of persons to a slot (appointment number 1..n) array[1..n] of var 1..n: x; solve satisfy; constraint % ensure that the appointed person for the time slot is free forall(i in 1..n) ( x[i] in s[i] ) /\ % ensure that each person get a distinct time slot alldifferent(x) ; output [ show(x) ];
该模型输出这4种解决方案(0.5ms),例如时间1被分配给人3等。
x: [3, 2, 4, 1] ---------- x: [2, 3, 4, 1] ---------- x: [3, 2, 1, 4] ---------- x: [2, 3, 1, 4]
MiniZinc模型在这里:appointment_scheduling_set.mzn
矩阵方法模型在这里(没有输出部分)并使用标准的整数编程方法:appointment_scheduling.mzn。
int: n = 4; % rows are time slots % columns are people array[1..n, 1..n] of int: m = array2d(1..n, 1..n, [ 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, ]); % decision variables % the assignment of persons to a slot (appointment number 1..n) array[1..n, 1..n] of var 0..1: x; solve satisfy; constraint forall(i in 1..n) ( % ensure a free slot sum([m[i,j]*x[i,j] | j in 1..n]) = 1 /\ % ensure one assignment per slot and per person sum([x[i,j] | j in 1..n]) = 1 /\ sum([x[j,i] | j in 1..n]) = 1 ) ;
此模型的解决方案是相同的,尽管以另一种(并且更详细)的方式呈现,并且 - 当它发生时 - 与基于集合的方法的顺序相同
slot 1: 3 slot 2: 2 slot 3: 4 slot 4: 1 ---------- slot 1: 2 slot 2: 3 slot 3: 4 slot 4: 1 ---------- slot 1: 3 slot 2: 2 slot 3: 1 slot 4: 4 ---------- slot 1: 2 slot 2: 3 slot 3: 1 slot 4: 4
答案 2 :(得分:3)
这是Maximum Bipartite Matching problem。
根据图表的密度,最快的解决方案可能是Hopcroft-Karp algorithm,它最多运行时间为O(N ^(5/2)),但可能要快得多。
答案 3 :(得分:2)
我相信您可以使用network flows。
u_i
创建一个顶点i
,为广告v_j
创建一个顶点j
。s
并将s
的(定向)边缘放置到容量为1的每个u_i
。t
,并将每个v_j
的边缘放置到容量为1的t
。u_i
可以在v_j
位置进行采访,则可以将i
的优势放到j
。O(N)
个顶点和O(N^2)
条边,最大可能流程为N
。O(E*f)
需要E
,其中f
是边数,O(N^3)
是最大流量的值,所以它需要N
。(u_i,v_j)
,那么我们会有一个时间表:如果边i
的流量为1,那么我们会在广告位j
中与候选{{1}}进行对话,否则这是不可能的。通过积分流定理,最大流量将在边缘上具有整数流量,即0或1,因此我们确实有一个有效的时间表。