Appointment scheduling algorithm (N people with N free-busy slots, constraint-satisfaction)

这一生的挚爱 提交于 2019-11-27 17:32:18

As you pointed out, the problem is equivalent to the problem of finding a maximum matching in a bipartite graph (one set of vertices is the set of people and the other on the set of slots, there is an edge between a person and a slot if the person is available for this slot).

This problem can be solved with the Hopcroft-Karp algorithm.

Complexity O(n^(5/2)) in the worst case, better if the graph is sparse.

hakank

As for the Constraint Programming approach it can be modeled in different ways, for example with a matrix approach and a set based approach.

The set based approach is shown below in the high level CP language MiniZinc. s is the people who are available each time slot (using set notation); the decision variables are the array x (which person should be allotted to each time).

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) ];

The model outputs these 4 solutions (in 0.5ms), e.g. time 1 is assigned to person 3 etc.

x: [3, 2, 4, 1]
----------
x: [2, 3, 4, 1]
----------
x: [3, 2, 1, 4]
----------
x: [2, 3, 1, 4]

The MiniZinc model is here: appointment_scheduling_set.mzn

The matrix approach model is here (without the output section) and use a standard Integer programming approach: 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
  )
;

The solution from this model is the same, though presented in another (and more verbose) way and - as it happens - in the same order as the set based approach

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

This is the Maximum Bipartite Matching problem.

Depending on the density of the graph, the fastest solution is probably the Hopcroft-Karp algorithm, which runs in at most O(N^(5/2)) time, but likely much faster.

I believe that you can use network flows.

  • Create a vertex u_i for candidate i, and a vertex v_j for slot j.
  • Make a source node s and put an (directed) edge from s to each u_i of capacity 1.
  • Make a sink node t and put an edge from each v_j to t of capacity 1.
  • Put an edge from u_i to v_j if candidate i can interview in slot j.
  • We have O(N) vertices and O(N^2) edges, the maximum possible flow is N.
  • Find the max flow using, for example, the Ford-Fulkerson algorithm, which takes O(E*f) where E is the number of edges and f is the value of the max flow, so it takes O(N^3).
  • If the max flow is N, then we have a schedule: if the edge (u_i,v_j) has flow 1, then we interview candidate i in slot j, otherwise it's impossible.

By the integral flow theorem, the max flow will have integer flows on the edges, which is 0 or 1, so we do have a valid schedule.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!