Download
"""
PyCSP3 Model (see pycsp.org)
Data can come:
- either directly from a JSON file
- or from an intermediate parser
Example:
python MisteryShopper.py -data=MisteryShopper_04.json
"""
from pycsp3 import *
vr_sizes = data.visitorGroups # vr_sizes[i] gives the size of the ith visitor group
ve_sizes = data.visiteeGroups # ve_sizes[i] gives the size of the ith visitee group
nVisitors, nVisitees = sum(vr_sizes), sum(ve_sizes)
assert nVisitors >= nVisitees, "The number of visitors must be greater than the number of visitees"
if nVisitors - nVisitees > 0:
ve_sizes.append(nVisitors - nVisitees) # an artificial group with dummy visitees is added
n, nWeeks = nVisitors, len(vr_sizes)
vr_table = {(i, sum(vr_sizes[:i]) + j) for i, size in enumerate(vr_sizes) for j in range(size)}
ve_table = {(i, sum(ve_sizes[:i]) + j) for i, size in enumerate(ve_sizes) for j in range(size)}
# r[i][w] is the visitor for the ith visitee at week w
r = VarArray(size=[n, nWeeks], dom=range(n))
# e[i][w] is the visitee for the ith visitor at week w
e = VarArray(size=[n, nWeeks], dom=range(n))
# rg[i][w] is the visitor group for the ith visitee at week w
rg = VarArray(size=[n, nWeeks], dom=range(len(vr_sizes)))
# eg[i][w] is the visitee group for the ith visitor at week w
eg = VarArray(size=[n, nWeeks], dom=range(len(ve_sizes)))
satisfy(
# each week, all visitors must be different
[AllDifferent(col) for col in columns(r)],
# each week, all visitees must be different
[AllDifferent(col) for col in columns(e)],
# the visitor groups must be different for each visitee
[AllDifferent(row) for row in rg],
# the visitee groups must be different for each visitor
[AllDifferent(row) for row in eg],
# channeling arrays vr and ve, each week
[Channel(r[:, w], e[:, w]) for w in range(nWeeks)],
# tag(symmetry-breaking)
[
LexIncreasing(r, matrix=True),
[Increasing([r[i][w] for i in range(nVisitees, n)], strict=True) for w in range(nWeeks)]
],
# linking a visitor with its group
[(rg[i][w], r[i][w]) in vr_table for i in range(n) for w in range(nWeeks)],
# linking a visitee with its group
[(eg[i][w], e[i][w]) in ve_table for i in range(n) for w in range(nWeeks)]
)