Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d860b57

Browse files
committed
chapter 3 draft
1 parent d377014 commit d860b57

File tree

7 files changed

+569
-0
lines changed

7 files changed

+569
-0
lines changed

‎CCSPiJ/src/chapter3/CSP.java‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// CSP.java
2+
// From Classic Computer Science Problems in Java Chapter 3
3+
// Copyright 2020 David Kopec
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package chapter3;
18+
19+
import java.util.ArrayList;
20+
import java.util.HashMap;
21+
import java.util.List;
22+
import java.util.Map;
23+
24+
public class CSP<V, D> {
25+
private List<V> variables;
26+
private Map<V, List<D>> domains;
27+
private Map<V, List<Constraint<V, D>>> constraints;
28+
29+
public CSP(List<V> variables, Map<V, List<D>> domains) {
30+
this.variables = variables;
31+
this.domains = domains;
32+
constraints = new HashMap<>();
33+
for (V variable : variables) {
34+
constraints.put(variable, new ArrayList<>());
35+
if (!domains.containsKey(variable)) {
36+
throw new IllegalArgumentException("Every variable should have a domain assigned to it.");
37+
}
38+
}
39+
}
40+
41+
public void addConstraint(Constraint<V, D> constraint) {
42+
for (V variable : constraint.variables) {
43+
if (!variables.contains(variable)) {
44+
throw new IllegalArgumentException("Variable in constraint not in CSP");
45+
} else {
46+
constraints.get(variable).add(constraint);
47+
}
48+
}
49+
}
50+
51+
// Check if the value assignment is consistent by checking all constraints
52+
// for the given variable against it
53+
public boolean consistent(V variable, Map<V, D> assignment) {
54+
for (Constraint<V, D> constraint : constraints.get(variable)) {
55+
if (!constraint.satisfied(assignment)) {
56+
return false;
57+
}
58+
}
59+
return true;
60+
}
61+
62+
public Map<V, D> backtrackingSearch(Map<V, D> assignment) {
63+
// assignment is complete if every variable is assigned (our base case)
64+
if (assignment.size() == variables.size()) {
65+
return assignment;
66+
}
67+
// get the first variable in the CSP but not in the assignment
68+
V unassigned = variables.stream().filter(v -> (!assignment.containsKey(v))).findFirst().get();
69+
// get the every possible domain value of the first unassigned variable
70+
for (D value : domains.get(unassigned)) {
71+
// shallow copy of assignment that we can change
72+
Map<V, D> localAssignment = new HashMap<>(assignment);
73+
localAssignment.put(unassigned, value);
74+
// if we're still consistent, we recurse (continue)
75+
if (consistent(unassigned, localAssignment)) {
76+
Map<V, D> result = backtrackingSearch(localAssignment);
77+
// if we didn't find the result, we will end up backtracking
78+
if (result != null) {
79+
return result;
80+
}
81+
}
82+
}
83+
return null;
84+
}
85+
86+
// helper for backtrackingSearch when nothing known yet
87+
public Map<V, D> backtrackingSearch() {
88+
return backtrackingSearch(new HashMap<>());
89+
}
90+
}

