-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathforward_checking.cpp
More file actions
102 lines (87 loc) · 3.41 KB
/
forward_checking.cpp
File metadata and controls
102 lines (87 loc) · 3.41 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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
namespace ForwardChecking {
int numberOfNodes;
int numberOfBacktracks;
int dim;
bool revise(vector<int>&domains, int i, int j) {
bool doDelete = false;
for (int x = 1; x <= dim; x++) {
int containsx = 1<<x;
///check if x is in domain of vi
if (domains[i]&containsx) {
///check if domain of vj contains only x
if (domains[j] == containsx) {
///delete x from domain of vi
domains[i] ^= containsx;
doDelete = true;
}
}
}
return doDelete;
}
typedef pair< int, int > Arc;
bool AC3(const Matrix &cur, const vector<Cell>&unassigned, vector<int>&domains, int cv) {
queue< Arc >Q;
///push arcs to source node
for (int i = 0; i < unassigned.size(); i++) {
if (isArc(unassigned[i], unassigned[cv])) {
Q.emplace(i, cv);
}
}
bool consistent = true;
while (!Q.empty() && consistent) {
Arc arc = Q.front();
Q.pop();
int k = arc.first;
int m = arc.second;
if (revise(domains, k, m)) {
consistent = domains[k] != 0;
}
}
return consistent;
}
bool forwardChecking(Matrix &cur, vector< Cell >&unassigned, vector< int >&domains) {
numberOfNodes++;
if (unassigned.empty()) return true;
if (timer.timesUp()) return false;
int nxtIdx = VariableOrdering::chooseNextIndex(cur, unassigned);
swap(unassigned[nxtIdx], unassigned[unassigned.size()-1]);
swap(domains[nxtIdx], domains[domains.size()-1]);
const Cell p = unassigned.back();
const int options = domains.back();
bool wentDeeper = false;
for (int x : ValueOrdering::getValueOrderWithDomain(cur, p, options)) {
cur[p.first][p.second] = x;
vector<int>newDomains(domains);
newDomains.back() = 1<<x;
if (AC3(cur, unassigned, newDomains, unassigned.size()-1)) {
wentDeeper = true;
unassigned.pop_back();
newDomains.pop_back();
if (forwardChecking(cur, unassigned, newDomains)) return true;
unassigned.push_back(p);
}
cur[p.first][p.second] = 0;
}
if (!wentDeeper) numberOfBacktracks++;
swap(unassigned[nxtIdx], unassigned[unassigned.size()-1]);
swap(domains[nxtIdx], domains[domains.size()-1]);
return false;
}
void solveWithForwardChecking(Matrix start) {
dim = start.size();
vector<Cell> unassigned = getUnassignedPlaces(start);
vector<int> domains = getDomains(start, unassigned);
numberOfNodes = numberOfBacktracks = 0;
if (forwardChecking(start, unassigned, domains)) {
cout << "Found a solution with forward cheking:" << endl;
printMat(start);
assert(isConsistent(start));
} else {
cout << "Solution not found!" << endl;
numberOfNodes = numberOfBacktracks = -1;
}
cout << "Number of nodes: " << numberOfNodes << endl;
cout << "Number of backtracks: " << numberOfBacktracks << endl;
cout << endl;
}
}