-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgen.mzn
More file actions
87 lines (63 loc) · 3.45 KB
/
Copy pathgen.mzn
File metadata and controls
87 lines (63 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
int: n;
constraint assert(n == 5 \/ n == 7 \/ n == 10 \/ n == 15, "n must be equal to 5 or 7 or 10 or 15");
enum TYPE = {Empty, Right, Down, Implicit};
set of int: indices = 1..n;
%numero di buchi esatti per riga e colonna
array[indices] of var int: rowSum;
array[indices] of var int: colSum;
%matrice di gruppi
array[indices, indices] of int: groups;
%matrice di variabili decisionali
array[indices, indices] of var TYPE: results;
%dimensioni della matrice di adiacenza dei gruppi
int: rowN;
constraint assert(rowN > 0, "Number of groups must be greater than 0");
int: colN;
constraint assert(colN > 0, "Number of groups must be greater than 0");
set of int: rowPair = 1..rowN;
set of int: colPair = 1..colN;
%matrice di adiacenza
array[rowPair, colPair] of int: pair;
constraint assert(forall(i in rowPair, j in colPair)(pair[i,j] >= 0 /\ pair[i,j] <= 1), "Elements of the adjacency matrix must be 0 or 1");
%l'ultima colonna non può avere un valore "Right"
constraint forall(i in indices) (results[i,n] != Right);
%l'ultima riga non può avere un valore "Down"
constraint forall(j in indices) (results[n,j] != Down);
%il numero di buchi per ogni riga deve corrispondere esattamente al valore in input per quella riga
constraint forall(i in indices) (
sum(j in indices) (results[i,j] != Empty) = rowSum[i]
);
%il numero di buchi per ogni colonna deve corrispondere esattamente al valore in input per quella colonna
constraint forall(j in indices) (
sum(i in indices) (results[i,j] != Empty) = colSum[j]
);
%Non è possibile che ad una cella venga assegnato Right se alla sua destra il gruppo non cambia
constraint forall(i in indices, j in indices) (
if results[i,j] == Right then groups[i,j] != groups[i,j+1] else true endif
);
%Non è possibile che ad una cella venga assegnato Down se sotto di essa il gruppo non cambia
constraint forall(i in indices, j in indices) (
if results[i,j] == Down then groups[i,j] != groups[i+1,j] else true endif
);
%conta i collegamenti fra due gruppi usando la cucitura "destra"
function var int: count_right(int: group1, int: group2) = count(i in indices, j in indices where groups[i,j] == group1 /\ groups[i,j+1] == group2) (results[i,j] == Right);
%conta i collegamenti fra due gruppi usando la cucitura "sotto"
function var int: count_down(int: group1, int: group2) = count(i in indices, j in indices where groups[i,j] == group1 /\ groups[i+1,j] == group2) (results[i,j] == Down);
%per ogni pair di gruppi collegati, il numero di collegamenti dev'essere 1
constraint forall(i in rowPair, j in colPair) (
if pair[i,j] == 1 then (count_right(i,j) + count_down(i,j)) == 1 \/ (count_right(j,i) + count_down(j,i)) == 1 else true endif
);
%Se una cella ha valore "Right", la cella di destra deve avere valore "Implicit"
constraint forall(i in indices, j in indices) (
if results[i,j] == Right then results[i,j+1] = Implicit else true endif
);
%Se una cella ha valore "Down", la cella di destra deve avere valore "Implicit"
constraint forall(i in indices, j in indices) (
if results[i,j] == Down then results[i+1,j] = Implicit else true endif
);
%Se una cella ha valore "Implicit", la cella di sopra deve avere valore "Down" oppure la cella di sinistra deve avere valore "Right" (or esclusivo)
constraint forall(i in indices, j in indices) (
if results[i,j] == Implicit then results[i,j-1] = Right xor results[i-1,j] = Down else true endif
);
solve satisfy;
output ["\(results[i,j])," ++ if j == n then "\n" else " " endif | i in indices, j in indices];