‎CCSPiJ/src/chapter3/Constraint.java‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Constraint.java
2+
// From Classic Computer Science Problems in Java Chapter 3
3+
// Copyright 2020 David Kopec
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package chapter3;
18+
19+
import java.util.List;
20+
import java.util.Map;
21+
22+
// V is the variable type, and D is the domain type
23+
public abstract class Constraint<V, D> {
24+
25+
// the variables that the constraint is between
26+
protected List<V> variables;
27+
28+
public Constraint(List<V> variables) {
29+
this.variables = variables;
30+
}
31+
32+
// must be overridden by subclasses
33+
public abstract boolean satisfied(Map<V, D> assignment);
34+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// MapColoringContraint.java
2+
// From Classic Computer Science Problems in Java Chapter 3
3+
// Copyright 2020 David Kopec
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package chapter3;
18+
19+
import java.util.HashMap;
20+
import java.util.List;
21+
import java.util.Map;
22+
23+
public final class MapColoringConstraint extends Constraint<String, String> {
24+
private String place1, place2;
25+
26+
public MapColoringConstraint(String place1, String place2) {
27+
super(List.of(place1, place2));
28+
this.place1 = place1;
29+
this.place2 = place2;
30+
}
31+
32+
@Override
33+
public boolean satisfied(Map<String, String> assignment) {
34+
// if either place is not in the assignment, then it is not
35+
// yet possible for their colors to be conflicting
36+
if (!assignment.containsKey(place1) || !assignment.containsKey(place2)) {
37+
return true;
38+
}
39+
// check the color assigned to place1 is not the same as the
40+
// color assigned to place2
41+
return !assignment.get(place1).equals(assignment.get(place2));
42+
}
43+
44+
public static void main(String[] args) {
45+
List<String> variables = List.of("Western Australia", "Northern Territory",
46+
"South Australia", "Queensland", "New South Wales", "Victoria", "Tasmania");
47+
Map<String, List<String>> domains = new HashMap<>();
48+
for (String variable : variables) {
49+
domains.put(variable, List.of("red", "green", "blue"));
50+
}
51+
CSP<String, String> csp = new CSP<>(variables, domains);
52+
csp.addConstraint(new MapColoringConstraint("Western Australia", "Northern Territory"));
53+
csp.addConstraint(new MapColoringConstraint("Western Australia", "South Australia"));
54+
csp.addConstraint(new MapColoringConstraint("South Australia", "Northern Territory"));
55+
csp.addConstraint(new MapColoringConstraint("Queensland", "Northern Territory"));
56+
csp.addConstraint(new MapColoringConstraint("Queensland", "South Australia"));
57+
csp.addConstraint(new MapColoringConstraint("Queensland", "New South Wales"));
58+
csp.addConstraint(new MapColoringConstraint("New South Wales", "South Australia"));
59+
csp.addConstraint(new MapColoringConstraint("Victoria", "South Australia"));
60+
csp.addConstraint(new MapColoringConstraint("Victoria", "New South Wales"));
61+
csp.addConstraint(new MapColoringConstraint("Victoria", "Tasmania"));
62+
Map<String, String> solution = csp.backtrackingSearch();
63+
if (solution == null) {
64+
System.out.println("No solution found!");
65+
} else {
66+
System.out.println(solution);
67+
}
68+
}
69+
70+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// QueensConstraint.java
2+
// From Classic Computer Science Problems in Java Chapter 3
3+
// Copyright 2020 David Kopec
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package chapter3;
18+
19+
import java.util.HashMap;
20+
import java.util.List;
21+
import java.util.Map;
22+
import java.util.Map.Entry;
23+
24+
public class QueensConstraint extends Constraint<Integer, Integer> {
25+
private List<Integer> columns;
26+
27+
public QueensConstraint(List<Integer> columns) {
28+
super(columns);
29+
this.columns = columns;
30+
}
31+
32+
@Override
33+
public boolean satisfied(Map<Integer, Integer> assignment) {
34+
for (Entry<Integer, Integer> item : assignment.entrySet()) {
35+
// q1c = queen 1 column, q1r = queen 1 row
36+
int q1c = item.getKey();
37+
int q1r = item.getValue();
38+
// q2c = queen 2 column
39+
for (int q2c = q1c + 1; q2c <= columns.size(); q2c++) {
40+
if (assignment.containsKey(q2c)) {
41+
// q2r = queen 2 row
42+
int q2r = assignment.get(q2c);
43+
// same row?
44+
if (q1r == q2r) {
45+
return false;
46+
}
47+
// same diagonal?
48+
if (Math.abs(q1r - q2r) == Math.abs(q1c - q2c)) {
49+
return false;
50+
}
51+
}
52+
}
53+
}
54+
return true; // no conflict
55+
}
56+
57+
public static void main(String[] args) {
58+
List<Integer> columns = List.of(1, 2, 3, 4, 5, 6, 7, 8);
59+
Map<Integer, List<Integer>> rows = new HashMap<>();
60+
for (int column : columns) {
61+
rows.put(column, List.of(1, 2, 3, 4, 5, 6, 7, 8));
62+
}
63+
CSP<Integer, Integer> csp = new CSP<>(columns, rows);
64+
csp.addConstraint(new QueensConstraint(columns));
65+
Map<Integer, Integer> solution = csp.backtrackingSearch();
66+
if (solution == null) {
67+
System.out.println("No solution found!");
68+
} else {
69+
System.out.println(solution);
70+
}
71+
}
72+
73+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package chapter3;
2+
3+
import java.util.HashMap;
4+
import java.util.HashSet;
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
public class SendMoreMoneyConstraint extends Constraint<Character, Integer> {
9+
private List<Character> letters;
10+
11+
public SendMoreMoneyConstraint(List<Character> letters) {
12+
super(letters);
13+
this.letters = letters;
14+
}
15+
16+
@Override
17+
public boolean satisfied(Map<Character, Integer> assignment) {
18+
// if there are duplicate values then it's not a solution
19+
if ((new HashSet<>(assignment.values())).size() < assignment.size()) {
20+
return false;
21+
}
22+
23+
// if all variables have been assigned, check if it adds correctly
24+
if (assignment.size() == letters.size()) {
25+
int s = assignment.get('S');
26+
int e = assignment.get('E');
27+
int n = assignment.get('N');
28+
int d = assignment.get('D');
29+
int m = assignment.get('M');
30+
int o = assignment.get('O');
31+
int r = assignment.get('R');
32+
int y = assignment.get('Y');
33+
int send = s * 1000 + e * 100 + n * 10 + d;
34+
int more = m * 1000 + o * 100 + r * 10 + e;
35+
int money = m * 10000 + o * 1000 + n * 100 + e * 10 + y;
36+
return send + more == money;
37+
}
38+
return true; // no conflicts
39+
}
40+
41+
public static void main(String[] args) {
42+
List<Character> letters = List.of('S', 'E', 'N', 'D', 'M', 'O', 'R', 'Y');
43+
Map<Character, List<Integer>> possibleDigits = new HashMap<>();
44+
for (Character letter : letters) {
45+
possibleDigits.put(letter, List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
46+
}
47+
// so we don't get answers starting with a 0
48+
possibleDigits.replace('M', List.of(1));
49+
CSP<Character, Integer> csp = new CSP<>(letters, possibleDigits);
50+
csp.addConstraint(new SendMoreMoneyConstraint(letters));
51+
Map<Character, Integer> solution = csp.backtrackingSearch();
52+
if (solution == null) {
53+
System.out.println("No solution found!");
54+
} else {
55+
System.out.println(solution);
56+
}
57+
}
58+
59+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /