format all C# files

This commit is contained in:
Mizux Seiha
2020-10-26 18:36:17 +01:00
parent 976ab9d82b
commit 335cf3df3d
197 changed files with 10040 additions and 12226 deletions

View File

@@ -4,4 +4,7 @@ BasedOnStyle: Google
---
Language: Java
BasedOnStyle: Google
---
Language: CSharp
BasedOnStyle: Google
...

View File

@@ -21,4 +21,4 @@ jobs:
run: docker run --rm --init -v $(pwd):/repo linter:latest clang-format --help
- name: Check current commit
run: docker run --rm --init -v $(pwd):/repo -w /repo linter:latest sh -c "git diff --diff-filter=d --name-only FETCH_HEAD | grep '\.c$\|\.h$\|\.cc$\|\.java$' | xargs clang-format --verbose --style=file --dry-run --Werror "
run: docker run --rm --init -v $(pwd):/repo -w /repo linter:latest sh -c "git diff --diff-filter=d --name-only FETCH_HEAD | grep '\.c$\|\.h$\|\.cc$\|\.java$\|\.cs$' | xargs clang-format --verbose --style=file --dry-run --Werror "

View File

@@ -19,10 +19,7 @@ using System.Linq;
using System.Diagnostics;
using Google.OrTools.ConstraintSolver;
public class ThreeJugsRegular
{
public class ThreeJugsRegular {
/*
* Global constraint regular
*
@@ -45,16 +42,8 @@ public class ThreeJugsRegular
* F : accepting states
*
*/
static void MyRegular(Solver solver,
IntVar[] x,
int Q,
int S,
int[,] d,
int q0,
int[] F) {
static void MyRegular(Solver solver, IntVar[] x, int Q, int S, int[, ] d,
int q0, int[] F) {
Debug.Assert(Q > 0, "regular: 'Q' must be greater than zero");
Debug.Assert(S > 0, "regular: 'S' must be greater than zero");
@@ -62,22 +51,25 @@ public class ThreeJugsRegular
// each possible input; each extra transition is from state zero
// to state zero. This allows us to continue even if we hit a
// non-accepted input.
int[][] d2 = new int[Q+1][];
for(int i = 0; i <= Q; i++) {
int[][] d2 = new int [Q + 1]
[];
for (int i = 0; i <= Q; i++) {
int[] row = new int[S];
for(int j = 0; j < S; j++) {
for (int j = 0; j < S; j++) {
if (i == 0) {
row[j] = 0;
} else {
row[j] = d[i-1,j];
row[j] = d[i - 1, j];
}
}
d2[i] = row;
}
int[] d2_flatten = (from i in Enumerable.Range(0, Q+1)
from j in Enumerable.Range(0, S)
select d2[i][j]).ToArray();
int[] d2_flatten =
(from i in Enumerable.Range(0, Q + 1) from j in Enumerable.Range(0, S)
select d2 [i]
[j])
.ToArray();
// If x has index set m..n, then a[m-1] holds the initial state
// (q0), and a[i+1] holds the state we're in after processing
@@ -86,25 +78,21 @@ public class ThreeJugsRegular
int m = 0;
int n = x.Length;
IntVar[] a = solver.MakeIntVarArray(n+1-m, 0,Q+1, "a");
IntVar[] a = solver.MakeIntVarArray(n + 1 - m, 0, Q + 1, "a");
// Check that the final state is in F
solver.Add(a[a.Length-1].Member(F));
solver.Add(a [a.Length - 1]
.Member(F));
// First state is q0
solver.Add(a[m] == q0);
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
solver.Add(x[i] >= 1);
solver.Add(x[i] <= S);
// Determine a[i+1]: a[i+1] == d2[a[i], x[i]]
solver.Add(a[i+1] == d2_flatten.Element(((a[i]*S)+(x[i]-1))));
solver.Add(a[i + 1] == d2_flatten.Element(((a[i] * S) + (x[i] - 1))));
}
}
/**
*
* 3 jugs problem using regular constraint in Google CP Solver.
@@ -127,18 +115,17 @@ public class ThreeJugsRegular
* Also see http://www.hakank.org/or-tools/3_jugs_regular.py
*
*/
private static bool Solve(int n)
{
private static bool Solve(int n) {
Solver solver = new Solver("ThreeJugProblem");
//
// Data
//
// the DFA (for regular)
int n_states = 14;
int input_max = 15;
int initial_state = 1; // state 0 is for the failing state
int initial_state = 1; // state 0 is for the failing state
int[] accepting_states = {15};
//
@@ -170,36 +157,37 @@ public class ThreeJugsRegular
// However, the DFA is easy to create from adjacency lists.
//
int[][] states = {
new int[] {2,9}, // state 1
new int[] {3}, // state 2
new int[] {4, 9}, // state 3
new int[] {5}, // state 4
new int[] {6,9}, // state 5
new int[] {7}, // state 6
new int[] {8,9}, // state 7
new int[] {15}, // state 8
new int[] {10}, // state 9
new int[] {11}, // state 10
new int[] {12}, // state 11
new int[] {13}, // state 12
new int[] {14}, // state 13
new int[] {15} // state 14
new int[]{2, 9}, // state 1
new int[]{3}, // state 2
new int[]{4, 9}, // state 3
new int[]{5}, // state 4
new int[]{6, 9}, // state 5
new int[]{7}, // state 6
new int[]{8, 9}, // state 7
new int[]{15}, // state 8
new int[]{10}, // state 9
new int[]{11}, // state 10
new int[]{12}, // state 11
new int[]{13}, // state 12
new int[]{14}, // state 13
new int[]{15} // state 14
};
int[,] transition_fn = new int[n_states,input_max];
for(int i = 0; i < n_states; i++) {
for(int j = 1; j <= input_max; j++) {
int[, ] transition_fn = new int[n_states, input_max];
for (int i = 0; i < n_states; i++) {
for (int j = 1; j <= input_max; j++) {
bool in_states = false;
for(int s = 0; s < states[i].Length; s++) {
if (j == states[i][s]) {
for (int s = 0; s < states[i].Length; s++) {
if (j == states [i]
[s]) {
in_states = true;
break;
}
}
if (in_states) {
transition_fn[i,j-1] = j;
transition_fn[i, j - 1] = j;
} else {
transition_fn[i,j-1] = 0;
transition_fn[i, j - 1] = 0;
}
}
}
@@ -209,21 +197,21 @@ public class ThreeJugsRegular
// the solution.
//
string[] nodes = {
"8,0,0", // 1 start
"5,0,3", // 2
"5,3,0", // 3
"2,3,3", // 4
"2,5,1", // 5
"7,0,1", // 6
"7,1,0", // 7
"4,1,3", // 8
"3,5,0", // 9
"3,2,3", // 10
"6,2,0", // 11
"6,0,2", // 12
"1,5,2", // 13
"1,4,3", // 14
"4,4,0" // 15 goal
"8,0,0", // 1 start
"5,0,3", // 2
"5,3,0", // 3
"2,3,3", // 4
"2,5,1", // 5
"7,0,1", // 6
"7,1,0", // 7
"4,1,3", // 8
"3,5,0", // 9
"3,2,3", // 10
"6,2,0", // 11
"6,0,2", // 12
"1,5,2", // 13
"1,4,3", // 14
"4,4,0" // 15 goal
};
//
@@ -233,35 +221,33 @@ public class ThreeJugsRegular
// Note: We use 1..2 (instead of 0..1) and subtract 1 in the solution
IntVar[] x = solver.MakeIntVarArray(n, 1, input_max, "x");
//
// Constraints
//
MyRegular(solver, x, n_states, input_max, transition_fn,
initial_state, accepting_states);
MyRegular(solver, x, n_states, input_max, transition_fn, initial_state,
accepting_states);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
bool found = false;
while (solver.NextSolution()) {
Console.WriteLine("\nFound a solution of length {0}", n+1);
Console.WriteLine("\nFound a solution of length {0}", n + 1);
int[] x_val = new int[n];
x_val[0] = 1;
Console.WriteLine("{0} -> {1}", nodes[0], nodes[x_val[0]]);
for(int i = 1; i < n; i++) {
for (int i = 1; i < n; i++) {
// Note: here we subtract 1 to get 0..1
int val = (int)x[i].Value()-1;
int val = (int) x [i]
.Value() -
1;
x_val[i] = val;
Console.WriteLine("{0} -> {1}", nodes[x_val[i-1]], nodes[x_val[i]]);
Console.WriteLine("{0} -> {1}", nodes[x_val[i - 1]], nodes[x_val[i]]);
}
Console.WriteLine();
@@ -269,21 +255,17 @@ public class ThreeJugsRegular
Console.WriteLine("WallTime: {0}ms", solver.WallTime());
Console.WriteLine("Failures: {0}", solver.Failures());
Console.WriteLine("Branches: {0} ", solver.Branches());
found = true;
found = true;
}
solver.EndSearch();
return found;
}
public static void Main(String[] args)
{
for(int n = 1; n < 15; n++) {
public static void Main(String[] args) {
for (int n = 1; n < 15; n++) {
bool found = Solve(n);
if (found) {
break;

View File

@@ -17,8 +17,7 @@ using System;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class APuzzle
{
public class APuzzle {
/**
*
* From "God plays dice"
@@ -84,13 +83,11 @@ public class APuzzle
*
*
*/
private static void Solve(int p = 1)
{
private static void Solve(int p = 1) {
Solver solver = new Solver("APuzzle");
Console.WriteLine("\nSolving p{0}", p);
//
// Data
//
@@ -99,22 +96,21 @@ public class APuzzle
//
// Decision variables
//
IntVar x0 = solver.MakeIntVar(0, n-1, "x0");
IntVar x1 = solver.MakeIntVar(0, n-1, "x1");
IntVar x2 = solver.MakeIntVar(0, n-1, "x2");
IntVar x3 = solver.MakeIntVar(0, n-1, "x3");
IntVar x4 = solver.MakeIntVar(0, n-1, "x4");
IntVar x5 = solver.MakeIntVar(0, n-1, "x5");
IntVar x6 = solver.MakeIntVar(0, n-1, "x6");
IntVar x7 = solver.MakeIntVar(0, n-1, "x7");
IntVar x8 = solver.MakeIntVar(0, n-1, "x8");
IntVar x9 = solver.MakeIntVar(0, n-1, "x9");
IntVar x0 = solver.MakeIntVar(0, n - 1, "x0");
IntVar x1 = solver.MakeIntVar(0, n - 1, "x1");
IntVar x2 = solver.MakeIntVar(0, n - 1, "x2");
IntVar x3 = solver.MakeIntVar(0, n - 1, "x3");
IntVar x4 = solver.MakeIntVar(0, n - 1, "x4");
IntVar x5 = solver.MakeIntVar(0, n - 1, "x5");
IntVar x6 = solver.MakeIntVar(0, n - 1, "x6");
IntVar x7 = solver.MakeIntVar(0, n - 1, "x7");
IntVar x8 = solver.MakeIntVar(0, n - 1, "x8");
IntVar x9 = solver.MakeIntVar(0, n - 1, "x9");
IntVar[] all = {x0,x1,x2,x3,x4,x5,x6,x7,x8,x9};
IntVar[] all = {x0, x1, x2, x3, x4, x5, x6, x7, x8, x9};
// The unknown, i.e. 2581 = x
IntVar x = solver.MakeIntVar(0, n-1, "x");
IntVar x = solver.MakeIntVar(0, n - 1, "x");
//
// Constraints
@@ -126,120 +122,90 @@ public class APuzzle
// - using a a matrix and Sum of each row
if (p == 1) {
// Problem 1
solver.Add(x8+x8+x0+x9 == 6);
solver.Add(x7+x1+x1+x1 == 0);
solver.Add(x2+x1+x7+x2 == 0);
solver.Add(x6+x6+x6+x6 == 4);
solver.Add(x1+x1+x1+x1 == 0);
solver.Add(x3+x2+x1+x3 == 0);
solver.Add(x7+x6+x6+x2 == 2);
solver.Add(x9+x3+x1+x2 == 1);
solver.Add(x0+x0+x0+x0 == 4);
solver.Add(x2+x2+x2+x2 == 0);
solver.Add(x3+x3+x3+x3 == 0);
solver.Add(x5+x5+x5+x5 == 0);
solver.Add(x8+x1+x9+x3 == 3);
solver.Add(x8+x0+x9+x6 == 5);
solver.Add(x7+x7+x7+x7 == 0);
solver.Add(x9+x9+x9+x9 == 4);
solver.Add(x7+x7+x5+x6 == 1);
solver.Add(x6+x8+x5+x5 == 3);
solver.Add(x9+x8+x8+x1 == 5);
solver.Add(x5+x5+x3+x1 == 0);
solver.Add(x8 + x8 + x0 + x9 == 6);
solver.Add(x7 + x1 + x1 + x1 == 0);
solver.Add(x2 + x1 + x7 + x2 == 0);
solver.Add(x6 + x6 + x6 + x6 == 4);
solver.Add(x1 + x1 + x1 + x1 == 0);
solver.Add(x3 + x2 + x1 + x3 == 0);
solver.Add(x7 + x6 + x6 + x2 == 2);
solver.Add(x9 + x3 + x1 + x2 == 1);
solver.Add(x0 + x0 + x0 + x0 == 4);
solver.Add(x2 + x2 + x2 + x2 == 0);
solver.Add(x3 + x3 + x3 + x3 == 0);
solver.Add(x5 + x5 + x5 + x5 == 0);
solver.Add(x8 + x1 + x9 + x3 == 3);
solver.Add(x8 + x0 + x9 + x6 == 5);
solver.Add(x7 + x7 + x7 + x7 == 0);
solver.Add(x9 + x9 + x9 + x9 == 4);
solver.Add(x7 + x7 + x5 + x6 == 1);
solver.Add(x6 + x8 + x5 + x5 == 3);
solver.Add(x9 + x8 + x8 + x1 == 5);
solver.Add(x5 + x5 + x3 + x1 == 0);
// The unknown
solver.Add(x2+x5+x8+x1 == x);
solver.Add(x2 + x5 + x8 + x1 == x);
} else if (p == 2) {
// Another representation of Problem 1
int[,] problem1 = {
{8,8,0,9, 6},
{7,1,1,1, 0},
{2,1,7,2, 0},
{6,6,6,6, 4},
{1,1,1,1, 0},
{3,2,1,3, 0},
{7,6,6,2, 2},
{9,3,1,2, 1},
{0,0,0,0, 4},
{2,2,2,2, 0},
{3,3,3,3, 0},
{5,5,5,5, 0},
{8,1,9,3, 3},
{8,0,9,6, 5},
{7,7,7,7, 0},
{9,9,9,9, 4},
{7,7,5,6, 1},
{6,8,5,5, 3},
{9,8,8,1, 5},
{5,5,3,1, 0}
};
int[, ] problem1 = {
{8, 8, 0, 9, 6}, {7, 1, 1, 1, 0}, {2, 1, 7, 2, 0}, {6, 6, 6, 6, 4},
{1, 1, 1, 1, 0}, {3, 2, 1, 3, 0}, {7, 6, 6, 2, 2}, {9, 3, 1, 2, 1},
{0, 0, 0, 0, 4}, {2, 2, 2, 2, 0}, {3, 3, 3, 3, 0}, {5, 5, 5, 5, 0},
{8, 1, 9, 3, 3}, {8, 0, 9, 6, 5}, {7, 7, 7, 7, 0}, {9, 9, 9, 9, 4},
{7, 7, 5, 6, 1}, {6, 8, 5, 5, 3}, {9, 8, 8, 1, 5}, {5, 5, 3, 1, 0}};
for(int i = 0; i < problem1.GetLength(0); i++) {
solver.Add( (from j in Enumerable.Range(0, 4)
select all[problem1[i,j]]
).ToArray().Sum() == problem1[i,4] );
for (int i = 0; i < problem1.GetLength(0); i++) {
solver.Add((from j in Enumerable.Range(0, 4) select all[problem1[i, j]])
.ToArray()
.Sum() == problem1[i, 4]);
}
solver.Add(all[2]+all[5]+all[8]+all[1] == x);
solver.Add(all[2] + all[5] + all[8] + all[1] == x);
} else if (p == 3) {
// Problem 2
solver.Add(x8+x8+x0+x9 == 6);
solver.Add(x7+x6+x6+x2 == 2);
solver.Add(x9+x3+x1+x2 == 1);
solver.Add(x8+x1+x9+x3 == 3);
solver.Add(x8+x0+x9+x6 == 5);
solver.Add(x7+x7+x5+x6 == 1);
solver.Add(x6+x8+x5+x5 == 3);
solver.Add(x9+x8+x8+x1 == 5);
solver.Add(x8 + x8 + x0 + x9 == 6);
solver.Add(x7 + x6 + x6 + x2 == 2);
solver.Add(x9 + x3 + x1 + x2 == 1);
solver.Add(x8 + x1 + x9 + x3 == 3);
solver.Add(x8 + x0 + x9 + x6 == 5);
solver.Add(x7 + x7 + x5 + x6 == 1);
solver.Add(x6 + x8 + x5 + x5 == 3);
solver.Add(x9 + x8 + x8 + x1 == 5);
// The unknown
solver.Add(x2+x5+x8+x1 == x);
solver.Add(x2 + x5 + x8 + x1 == x);
} else {
// Another representation of Problem 2
int[,] problem2 = {
{8,8,0,9, 6},
{7,6,6,2, 2},
{9,3,1,2, 1},
{8,1,9,3, 3},
{8,0,9,6, 5},
{7,7,5,6, 1},
{6,8,5,5, 3},
{9,8,8,1, 5}
};
int[, ] problem2 = {{8, 8, 0, 9, 6}, {7, 6, 6, 2, 2}, {9, 3, 1, 2, 1},
{8, 1, 9, 3, 3}, {8, 0, 9, 6, 5}, {7, 7, 5, 6, 1},
{6, 8, 5, 5, 3}, {9, 8, 8, 1, 5}};
for(int i = 0; i < problem2.GetLength(0); i++) {
solver.Add( (from j in Enumerable.Range(0, 4)
select all[problem2[i,j]]
).ToArray().Sum() == problem2[i,4] );
for (int i = 0; i < problem2.GetLength(0); i++) {
solver.Add((from j in Enumerable.Range(0, 4) select all[problem2[i, j]])
.ToArray()
.Sum() == problem2[i, 4]);
}
solver.Add(all[2]+all[5]+all[8]+all[1] == x);
solver.Add(all[2] + all[5] + all[8] + all[1] == x);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(all,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(all, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x: {0} x0..x9: ", x.Value());
for(int i = 0; i < n; i++) {
Console.Write(all[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(all [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -250,12 +216,10 @@ public class APuzzle
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
for(int p = 1; p <= 4; p++) {
public static void Main(String[] args) {
for (int p = 1; p <= 4; p++) {
Solve(p);
}
}

View File

@@ -20,10 +20,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class ARoundOfGolf
{
public class ARoundOfGolf {
/**
*
* A Round of Golf puzzle (Dell Logic Puzzles) in Google CP Solver.
@@ -38,21 +35,20 @@ public class ARoundOfGolf
* Stars: 1
*
* When the Sunny Hills Country Club golf course isn't in use by club members,
* of course, it's open to the club's employees. Recently, Jack and three other
* workers at the golf course got together on their day off to play a round of
* eighteen holes of golf.
* Afterward, all four, including Mr. Green, went to the clubhouse to total
* their scorecards. Each man works at a different job (one is a short-order
* cook), and each shot a different score in the game. No one scored below
* 70 or above 85 strokes. From the clues below, can you discover each man's
* full name, job and golf score?
* of course, it's open to the club's employees. Recently, Jack and three
* other workers at the golf course got together on their day off to play a
* round of eighteen holes of golf. Afterward, all four, including Mr. Green,
* went to the clubhouse to total their scorecards. Each man works at a
* different job (one is a short-order cook), and each shot a different score
* in the game. No one scored below 70 or above 85 strokes. From the clues
* below, can you discover each man's full name, job and golf score?
*
* 1. Bill, who is not the maintenance man, plays golf often and had the lowest
* score of the foursome.
* 2. Mr. Clubb, who isn't Paul, hit several balls into the woods and scored ten
* strokes more than the pro-shop clerk.
* 3. In some order, Frank and the caddy scored four and seven more strokes than
* Mr. Sands.
* 1. Bill, who is not the maintenance man, plays golf often and had the
* lowest score of the foursome.
* 2. Mr. Clubb, who isn't Paul, hit several balls into the woods and scored
* ten strokes more than the pro-shop clerk.
* 3. In some order, Frank and the caddy scored four and seven more strokes
* than Mr. Sands.
* 4. Mr. Carter thought his score of 78 was one of his better games, even
* though Frank's score was lower.
* 5. None of the four scored exactly 81 strokes.
@@ -63,41 +59,40 @@ public class ARoundOfGolf
* See http://www.hakank.org/google_or_tools/a_round_of_golf.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("ARoundOfGolf");
// number of speakers
int n = 4;
int Jack = 0;
int Bill = 1;
int Paul = 2;
int Jack = 0;
int Bill = 1;
int Paul = 2;
int Frank = 3;
//
// Decision variables
//
IntVar[] last_name = solver.MakeIntVarArray(n, 0, n-1, "last_name");
IntVar[] last_name = solver.MakeIntVarArray(n, 0, n - 1, "last_name");
// IntVar Green = last_name[0]; // not used
IntVar Clubb = last_name[1];
IntVar Sands = last_name[2];
IntVar Clubb = last_name[1];
IntVar Sands = last_name[2];
IntVar Carter = last_name[3];
IntVar[] job = solver.MakeIntVarArray(n, 0, n-1, "job");
IntVar[] job = solver.MakeIntVarArray(n, 0, n - 1, "job");
// IntVar cook = job[0]; // not used
IntVar maintenance_man = job[1];
IntVar clerk = job[2];
IntVar caddy = job[3];
IntVar clerk = job[2];
IntVar caddy = job[3];
IntVar[] score = solver.MakeIntVarArray(n, 70, 85, "score");
IntVar[] score = solver.MakeIntVarArray(n, 70, 85, "score");
// for search
IntVar[] all = new IntVar[n*3];
for(int i = 0; i < n; i++) {
IntVar[] all = new IntVar[n * 3];
for (int i = 0; i < n; i++) {
all[i] = last_name[i];
all[i+n] = job[i];
all[i+2*n] = score[i];
all[i + n] = job[i];
all[i + 2 * n] = score[i];
}
//
@@ -129,7 +124,7 @@ public class ARoundOfGolf
IntVar b3_a_2 = score.Element(caddy) == score.Element(Sands) + 7;
IntVar b3_b_1 = score.Element(Sands) + 7 == score[Frank];
IntVar b3_b_2 = score.Element(caddy) == score.Element(Sands) + 4;
solver.Add( (b3_a_1*b3_a_2) + (b3_b_1*b3_b_2) == 1);
solver.Add((b3_a_1 * b3_a_2) + (b3_b_1 * b3_b_2) == 1);
// 4. Mr. Carter thought his score of 78 was one of his better games,
// even though Frank's score was lower.
@@ -138,32 +133,32 @@ public class ARoundOfGolf
solver.Add(score[Frank] < score.Element(Carter));
// 5. None of the four scored exactly 81 strokes.
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
solver.Add(score[i] != 81);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(all,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(all, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.WriteLine(
"Last name: " +
String.Join(", ", (from i in last_name
select i.Value().ToString()).ToArray()));
String.Join(
", ",
(from i in last_name select i.Value().ToString()).ToArray()));
Console.WriteLine(
"Job : " +
String.Join(", ", (from i in job
select i.Value().ToString()).ToArray()));
String.Join(", ",
(from i in job select i.Value().ToString()).ToArray()));
Console.WriteLine(
"Score : " +
String.Join(", ", (from i in score
select i.Value().ToString()).ToArray()));
String.Join(", ",
(from i in score select i.Value().ToString()).ToArray()));
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -172,12 +167,7 @@ public class ARoundOfGolf
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,26 +19,21 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class AllInterval
{
public class AllInterval {
/**
*
* Implements the all interval problem.
* See http://www.hakank.org/google_or_tools/all_interval.py
*
*/
private static void Solve(int n=12)
{
private static void Solve(int n = 12) {
Solver solver = new Solver("AllInterval");
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 0, n-1, "x");
IntVar[] diffs = solver.MakeIntVarArray(n-1, 1, n-1, "diffs");
IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x");
IntVar[] diffs = solver.MakeIntVarArray(n - 1, 1, n - 1, "diffs");
//
// Constraints
@@ -46,34 +41,34 @@ public class AllInterval
solver.Add(x.AllDifferent());
solver.Add(diffs.AllDifferent());
for(int k = 0; k < n - 1; k++) {
for (int k = 0; k < n - 1; k++) {
// solver.Add(diffs[k] == (x[k + 1] - x[k]).Abs());
solver.Add(diffs[k] == (x[k + 1] - x[k].Abs()));
solver.Add(diffs[k] == (x[k + 1] - x [k]
.Abs()));
}
// symmetry breaking
solver.Add(x[0] < x[n - 1]);
solver.Add(diffs[0] < diffs[1]);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x: ");
for(int i = 0; i < n; i++) {
Console.Write("{0} ", x[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", x [i]
.Value());
}
Console.Write(" diffs: ");
for(int i = 0; i < n-1; i++) {
Console.Write("{0} ", diffs[i].Value());
for (int i = 0; i < n - 1; i++) {
Console.Write("{0} ", diffs [i]
.Value());
}
Console.WriteLine();
}
@@ -84,12 +79,9 @@ public class AllInterval
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 12;
if (args.Length > 0) {
n = Convert.ToInt32(args[0]);

View File

@@ -16,24 +16,19 @@
using System;
using Google.OrTools.ConstraintSolver;
public class AllDifferentExcept0Test
{
public class AllDifferentExcept0Test {
//
// Decomposition of alldifferent_except_0
//
public static void AllDifferentExcept0(Solver solver, IntVar[] a) {
int n = a.Length;
for(int i = 0; i < n; i++) {
for(int j = 0; j < i; j++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
solver.Add((a[i] != 0) * (a[j] != 0) <= (a[i] != a[j]));
}
}
}
/**
*
* Decomposition of alldifferent_except_0
@@ -42,8 +37,7 @@ public class AllDifferentExcept0Test
*
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("AllDifferentExcept0");
//
@@ -54,7 +48,7 @@ public class AllDifferentExcept0Test
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1 , "x");
IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x");
//
// Constraints
@@ -63,25 +57,24 @@ public class AllDifferentExcept0Test
// we also require at least 2 0's
IntVar[] z_tmp = new IntVar[n];
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
z_tmp[i] = x[i] == 0;
}
IntVar z = z_tmp.Sum().VarWithName("z");
solver.Add(z == 2);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("z: {0} x: ", z.Value());
for(int i = 0; i < n; i++) {
Console.Write("{0} ", x[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", x [i]
.Value());
}
Console.WriteLine();
@@ -93,11 +86,7 @@ public class AllDifferentExcept0Test
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,9 +20,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class Assignment
{
public class Assignment {
/**
*
* Assignment problem
@@ -34,9 +32,7 @@ public class Assignment
* See See http://www.hakank.org/or-tools/assignment.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Assignment");
//
@@ -48,18 +44,13 @@ public class Assignment
// interesting
int rows = 4;
int cols = 5;
int[,] cost = {
{14, 5, 8, 7, 15},
{ 2, 12, 6, 5, 3},
{ 7, 8, 3, 9, 7},
{ 2, 4, 6, 10, 1}
};
int[, ] cost = {
{14, 5, 8, 7, 15}, {2, 12, 6, 5, 3}, {7, 8, 3, 9, 7}, {2, 4, 6, 10, 1}};
//
// Decision variables
//
IntVar[,] x = solver.MakeBoolVarMatrix(rows, cols, "x");
IntVar[, ] x = solver.MakeBoolVarMatrix(rows, cols, "x");
IntVar[] x_flat = x.Flatten();
//
@@ -68,57 +59,62 @@ public class Assignment
// Exacly one assignment per row (task),
// i.e. all rows must be assigned with one worker
for(int i = 0; i < rows; i++) {
solver.Add((from j in Enumerable.Range(0, cols)
select x[i,j]).ToArray().Sum() == 1);
for (int i = 0; i < rows; i++) {
solver.Add((from j in Enumerable.Range(0, cols) select x[i, j])
.ToArray()
.Sum() == 1);
}
// At most one assignments per column (worker)
for(int j = 0; j < cols; j++) {
solver.Add((from i in Enumerable.Range(0, rows)
select x[i,j]).ToArray().Sum() <= 1);
for (int j = 0; j < cols; j++) {
solver.Add((from i in Enumerable.Range(0, rows) select x[i, j])
.ToArray()
.Sum() <= 1);
}
// Total cost
IntVar total_cost = (from i in Enumerable.Range(0, rows)
from j in Enumerable.Range(0, cols)
select (cost[i,j] * x[i,j])).ToArray().Sum().Var();
IntVar total_cost =
(from i in Enumerable.Range(0, rows) from j in Enumerable.Range(0, cols)
select(cost[i, j] * x[i, j]))
.ToArray()
.Sum()
.Var();
//
// objective
//
OptimizeVar objective = total_cost.Minimize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, objective);
while (solver.NextSolution()) {
Console.WriteLine("total_cost: {0}", total_cost.Value());
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
Console.Write(x[i,j].Value() + " ");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
Console.Write(x [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("Assignments:");
for(int i = 0; i < rows; i++) {
for (int i = 0; i < rows; i++) {
Console.Write("Task " + i);
for(int j = 0; j < cols; j++) {
if (x[i,j].Value() == 1) {
for (int j = 0; j < cols; j++) {
if (x [i, j]
.Value() == 1) {
Console.WriteLine(" is done by " + j);
}
}
}
Console.WriteLine();
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -127,11 +123,7 @@ public class Assignment
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -17,10 +17,7 @@ using System;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class BrokenWeights
{
public class BrokenWeights {
/**
*
* Broken weights problem.
@@ -49,46 +46,40 @@ public class BrokenWeights
* Also see http://www.hakank.org/or-tools/broken_weights.py
*
*/
private static void Solve(int m=40, int n=4)
{
private static void Solve(int m = 40, int n = 4) {
Solver solver = new Solver("BrokenWeights");
Console.WriteLine("Total weight (m): {0}", m);
Console.WriteLine("Number of pieces (n): {0}", n);
Console.WriteLine();
//
// Decision variables
//
IntVar[] weights = solver.MakeIntVarArray(n, 1, m , "weights");
IntVar[,] x = new IntVar[m, n];
IntVar[] weights = solver.MakeIntVarArray(n, 1, m, "weights");
IntVar[, ] x = new IntVar[m, n];
// Note: in x_flat we insert the weights array before x
IntVar[] x_flat = new IntVar[m*n + n];
for(int j = 0; j < n; j++) {
IntVar[] x_flat = new IntVar[m * n + n];
for (int j = 0; j < n; j++) {
x_flat[j] = weights[j];
}
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
x[i,j] = solver.MakeIntVar(-1, 1, "x["+i+","+j+"]");
x_flat[n+i*n+j] = x[i,j];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
x[i, j] = solver.MakeIntVar(-1, 1, "x[" + i + "," + j + "]");
x_flat[n + i * n + j] = x[i, j];
}
}
//
// Constraints
//
// symmetry breaking
for(int j = 1; j < n; j++) {
solver.Add(weights[j-1] < weights[j]);
for (int j = 1; j < n; j++) {
solver.Add(weights[j - 1] < weights[j]);
}
solver.Add(weights.Sum() == m);
// Check that all weights from 1 to n (default 40) can be made.
@@ -98,41 +89,42 @@ public class BrokenWeights
// -1, 0, or 1 of the weights, assuming that
// -1 is the weights on the left and 1 is on the right.
//
for(int i = 0; i < m; i++) {
solver.Add( (from j in Enumerable.Range(0, n)
select weights[j] * x[i,j]).ToArray().Sum() == i+1);
for (int i = 0; i < m; i++) {
solver.Add((from j in Enumerable.Range(0, n) select weights[j] * x[i, j])
.ToArray()
.Sum() == i + 1);
}
//
// The objective is to minimize the last weight.
//
OptimizeVar obj = weights[n-1].Minimize(1);
OptimizeVar obj = weights [n - 1]
.Minimize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.Write("weights: ");
for(int i = 0; i < n; i++) {
Console.Write("{0,3} ", weights[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0,3} ", weights [i]
.Value());
}
Console.WriteLine();
for(int i = 0; i < 10+n*4; i++) {
for (int i = 0; i < 10 + n * 4; i++) {
Console.Write("-");
}
Console.WriteLine();
for(int i = 0; i < m; i++) {
Console.Write("weight {0,2}:", i+1);
for(int j = 0; j < n; j++) {
Console.Write("{0,3} ", x[i,j].Value());
for (int i = 0; i < m; i++) {
Console.Write("weight {0,2}:", i + 1);
for (int j = 0; j < n; j++) {
Console.Write("{0,3} ", x [i, j]
.Value());
}
Console.WriteLine();
}
@@ -145,12 +137,9 @@ public class BrokenWeights
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int m = 40;
int n = 4;

View File

@@ -20,10 +20,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class BusSchedule
{
public class BusSchedule {
/**
*
* Bus scheduling.
@@ -31,15 +28,13 @@ public class BusSchedule
* Minimize number of buses in timeslots.
*
* Problem from Taha "Introduction to Operations Research", page 58.
*
*
* This is a slightly more general model than Taha's.
*
* Also see, http://www.hakank.org/or-tools/bus_schedule.py
*
*/
private static long Solve(long num_buses_check = 0)
{
private static long Solve(long num_buses_check = 0) {
Solver solver = new Solver("BusSchedule");
//
@@ -63,44 +58,40 @@ public class BusSchedule
//
// Meet the demands for this and the next time slot.
for(int i = 0; i < time_slots - 1; i++) {
solver.Add(x[i]+x[i+1] >= demands[i]);
for (int i = 0; i < time_slots - 1; i++) {
solver.Add(x[i] + x[i + 1] >= demands[i]);
}
// The demand "around the clock"
solver.Add(x[time_slots-1] + x[0] - demands[time_slots-1] == 0);
solver.Add(x[time_slots - 1] + x[0] - demands[time_slots - 1] == 0);
// For showing all solutions of minimal number of buses
if (num_buses_check > 0) {
solver.Add(num_buses == num_buses_check);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
if (num_buses_check == 0) {
// Minimize num_buses
OptimizeVar obj = num_buses.Minimize(1);
solver.NewSearch(db, obj);
} else {
solver.NewSearch(db);
}
long result = 0;
while (solver.NextSolution()) {
result = num_buses.Value();
Console.Write("x: ");
for(int i = 0; i < time_slots; i++) {
Console.Write("{0,2} ", x[i].Value());
for (int i = 0; i < time_slots; i++) {
Console.Write("{0,2} ", x [i]
.Value());
}
Console.WriteLine("num_buses: " + num_buses.Value());
}
@@ -113,19 +104,13 @@ public class BusSchedule
solver.EndSearch();
return result;
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
Console.WriteLine("Check for minimum number of buses: ");
long num_buses = Solve();
Console.WriteLine("\n... got {0} as minimal value.", num_buses);
Console.WriteLine("\nAll solutions: ", num_buses);
num_buses = Solve(num_buses);
}
}

View File

@@ -19,11 +19,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class CircuitTest
{
public class CircuitTest {
/**
* circuit(solver, x)
*
@@ -34,7 +30,6 @@ public class CircuitTest
* since C# is 0-based.
*/
public static void circuit(Solver solver, IntVar[] x) {
int n = x.Length;
IntVar[] z = solver.MakeIntVarArray(n, 0, n - 1, "z");
@@ -43,18 +38,17 @@ public class CircuitTest
// put the orbit of x[0] in z[0..n-1]
solver.Add(z[0] == x[0]);
for(int i = 1; i < n-1; i++) {
solver.Add(z[i] == x.Element(z[i-1]));
for (int i = 1; i < n - 1; i++) {
solver.Add(z[i] == x.Element(z[i - 1]));
}
// z may not be 0 for i < n-1
for(int i = 1; i < n - 1; i++) {
for (int i = 1; i < n - 1; i++) {
solver.Add(z[i] != 0);
}
// when i = n-1 it must be 0
solver.Add(z[n - 1] == 0);
}
/**
@@ -63,35 +57,31 @@ public class CircuitTest
* See http://www.hakank.org/google_or_tools/circuit.py
*
*/
private static void Solve(int n = 5)
{
private static void Solve(int n = 5) {
Solver solver = new Solver("Circuit");
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 0, n-1, "x");
IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x");
//
// Constraints
//
circuit(solver, x);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
Console.Write("{0} ", x[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", x [i]
.Value());
}
Console.WriteLine();
}
@@ -102,12 +92,9 @@ public class CircuitTest
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 5;
if (args.Length > 0) {
n = Convert.ToInt32(args[0]);

View File

@@ -19,11 +19,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class CircuitTest2
{
public class CircuitTest2 {
/**
* circuit(solver, x, z)
*
@@ -36,7 +32,6 @@ public class CircuitTest2
* since C# is 0-based.
*/
public static void circuit(Solver solver, IntVar[] x, IntVar[] z) {
int n = x.Length;
solver.Add(x.AllDifferent());
@@ -44,18 +39,17 @@ public class CircuitTest2
// put the orbit of x[0] in z[0..n-1]
solver.Add(z[0] == x[0]);
for(int i = 1; i < n-1; i++) {
solver.Add(z[i] == x.Element(z[i-1]));
for (int i = 1; i < n - 1; i++) {
solver.Add(z[i] == x.Element(z[i - 1]));
}
// z may not be 0 for i < n-1
for(int i = 1; i < n - 1; i++) {
for (int i = 1; i < n - 1; i++) {
solver.Add(z[i] != 0);
}
// when i = n-1 it must be 0
solver.Add(z[n - 1] == 0);
}
/**
@@ -67,42 +61,38 @@ public class CircuitTest2
* Thus the extracted path is 0 -> 3 -> 2 -> 4 -> 1 -> 0
*
*/
private static void Solve(int n = 5)
{
private static void Solve(int n = 5) {
Solver solver = new Solver("CircuitTest2");
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 0, n-1, "x");
IntVar[] path = solver.MakeIntVarArray(n, 0, n-1, "path");
IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x");
IntVar[] path = solver.MakeIntVarArray(n, 0, n - 1, "path");
//
// Constraints
//
circuit(solver, x, path);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x : ");
for(int i = 0; i < n; i++) {
Console.Write("{0} ", x[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", x [i]
.Value());
}
Console.Write("\npath: ");
for(int i = 0; i < n; i++) {
Console.Write("{0} ", path[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", path [i]
.Value());
}
Console.WriteLine("\n");
}
@@ -113,12 +103,9 @@ public class CircuitTest2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 5;
if (args.Length > 0) {
n = Convert.ToInt32(args[0]);

View File

@@ -19,10 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class Coins3
{
public class Coins3 {
/**
*
* Coin application.
@@ -37,18 +34,16 @@ public class Coins3
* euro cents, of denomination 1, 2, 5, 10, 20, 50
* """
* Also see http://www.hakank.org/or-tools/coins3.py
* Also see http://www.hakank.org/or-tools/coins3.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Coins3");
//
// Data
//
int n = 6; // number of different coins
int n = 6; // number of different coins
int[] variables = {1, 2, 5, 10, 25, 50};
IEnumerable<int> RANGE = Enumerable.Range(0, n);
@@ -59,20 +54,18 @@ public class Coins3
IntVar[] x = solver.MakeIntVarArray(n, 0, 99, "x");
IntVar num_coins = x.Sum().VarWithName("num_coins");
//
// Constraints
//
// Check that all changes from 1 to 99 can be made.
for(int j = 1; j < 100; j++) {
for (int j = 1; j < 100; j++) {
IntVar[] tmp = solver.MakeIntVarArray(n, 0, 99, "tmp");
solver.Add(tmp.ScalProd(variables) == j);
foreach(int i in RANGE) {
foreach (int i in RANGE) {
solver.Add(tmp[i] <= x[i]);
}
}
//
@@ -83,8 +76,7 @@ public class Coins3
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
@@ -92,8 +84,10 @@ public class Coins3
while (solver.NextSolution()) {
Console.WriteLine("num_coins: {0}", num_coins.Value());
Console.Write("x: ");
foreach(int i in RANGE) {
Console.Write(x[i].Value() + " ");
foreach (int i in RANGE) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -104,11 +98,7 @@ public class Coins3
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,23 +16,20 @@
using System;
using Google.OrTools.ConstraintSolver;
public class CoinsGrid
{
public class CoinsGrid {
/**
*
* Solves the Coins Grid problm.
* See http://www.hakank.org/google_or_tools/coins_grid.py
*
*/
private static void Solve(int n = 31, int c = 14)
{
private static void Solve(int n = 31, int c = 14) {
Solver solver = new Solver("CoinsGrid");
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 0, 1 , "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 0, 1, "x");
IntVar[] x_flat = x.Flatten();
//
@@ -40,12 +37,12 @@ public class CoinsGrid
//
// sum row/columns == c
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
IntVar[] row = new IntVar[n];
IntVar[] col = new IntVar[n];
for(int j = 0; j < n; j++) {
row[j] = x[i,j];
col[j] = x[j,i];
for (int j = 0; j < n; j++) {
row[j] = x[i, j];
col[j] = x[j, i];
}
solver.Add(row.Sum() == c);
solver.Add(col.Sum() == c);
@@ -53,9 +50,9 @@ public class CoinsGrid
// quadratic horizonal distance
IntVar[] obj_tmp = new IntVar[n * n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
obj_tmp[i * n + j] = (x[i,j] * (i - j) * (i - j)).Var();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
obj_tmp[i * n + j] = (x[i, j] * (i - j) * (i - j)).Var();
}
}
IntVar obj_var = obj_tmp.Sum().Var();
@@ -68,17 +65,18 @@ public class CoinsGrid
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MAX_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("obj: " + obj_var.Value());
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
Console.Write(x[i,j].Value() + " ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write(x [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -91,11 +89,9 @@ public class CoinsGrid
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 31;
int c = 14;
@@ -107,7 +103,6 @@ public class CoinsGrid
c = Convert.ToInt32(args[1]);
}
Solve(n, c);
}
}

View File

@@ -19,8 +19,7 @@ using System.Collections;
using System.Collections.Generic;
using Google.OrTools.ConstraintSolver;
public class CombinatorialAuction2
{
public class CombinatorialAuction2 {
/**
*
* Combinatorial auction.
@@ -35,8 +34,7 @@ public class CombinatorialAuction2
* http://www.hakank.org/numberjack/combinatorial_auction.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("CombinatorialAuction2");
//
@@ -46,15 +44,15 @@ public class CombinatorialAuction2
// the items for each bid
int[][] items = {
new int[] {0,1}, // A,B
new int[] {0,2}, // A, C
new int[] {1,3}, // B,D
new int[] {1,2,3}, // B,C,D
new int[] {0} // A
new int[]{0, 1}, // A,B
new int[]{0, 2}, // A, C
new int[]{1, 3}, // B,D
new int[]{1, 2, 3}, // B,C,D
new int[]{0} // A
};
int[] bid_ids = {0,1,2,3};
int[] bid_amount = {10,20,30,40,14};
int[] bid_ids = {0, 1, 2, 3};
int[] bid_amount = {10, 20, 30, 40, 14};
//
// Decision variables
@@ -66,20 +64,15 @@ public class CombinatorialAuction2
// Constraints
//
foreach(int bid_id in bid_ids) {
foreach (int bid_id in bid_ids) {
var tmp2 = (from item in Enumerable.Range(0, n)
from i in Enumerable.Range(0, items[item].Length)
where items[item][i] == bid_id
select x[item]);
from i in Enumerable.Range(0, items[item].Length)
where items [item]
[i] == bid_id select x[item]);
solver.Add(tmp2.ToArray().Sum() <= 1);
}
//
// Objective
//
@@ -88,16 +81,17 @@ public class CombinatorialAuction2
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.Write("z: {0,2} x: ", z.Value());
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -108,11 +102,7 @@ public class CombinatorialAuction2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,10 +19,7 @@ using System.Linq;
using System.Diagnostics;
using Google.OrTools.ConstraintSolver;
public class ContiguityRegular
{
public class ContiguityRegular {
/*
* Global constraint regular
*
@@ -45,16 +42,8 @@ public class ContiguityRegular
* F : accepting states
*
*/
static void MyRegular(Solver solver,
IntVar[] x,
int Q,
int S,
int[,] d,
int q0,
int[] F) {
static void MyRegular(Solver solver, IntVar[] x, int Q, int S, int[, ] d,
int q0, int[] F) {
Debug.Assert(Q > 0, "regular: 'Q' must be greater than zero");
Debug.Assert(S > 0, "regular: 'S' must be greater than zero");
@@ -62,22 +51,25 @@ public class ContiguityRegular
// each possible input; each extra transition is from state zero
// to state zero. This allows us to continue even if we hit a
// non-accepted input.
int[][] d2 = new int[Q+1][];
for(int i = 0; i <= Q; i++) {
int[][] d2 = new int [Q + 1]
[];
for (int i = 0; i <= Q; i++) {
int[] row = new int[S];
for(int j = 0; j < S; j++) {
for (int j = 0; j < S; j++) {
if (i == 0) {
row[j] = 0;
} else {
row[j] = d[i-1,j];
row[j] = d[i - 1, j];
}
}
d2[i] = row;
}
int[] d2_flatten = (from i in Enumerable.Range(0, Q+1)
from j in Enumerable.Range(0, S)
select d2[i][j]).ToArray();
int[] d2_flatten =
(from i in Enumerable.Range(0, Q + 1) from j in Enumerable.Range(0, S)
select d2 [i]
[j])
.ToArray();
// If x has index set m..n, then a[m-1] holds the initial state
// (q0), and a[i+1] holds the state we're in after processing
@@ -86,50 +78,43 @@ public class ContiguityRegular
int m = 0;
int n = x.Length;
IntVar[] a = solver.MakeIntVarArray(n+1-m, 0,Q+1, "a");
IntVar[] a = solver.MakeIntVarArray(n + 1 - m, 0, Q + 1, "a");
// Check that the final state is in F
solver.Add(a[a.Length-1].Member(F));
solver.Add(a [a.Length - 1]
.Member(F));
// First state is q0
solver.Add(a[m] == q0);
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
solver.Add(x[i] >= 1);
solver.Add(x[i] <= S);
// Determine a[i+1]: a[i+1] == d2[a[i], x[i]]
solver.Add(a[i+1] == d2_flatten.Element(((a[i]*S)+(x[i]-1))));
solver.Add(a[i + 1] == d2_flatten.Element(((a[i] * S) + (x[i] - 1))));
}
}
static void MyContiguity(Solver solver, IntVar[] x) {
// the DFA (for regular)
int n_states = 3;
int input_max = 2;
int initial_state = 1; // note: state 0 is used for the failing state
// in MyRegular
int initial_state = 1; // note: state 0 is used for the failing state
// in MyRegular
// all states are accepting states
int[] accepting_states = {1,2,3};
int[] accepting_states = {1, 2, 3};
// The regular expression 0*1*0*
int[,] transition_fn =
{
{1,2}, // state 1 (start): input 0 -> state 1, input 1 -> state 2 i.e. 0*
{3,2}, // state 2: 1*
{3,0}, // state 3: 0*
};
MyRegular(solver, x, n_states, input_max, transition_fn,
initial_state, accepting_states);
int[, ] transition_fn = {
{1,
2}, // state 1 (start): input 0 -> state 1, input 1 -> state 2 i.e. 0*
{3, 2}, // state 2: 1*
{3, 0}, // state 3: 0*
};
MyRegular(solver, x, n_states, input_max, transition_fn, initial_state,
accepting_states);
}
/**
*
* Global constraint contiguity using regular
@@ -152,15 +137,13 @@ public class ContiguityRegular
* Also see http://www.hakank.org/or-tools/contiguity_regular.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("ContiguityRegular");
//
// Data
//
int n = 7; // length of the array
int n = 7; // length of the array
//
// Decision variables
@@ -169,26 +152,26 @@ public class ContiguityRegular
// Note: We use 1..2 (instead of 0..1) and subtract 1 in the solution
IntVar[] reg_input = solver.MakeIntVarArray(n, 1, 2, "reg_input");
//
// Constraints
//
MyContiguity(solver, reg_input);
//
// Search
//
DecisionBuilder db = solver.MakePhase(reg_input,
Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db = solver.MakePhase(
reg_input, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
// Note: here we subtract 1 to get 0..1
Console.Write((reg_input[i].Value()-1) + " ");
Console.Write((reg_input [i]
.Value() -
1) +
" ");
}
Console.WriteLine();
}
@@ -199,11 +182,7 @@ public class ContiguityRegular
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,35 +19,25 @@ using System.Linq;
using System.Diagnostics;
using Google.OrTools.ConstraintSolver;
public class ContiguityRegular
{
public class ContiguityRegular {
static void MyContiguity(Solver solver, IntVar[] x) {
// the DFA (for regular)
int initial_state = 1;
// all states are accepting states
int[] accepting_states = {1,2,3};
int[] accepting_states = {1, 2, 3};
// The regular expression 0*1*0* {state, input, next state}
long[][] transition_tuples = {
new long[] {1, 0, 1},
new long[] {1, 1, 2},
new long[] {2, 0, 3},
new long[] {2, 1, 2},
new long[] {3, 0, 3}
};
long[][] transition_tuples = {new long[]{1, 0, 1}, new long[]{1, 1, 2},
new long[]{2, 0, 3}, new long[]{2, 1, 2},
new long[]{3, 0, 3}};
IntTupleSet result = new IntTupleSet(3);
result.InsertAll(transition_tuples);
solver.Add(x.Transition(result,
initial_state,
accepting_states));
solver.Add(x.Transition(result, initial_state, accepting_states));
}
/**
*
* Global constraint contiguity using Transition
@@ -70,15 +60,13 @@ public class ContiguityRegular
* Also see http://www.hakank.org/or-tools/contiguity_regular.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("ContiguityRegular");
//
// Data
//
int n = 7; // length of the array
int n = 7; // length of the array
//
// Decision variables
@@ -86,25 +74,24 @@ public class ContiguityRegular
IntVar[] reg_input = solver.MakeIntVarArray(n, 0, 1, "reg_input");
//
// Constraints
//
MyContiguity(solver, reg_input);
//
// Search
//
DecisionBuilder db = solver.MakePhase(reg_input,
Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db = solver.MakePhase(
reg_input, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
Console.Write((reg_input[i].Value()) + " ");
for (int i = 0; i < n; i++) {
Console.Write((reg_input [i]
.Value()) +
" ");
}
Console.WriteLine();
}
@@ -115,11 +102,7 @@ public class ContiguityRegular
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,13 +20,11 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class CostasArray
{
public class CostasArray {
/**
*
* Costas array
*
*
* From http://mathworld.wolfram.com/CostasArray.html:
* """
* An order-n Costas array is a permutation on {1,...,n} such
@@ -36,15 +34,13 @@ public class CostasArray
* and {4}. Since each row contains no duplications, the permutation
* is therefore a Costas array.
* """
*
*
* Also see
* http://en.wikipedia.org/wiki/Costas_array
* http://hakank.org/or-tools/costas_array.py
*
*/
private static void Solve(int n = 6)
{
private static void Solve(int n = 6) {
Solver solver = new Solver("CostasArray");
//
@@ -56,19 +52,19 @@ public class CostasArray
// Decision variables
//
IntVar[] costas = solver.MakeIntVarArray(n, 1, n, "costas");
IntVar[,] differences = solver.MakeIntVarMatrix(n, n, -n+1, n-1,
"differences");
IntVar[, ] differences =
solver.MakeIntVarMatrix(n, n, -n + 1, n - 1, "differences");
//
// Constraints
//
// Fix the values in the lower triangle in the
// difference matrix to -n+1. This removes variants
// of the difference matrix for the the same Costas array.
for(int i = 0; i < n; i++) {
for(int j = 0; j <= i; j++ ) {
solver.Add(differences[i,j] == -n+1);
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
solver.Add(differences[i, j] == -n + 1);
}
}
@@ -77,75 +73,69 @@ public class CostasArray
//
solver.Add(costas.AllDifferent());
// "How do the positions in the Costas array relate
// to the elements of the distance triangle."
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i < j) {
solver.Add( differences[i,j] - (costas[j] - costas[j-i-1]) == 0);
solver.Add(differences[i, j] - (costas[j] - costas[j - i - 1]) == 0);
}
}
}
// "All entries in a particular row of the difference
// triangle must be distint."
for(int i = 0; i < n-2; i++) {
IntVar[] tmp = (
from j in Enumerable.Range(0, n)
where j > i
select differences[i,j]).ToArray();
for (int i = 0; i < n - 2; i++) {
IntVar[] tmp = (from j in Enumerable.Range(0, n)
where j > i select differences[i, j])
.ToArray();
solver.Add(tmp.AllDifferent());
}
//
// "All the following are redundant - only here to speed up search."
//
// "We can never place a 'token' in the same row as any other."
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i < j) {
solver.Add(differences[i,j] != 0);
solver.Add(differences[i,j] != 0);
solver.Add(differences[i, j] != 0);
solver.Add(differences[i, j] != 0);
}
}
}
for(int k = 2; k < n; k++) {
for(int l = 2; l < n; l++) {
for (int k = 2; k < n; k++) {
for (int l = 2; l < n; l++) {
if (k < l) {
solver.Add(
(differences[k-2,l-1] + differences[k,l]) -
(differences[k-1,l-1] + differences[k-1,l]) == 0
);
solver.Add((differences[k - 2, l - 1] + differences[k, l]) -
(differences[k - 1, l - 1] + differences[k - 1, l]) ==
0);
}
}
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(costas,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(costas, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("costas: ");
for(int i = 0; i < n; i++) {
Console.Write("{0} ", costas[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", costas [i]
.Value());
}
Console.WriteLine("\ndifferences:");
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
long v = differences[i,j].Value();
if (v == -n+1) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
long v = differences [i, j]
.Value();
if (v == -n + 1) {
Console.Write(" ");
} else {
Console.Write("{0,2} ", v);
@@ -162,13 +152,9 @@ public class CostasArray
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 6;
if (args.Length > 0) {
@@ -176,6 +162,5 @@ public class CostasArray
}
Solve(n);
}
}

View File

@@ -19,18 +19,14 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class SetCoveringOPL
{
public class SetCoveringOPL {
/**
*
* Solves a set covering problem.
* See See http://www.hakank.org/or-tools/set_covering_opl.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SetCoveringOPL");
//
@@ -41,28 +37,25 @@ public class SetCoveringOPL
// Which worker is qualified for each task.
// Note: This is 1-based and will be made 0-base below.
int[][] qualified = {
new int[] { 1, 9, 19, 22, 25, 28, 31 },
new int[] { 2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32 },
new int[] { 3, 10, 19, 24, 26, 30, 32 },
new int[] { 4, 21, 25, 28, 32 },
new int[] { 5, 11, 16, 22, 23, 27, 31 },
new int[] { 6, 20, 24, 26, 30, 32 },
new int[] { 7, 12, 17, 25, 30, 31 } ,
new int[] { 8, 17, 20, 22, 23 },
new int[] { 9, 13, 14, 26, 29, 30, 31 },
new int[] { 10, 21, 25, 31, 32 },
new int[] { 14, 15, 18, 23, 24, 27, 30, 32 },
new int[] { 18, 19, 22, 24, 26, 29, 31 },
new int[] { 11, 20, 25, 28, 30, 32 },
new int[] { 16, 19, 23, 31 },
new int[] { 9, 18, 26, 28, 31, 32 }
};
int[][] qualified = {new int[]{1, 9, 19, 22, 25, 28, 31},
new int[]{2, 12, 15, 19, 21, 23, 27, 29, 30, 31, 32},
new int[]{3, 10, 19, 24, 26, 30, 32},
new int[]{4, 21, 25, 28, 32},
new int[]{5, 11, 16, 22, 23, 27, 31},
new int[]{6, 20, 24, 26, 30, 32},
new int[]{7, 12, 17, 25, 30, 31},
new int[]{8, 17, 20, 22, 23},
new int[]{9, 13, 14, 26, 29, 30, 31},
new int[]{10, 21, 25, 31, 32},
new int[]{14, 15, 18, 23, 24, 27, 30, 32},
new int[]{18, 19, 22, 24, 26, 29, 31},
new int[]{11, 20, 25, 28, 30, 32},
new int[]{16, 19, 23, 31},
new int[]{9, 18, 26, 28, 31, 32}};
int[] cost = {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3,
3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 9};
//
// Decision variables
//
@@ -73,29 +66,29 @@ public class SetCoveringOPL
// Constraints
//
for(int j = 0; j < num_tasks; j++) {
for (int j = 0; j < num_tasks; j++) {
// Sum the cost for hiring the qualified workers
// (also, make 0-base).
int len = qualified[j].Length;
IntVar[] tmp = new IntVar[len];
for(int c = 0; c < len; c++) {
tmp[c] = hire[qualified[j][c] - 1];
for (int c = 0; c < len; c++) {
tmp[c] = hire [qualified [j]
[c]
- 1]
;
}
solver.Add(tmp.Sum() >= 1);
}
//
// objective
//
OptimizeVar objective = total_cost.Minimize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(hire,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(hire, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, objective);
@@ -103,13 +96,13 @@ public class SetCoveringOPL
while (solver.NextSolution()) {
Console.WriteLine("Cost: " + total_cost.Value());
Console.Write("Hire: ");
for(int i = 0; i < num_workers; i++) {
if (hire[i].Value() == 1) {
for (int i = 0; i < num_workers; i++) {
if (hire [i]
.Value() == 1) {
Console.Write(i + " ");
}
}
Console.WriteLine("\n");
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -118,11 +111,7 @@ public class SetCoveringOPL
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,10 +20,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class Crew
{
public class Crew {
/**
*
* Crew allocation problem in Google CP Solver.
@@ -41,65 +38,46 @@ public class Crew
* Also see http://www.hakank.org/or-tools/crew.pl
*
*/
private static void Solve(int sols = 1, int minimize = 0)
{
private static void Solve(int sols = 1, int minimize = 0) {
Solver solver = new Solver("Crew");
//
// Data
//
string[] names = {"Tom",
"David",
"Jeremy",
"Ron",
"Joe",
"Bill",
"Fred",
"Bob",
"Mario",
"Ed",
"Carol",
"Janet",
"Tracy",
"Marilyn",
"Carolyn",
"Cathy",
"Inez",
"Jean",
"Heather",
"Juliet"};
string[] names = {"Tom", "David", "Jeremy", "Ron", "Joe",
"Bill", "Fred", "Bob", "Mario", "Ed",
"Carol", "Janet", "Tracy", "Marilyn", "Carolyn",
"Cathy", "Inez", "Jean", "Heather", "Juliet"};
int num_persons = names.Length;
//
// Attributes of the crew
//
int[,] attributes = {
// steward, hostess, french, spanish, german
{1,0,0,0,1}, // Tom = 0
{1,0,0,0,0}, // David = 1
{1,0,0,0,1}, // Jeremy = 2
{1,0,0,0,0}, // Ron = 3
{1,0,0,1,0}, // Joe = 4
{1,0,1,1,0}, // Bill = 5
{1,0,0,1,0}, // Fred = 6
{1,0,0,0,0}, // Bob = 7
{1,0,0,1,1}, // Mario = 8
{1,0,0,0,0}, // Ed = 9
{0,1,0,0,0}, // Carol = 10
{0,1,0,0,0}, // Janet = 11
{0,1,0,0,0}, // Tracy = 12
{0,1,0,1,1}, // Marilyn = 13
{0,1,0,0,0}, // Carolyn = 14
{0,1,0,0,0}, // Cathy = 15
{0,1,1,1,1}, // Inez = 16
{0,1,1,0,0}, // Jean = 17
{0,1,0,1,1}, // Heather = 18
{0,1,1,0,0} // Juliet = 19
int[, ] attributes = {
// steward, hostess, french, spanish, german
{1, 0, 0, 0, 1}, // Tom = 0
{1, 0, 0, 0, 0}, // David = 1
{1, 0, 0, 0, 1}, // Jeremy = 2
{1, 0, 0, 0, 0}, // Ron = 3
{1, 0, 0, 1, 0}, // Joe = 4
{1, 0, 1, 1, 0}, // Bill = 5
{1, 0, 0, 1, 0}, // Fred = 6
{1, 0, 0, 0, 0}, // Bob = 7
{1, 0, 0, 1, 1}, // Mario = 8
{1, 0, 0, 0, 0}, // Ed = 9
{0, 1, 0, 0, 0}, // Carol = 10
{0, 1, 0, 0, 0}, // Janet = 11
{0, 1, 0, 0, 0}, // Tracy = 12
{0, 1, 0, 1, 1}, // Marilyn = 13
{0, 1, 0, 0, 0}, // Carolyn = 14
{0, 1, 0, 0, 0}, // Cathy = 15
{0, 1, 1, 1, 1}, // Inez = 16
{0, 1, 1, 0, 0}, // Jean = 17
{0, 1, 0, 1, 1}, // Heather = 18
{0, 1, 1, 0, 0} // Juliet = 19
};
//
// Required number of crew members.
//
@@ -111,27 +89,22 @@ public class Crew
// spanish : How many Spanish speaking employees are required
// german : How many German speaking employees are required
//
int[,] required_crew = {
{4,1,1,1,1,1}, // Flight 1
{5,1,1,1,1,1}, // Flight 2
{5,1,1,1,1,1}, // ..
{6,2,2,1,1,1},
{7,3,3,1,1,1},
{4,1,1,1,1,1},
{5,1,1,1,1,1},
{6,1,1,1,1,1},
{6,2,2,1,1,1}, // ...
{7,3,3,1,1,1} // Flight 10
};
int[, ] required_crew = {
{4, 1, 1, 1, 1, 1}, // Flight 1
{5, 1, 1, 1, 1, 1}, // Flight 2
{5, 1, 1, 1, 1, 1}, // ..
{6, 2, 2, 1, 1, 1}, {7, 3, 3, 1, 1, 1}, {4, 1, 1, 1, 1, 1},
{5, 1, 1, 1, 1, 1}, {6, 1, 1, 1, 1, 1}, {6, 2, 2, 1, 1, 1}, // ...
{7, 3, 3, 1, 1, 1} // Flight 10
};
int num_flights = required_crew.GetLength(0);
//
// Decision variables
//
IntVar[,] crew = solver.MakeIntVarMatrix(num_flights, num_persons,
0, 1, "crew");
IntVar[, ] crew =
solver.MakeIntVarMatrix(num_flights, num_persons, 0, 1, "crew");
IntVar[] crew_flat = crew.Flatten();
// number of working persons
@@ -143,37 +116,37 @@ public class Crew
// number of working persons
IntVar[] nw = new IntVar[num_persons];
for(int p = 0; p < num_persons; p++) {
for (int p = 0; p < num_persons; p++) {
IntVar[] tmp = new IntVar[num_flights];
for(int f = 0; f < num_flights; f++) {
tmp[f] = crew[f,p];
for (int f = 0; f < num_flights; f++) {
tmp[f] = crew[f, p];
}
nw[p] = tmp.Sum() > 0;
}
solver.Add(nw.Sum() == num_working);
for(int f = 0; f < num_flights; f++) {
for (int f = 0; f < num_flights; f++) {
// size of crew
IntVar[] tmp = new IntVar[num_persons];
for(int p = 0; p < num_persons; p++) {
tmp[p] = crew[f,p];
for (int p = 0; p < num_persons; p++) {
tmp[p] = crew[f, p];
}
solver.Add(tmp.Sum() == required_crew[f,0]);
solver.Add(tmp.Sum() == required_crew[f, 0]);
// attributes and requirements
for(int a = 0; a < 5; a++) {
for (int a = 0; a < 5; a++) {
IntVar[] tmp2 = new IntVar[num_persons];
for(int p = 0; p < num_persons; p++) {
tmp2[p] = (crew[f,p]*attributes[p,a]).Var();
for (int p = 0; p < num_persons; p++) {
tmp2[p] = (crew[f, p] * attributes[p, a]).Var();
}
solver.Add(tmp2.Sum() >= required_crew[f,a+1]);
solver.Add(tmp2.Sum() >= required_crew[f, a + 1]);
}
}
// after a flight, break for at least two flights
for(int f = 0; f < num_flights - 2; f++) {
for(int i = 0; i < num_persons; i++) {
solver.Add(crew[f,i] + crew[f+1,i] + crew[f+2,i] <= 1);
for (int f = 0; f < num_flights - 2; f++) {
for (int i = 0; i < num_persons; i++) {
solver.Add(crew[f, i] + crew[f + 1, i] + crew[f + 2, i] <= 1);
}
}
@@ -188,13 +161,11 @@ public class Crew
}
*/
//
// Search
//
DecisionBuilder db = solver.MakePhase(crew_flat,
Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db = solver.MakePhase(
crew_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
if (minimize > 0) {
OptimizeVar obj = num_working.Minimize(1);
@@ -209,17 +180,20 @@ public class Crew
Console.WriteLine("Solution #{0}", num_solutions);
Console.WriteLine("Number working: {0}", num_working.Value());
for(int f = 0; f < num_flights; f++) {
for(int p = 0; p < num_persons; p++) {
Console.Write(crew[f,p].Value() + " ");
for (int f = 0; f < num_flights; f++) {
for (int p = 0; p < num_persons; p++) {
Console.Write(crew [f, p]
.Value() +
" ");
}
Console.WriteLine();
}
Console.WriteLine("\nFlights: ");
for(int f = 0; f < num_flights; f++) {
for (int f = 0; f < num_flights; f++) {
Console.Write("Flight #{0}: ", f);
for(int p = 0; p < num_persons; p++) {
if (crew[f, p].Value() == 1) {
for (int p = 0; p < num_persons; p++) {
if (crew [f, p]
.Value() == 1) {
Console.Write(names[p] + " ");
}
}
@@ -227,10 +201,11 @@ public class Crew
}
Console.WriteLine("\nCrew:");
for(int p = 0; p < num_persons; p++) {
for (int p = 0; p < num_persons; p++) {
Console.Write("{0,-10}", names[p]);
for(int f = 0; f < num_flights; f++) {
if (crew[f,p].Value() == 1) {
for (int f = 0; f < num_flights; f++) {
if (crew [f, p]
.Value() == 1) {
Console.Write(f + " ");
}
}
@@ -242,7 +217,6 @@ public class Crew
if (num_solutions >= sols) {
break;
}
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -251,14 +225,11 @@ public class Crew
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 1;
int min = 0; // > 0 -> minimize num_working
int min = 0; // > 0 -> minimize num_working
if (args.Length > 0) {
n = Convert.ToInt32(args[0]);
}

View File

@@ -19,15 +19,11 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
// Note: During compilation, there are a couple of
// warnings about assigned but never used variables.
// It's the characters a..z so it's quite benign.
public class Crossword
{
public class Crossword {
/**
*
* Solving a simple crossword.
@@ -35,59 +31,78 @@ public class Crossword
*
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Crossword");
//
// data
//
String[] alpha = {"_","a","b","c","d","e","f",
"g","h","i","j","k","l","m",
"n","o","p","q","r","s","t",
"u","v","w","x","y","z"};
String[] alpha = {"_", "a", "b", "c", "d", "e", "f", "g", "h",
"i", "j", "k", "l", "m", "n", "o", "p", "q",
"r", "s", "t", "u", "v", "w", "x", "y", "z"};
int a=1; int b=2; int c=3; int d=4; int e=5; int f=6;
int g=7; int h=8; int i=9; int j=10; int k=11; int l=12;
int m=13; int n=14; int o=15; int p=16; int q=17; int r=18;
int s=19; int t=20; int u=21; int v=22; int w=23; int x=24;
int y=25; int z=26;
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int h = 8;
int i = 9;
int j = 10;
int k = 11;
int l = 12;
int m = 13;
int n = 14;
int o = 15;
int p = 16;
int q = 17;
int r = 18;
int s = 19;
int t = 20;
int u = 21;
int v = 22;
int w = 23;
int x = 24;
int y = 25;
int z = 26;
const int num_words = 15;
int word_len = 5;
int[,] AA = {{h, o, s, e, s}, // HOSES
{l, a, s, e, r}, // LASER
{s, a, i, l, s}, // SAILS
{s, h, e, e, t}, // SHEET
{s, t, e, e, r}, // STEER
{h, e, e, l, 0}, // HEEL
{h, i, k, e, 0}, // HIKE
{k, e, e, l, 0}, // KEEL
{k, n, o, t, 0}, // KNOT
{l, i, n, e, 0}, // LINE
{a, f, t, 0, 0}, // AFT
{a, l, e, 0, 0}, // ALE
{e, e, l, 0, 0}, // EEL
{l, e, e, 0, 0}, // LEE
{t, i, e, 0, 0}}; // TIE
int[, ] AA = {{h, o, s, e, s}, // HOSES
{l, a, s, e, r}, // LASER
{s, a, i, l, s}, // SAILS
{s, h, e, e, t}, // SHEET
{s, t, e, e, r}, // STEER
{h, e, e, l, 0}, // HEEL
{h, i, k, e, 0}, // HIKE
{k, e, e, l, 0}, // KEEL
{k, n, o, t, 0}, // KNOT
{l, i, n, e, 0}, // LINE
{a, f, t, 0, 0}, // AFT
{a, l, e, 0, 0}, // ALE
{e, e, l, 0, 0}, // EEL
{l, e, e, 0, 0}, // LEE
{t, i, e, 0, 0}}; // TIE
int num_overlapping = 12;
int[,] overlapping = {{0, 2, 1, 0}, // s
{0, 4, 2, 0}, // s
int[, ] overlapping = {{0, 2, 1, 0}, // s
{0, 4, 2, 0}, // s
{3, 1, 1, 2}, // i
{3, 2, 4, 0}, // k
{3, 3, 2, 2}, // e
{3, 1, 1, 2}, // i
{3, 2, 4, 0}, // k
{3, 3, 2, 2}, // e
{6, 0, 1, 3}, // l
{6, 1, 4, 1}, // e
{6, 2, 2, 3}, // e
{6, 0, 1, 3}, // l
{6, 1, 4, 1}, // e
{6, 2, 2, 3}, // e
{7, 0, 5, 1}, // l
{7, 2, 1, 4}, // s
{7, 3, 4, 2}, // e
{7, 4, 2, 4}}; // r
{7, 0, 5, 1}, // l
{7, 2, 1, 4}, // s
{7, 3, 4, 2}, // e
{7, 4, 2, 4}}; // r
int N = 8;
@@ -95,33 +110,28 @@ public class Crossword
// Decision variables
//
// for labeling on A and E
IntVar[,] A = solver.MakeIntVarMatrix(num_words, word_len,
0, 26, "A");
IntVar[, ] A = solver.MakeIntVarMatrix(num_words, word_len, 0, 26, "A");
IntVar[] A_flat = A.Flatten();
IntVar[] all = new IntVar[(num_words * word_len) + N];
for(int I = 0; I < num_words; I++) {
for(int J = 0; J < word_len; J++) {
all[I * word_len + J] = A[I,J];
for (int I = 0; I < num_words; I++) {
for (int J = 0; J < word_len; J++) {
all[I * word_len + J] = A[I, J];
}
}
IntVar[] E = solver.MakeIntVarArray(N, 0, num_words, "E");
for(int I = 0; I < N; I++) {
for (int I = 0; I < N; I++) {
all[num_words * word_len + I] = E[I];
}
//
// Constraints
//
solver.Add(E.AllDifferent());
for(int I = 0; I < num_words; I++) {
for(int J = 0; J < word_len; J++) {
solver.Add(A[I,J] == AA[I,J]);
for (int I = 0; I < num_words; I++) {
for (int J = 0; J < word_len; J++) {
solver.Add(A[I, J] == AA[I, J]);
}
}
@@ -139,30 +149,30 @@ public class Crossword
// ==
// solver.Element(A_flat,E[overlapping[I][2]]*word_len+overlapping[I][3]))
//
for(int I = 0; I < num_overlapping; I++) {
for (int I = 0; I < num_overlapping; I++) {
solver.Add(
A_flat.Element(E[overlapping[I,0]] * word_len + overlapping[I,1]) ==
A_flat.Element(E[overlapping[I,2]] * word_len + overlapping[I,3]));
A_flat.Element(E[overlapping[I, 0]] * word_len + overlapping[I, 1]) ==
A_flat.Element(E[overlapping[I, 2]] * word_len + overlapping[I, 3]));
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(all,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(all, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.WriteLine("E: ");
for(int ee = 0; ee < N; ee++) {
int e_val = (int)E[ee].Value();
for (int ee = 0; ee < N; ee++) {
int e_val = (int) E [ee]
.Value();
Console.Write(ee + ": (" + e_val + ") ");
for(int ii = 0; ii < word_len; ii++) {
Console.Write(alpha[(int)A[ee,ii].Value()]);
for (int ii = 0; ii < word_len; ii++) {
Console.Write(alpha [(int) A [ee, ii]
.Value()]
);
}
Console.WriteLine();
}
@@ -176,13 +186,7 @@ public class Crossword
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,12 +16,11 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Crypta
{
public class Crypta {
/**
*
* Cryptarithmetic puzzle.
*
*
* Prolog benchmark problem GNU Prolog (crypta.pl)
* """
* Name : crypta.pl
@@ -42,8 +41,7 @@ public class Crypta
* Also see http://hakank.org/or-tools/crypta.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Crypta");
//
@@ -60,12 +58,11 @@ public class Crypta
IntVar I = solver.MakeIntVar(0, 9, "I");
IntVar J = solver.MakeIntVar(0, 9, "J");
IntVar[] LD = new IntVar[] {A,B,C,D,E,F,G,H,I,J};
IntVar[] LD = new IntVar[]{A, B, C, D, E, F, G, H, I, J};
IntVar Sr1 = solver.MakeIntVar(0, 1, "Sr1");
IntVar Sr2 = solver.MakeIntVar(0, 1, "Sr2");
//
// Constraints
//
@@ -74,32 +71,35 @@ public class Crypta
solver.Add(D >= 1);
solver.Add(G >= 1);
solver.Add((A+10*E+100*J+1000*B+10000*B+100000*E+1000000*F+
E+10*J+100*E+1000*F+10000*G+100000*A+1000000*F) ==
(F+10*E+100*E+1000*H+10000*I+100000*F+1000000*B+10000000*Sr1));
solver.Add((A + 10 * E + 100 * J + 1000 * B + 10000 * B + 100000 * E +
1000000 * F + E + 10 * J + 100 * E + 1000 * F + 10000 * G +
100000 * A + 1000000 * F) ==
(F + 10 * E + 100 * E + 1000 * H + 10000 * I + 100000 * F +
1000000 * B + 10000000 * Sr1));
solver.Add((C + 10 * F + 100 * H + 1000 * A + 10000 * I + 100000 * I +
1000000 * J + F + 10 * I + 100 * B + 1000 * D + 10000 * I +
100000 * D + 1000000 * C + Sr1) ==
(J + 10 * F + 100 * A + 1000 * F + 10000 * H + 100000 * D +
1000000 * D + 10000000 * Sr2));
solver.Add((C+10*F+100*H+1000*A+10000*I+100000*I+1000000*J+
F+10*I+100*B+1000*D+10000*I+100000*D+1000000*C+Sr1) ==
(J+10*F+100*A+1000*F+10000*H+100000*D+1000000*D+10000000*Sr2));
solver.Add((A+10*J+100*J+1000*I+10000*A+100000*B+
B+10*A+100*G+1000*F+10000*H+100000*D+Sr2) ==
(C+10*A+100*G+1000*E+10000*J+100000*G));
solver.Add((A + 10 * J + 100 * J + 1000 * I + 10000 * A + 100000 * B + B +
10 * A + 100 * G + 1000 * F + 10000 * H + 100000 * D + Sr2) ==
(C + 10 * A + 100 * G + 1000 * E + 10000 * J + 100000 * G));
//
// Search
//
DecisionBuilder db = solver.MakePhase(LD,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(LD, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < 10; i++) {
Console.Write(LD[i].ToString() + " ");
for (int i = 0; i < 10; i++) {
Console.Write(LD [i]
.ToString() +
" ");
}
Console.WriteLine();
}
@@ -109,11 +109,7 @@ public class Crypta
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,12 +16,11 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Crypto
{
public class Crypto {
/**
*
* Crypto problem.
*
*
* This is the standard benchmark "crypto" problem.
*
* From GLPK:s model cryto.mod.
@@ -52,33 +51,31 @@ public class Crypto
* Also see http://hakank.org/or-tools/crypto.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Crypto");
int num_letters = 26;
int BALLET = 45;
int CELLO = 43;
int CONCERT = 74;
int FLUTE = 30;
int FUGUE = 50;
int GLEE = 66;
int JAZZ = 58;
int LYRE = 47;
int OBOE = 53;
int OPERA = 65;
int POLKA = 59;
int QUARTET = 50;
int SAXOPHONE = 134;
int SCALE = 51;
int SOLO = 37;
int SONG = 61;
int SOPRANO = 82;
int THEME = 72;
int VIOLIN = 100;
int WALTZ = 34;
int BALLET = 45;
int CELLO = 43;
int CONCERT = 74;
int FLUTE = 30;
int FUGUE = 50;
int GLEE = 66;
int JAZZ = 58;
int LYRE = 47;
int OBOE = 53;
int OPERA = 65;
int POLKA = 59;
int QUARTET = 50;
int SAXOPHONE = 134;
int SCALE = 51;
int SOLO = 37;
int SONG = 61;
int SOPRANO = 82;
int THEME = 72;
int VIOLIN = 100;
int WALTZ = 34;
//
// Decision variables
@@ -86,53 +83,71 @@ public class Crypto
IntVar[] LD = solver.MakeIntVarArray(num_letters, 1, num_letters, "LD");
// Note D is not used in the constraints below
IntVar A = LD[0]; IntVar B = LD[1]; IntVar C = LD[2]; // IntVar D = LD[3];
IntVar E = LD[4]; IntVar F = LD[5]; IntVar G = LD[6]; IntVar H = LD[7];
IntVar I = LD[8]; IntVar J = LD[9]; IntVar K = LD[10]; IntVar L = LD[11];
IntVar M = LD[12]; IntVar N = LD[13]; IntVar O = LD[14]; IntVar P = LD[15];
IntVar Q = LD[16]; IntVar R = LD[17]; IntVar S = LD[18]; IntVar T = LD[19];
IntVar U = LD[20]; IntVar V = LD[21]; IntVar W = LD[22]; IntVar X = LD[23];
IntVar Y = LD[24]; IntVar Z = LD[25];
IntVar A = LD[0];
IntVar B = LD[1];
IntVar C = LD[2]; // IntVar D = LD[3];
IntVar E = LD[4];
IntVar F = LD[5];
IntVar G = LD[6];
IntVar H = LD[7];
IntVar I = LD[8];
IntVar J = LD[9];
IntVar K = LD[10];
IntVar L = LD[11];
IntVar M = LD[12];
IntVar N = LD[13];
IntVar O = LD[14];
IntVar P = LD[15];
IntVar Q = LD[16];
IntVar R = LD[17];
IntVar S = LD[18];
IntVar T = LD[19];
IntVar U = LD[20];
IntVar V = LD[21];
IntVar W = LD[22];
IntVar X = LD[23];
IntVar Y = LD[24];
IntVar Z = LD[25];
//
// Constraints
//
solver.Add(LD.AllDifferent());
solver.Add( B + A + L + L + E + T == BALLET);
solver.Add( C + E + L + L + O == CELLO);
solver.Add( C + O + N + C + E + R + T == CONCERT);
solver.Add( F + L + U + T + E == FLUTE);
solver.Add( F + U + G + U + E == FUGUE);
solver.Add( G + L + E + E == GLEE);
solver.Add( J + A + Z + Z == JAZZ);
solver.Add( L + Y + R + E == LYRE);
solver.Add( O + B + O + E == OBOE);
solver.Add( O + P + E + R + A == OPERA);
solver.Add( P + O + L + K + A == POLKA);
solver.Add( Q + U + A + R + T + E + T == QUARTET);
solver.Add(B + A + L + L + E + T == BALLET);
solver.Add(C + E + L + L + O == CELLO);
solver.Add(C + O + N + C + E + R + T == CONCERT);
solver.Add(F + L + U + T + E == FLUTE);
solver.Add(F + U + G + U + E == FUGUE);
solver.Add(G + L + E + E == GLEE);
solver.Add(J + A + Z + Z == JAZZ);
solver.Add(L + Y + R + E == LYRE);
solver.Add(O + B + O + E == OBOE);
solver.Add(O + P + E + R + A == OPERA);
solver.Add(P + O + L + K + A == POLKA);
solver.Add(Q + U + A + R + T + E + T == QUARTET);
solver.Add(S + A + X + O + P + H + O + N + E == SAXOPHONE);
solver.Add( S + C + A + L + E == SCALE);
solver.Add( S + O + L + O == SOLO);
solver.Add( S + O + N + G == SONG);
solver.Add( S + O + P + R + A + N + O == SOPRANO);
solver.Add( T + H + E + M + E == THEME);
solver.Add( V + I + O + L + I + N == VIOLIN);
solver.Add( W + A + L + T + Z == WALTZ);
solver.Add(S + C + A + L + E == SCALE);
solver.Add(S + O + L + O == SOLO);
solver.Add(S + O + N + G == SONG);
solver.Add(S + O + P + R + A + N + O == SOPRANO);
solver.Add(T + H + E + M + E == THEME);
solver.Add(V + I + O + L + I + N == VIOLIN);
solver.Add(W + A + L + T + Z == WALTZ);
//
// Search
//
DecisionBuilder db = solver.MakePhase(LD,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
DecisionBuilder db = solver.MakePhase(LD, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_CENTER_VALUE);
solver.NewSearch(db);
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
while (solver.NextSolution()) {
for(int i = 0; i < num_letters; i++) {
Console.WriteLine("{0}: {1,2}", str[i], LD[i].Value());
for (int i = 0; i < num_letters; i++) {
Console.WriteLine("{0}: {1,2}", str[i],
LD [i]
.Value());
}
Console.WriteLine();
}
@@ -142,11 +157,7 @@ public class Crypto
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,8 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Diet
{
public class Diet {
/**
*
* Solves the Diet problem
@@ -25,24 +24,21 @@ public class Diet
* See http://www.hakank.org/google_or_tools/diet1.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Diet");
int n = 4;
int[] price = { 50, 20, 30, 80}; // in cents
int[] price = {50, 20, 30, 80}; // in cents
// requirements for each nutrition type
int[] limits = {500, 6, 10, 8};
int[] limits = {500, 6, 10, 8};
string[] products = {"A", "B", "C", "D"};
// nutritions for each product
int[] calories = {400, 200, 150, 500};
int[] calories = {400, 200, 150, 500};
int[] chocolate = {3, 2, 0, 0};
int[] sugar = {2, 2, 4, 4};
int[] fat = {2, 4, 1, 5};
int[] sugar = {2, 2, 4, 4};
int[] fat = {2, 4, 1, 5};
//
// Decision variables
@@ -50,19 +46,17 @@ public class Diet
IntVar[] x = solver.MakeIntVarArray(n, 0, 100, "x");
IntVar cost = x.ScalProd(price).Var();
//
// Constraints
//
// solver.Add(solver.MakeScalProdGreaterOrEqual(x, calories, limits[0]));
solver.Add(x.ScalProd(calories) >= limits[0]);
solver.Add(x.ScalProd(chocolate) >= limits[1]);
solver.Add(x.ScalProd(sugar) >= limits[2]);
solver.Add(x.ScalProd(fat) >= limits[3]);
//
// solver.Add(solver.MakeScalProdGreaterOrEqual(x, calories, limits[0]));
solver.Add(x.ScalProd(calories) >= limits[0]);
solver.Add(x.ScalProd(chocolate) >= limits[1]);
solver.Add(x.ScalProd(sugar) >= limits[2]);
solver.Add(x.ScalProd(fat) >= limits[3]);
//
// Objective
//
OptimizeVar obj = cost.Minimize(1);
@@ -70,18 +64,19 @@ public class Diet
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_PATH,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db =
solver.MakePhase(x, Solver.CHOOSE_PATH, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("cost: {0}", cost.Value());
Console.WriteLine("Products: ");
for(int i = 0; i < n; i++) {
Console.WriteLine("{0}: {1}", products[i], x[i].Value());
for (int i = 0; i < n; i++) {
Console.WriteLine("{0}: {1}", products[i],
x [i]
.Value());
}
Console.WriteLine();
}
@@ -91,11 +86,7 @@ public class Diet
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,17 +20,13 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class CuriousSetOfIntegers
{
public class CuriousSetOfIntegers {
public static void Decreasing(Solver solver, IntVar[] x) {
for(int i = 0; i < x.Length - 1; i++) {
solver.Add(x[i] <= x[i+1]);
for (int i = 0; i < x.Length - 1; i++) {
solver.Add(x[i] <= x[i + 1]);
}
}
/**
*
* Crypto problem in Google CP Solver.
@@ -46,9 +42,7 @@ public class CuriousSetOfIntegers
* Also see, http://www.hakank.org/or-tools/curious_set_of_integers.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("CuriousSetOfIntegers");
//
@@ -67,8 +61,8 @@ public class CuriousSetOfIntegers
//
solver.Add(x.AllDifferent());
for(int i = 0; i < n - 1; i++) {
for(int j = i + 1; j < n; j++) {
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
IntVar p = solver.MakeIntVar(0, max_val);
solver.Add((p.Square() - 1) - (x[i] * x[j]) == 0);
}
@@ -79,25 +73,26 @@ public class CuriousSetOfIntegers
// This is the original problem
// Which is the fifth number?
int[] v = {1,3,8,120};
IntVar[] b = (from i in Enumerable.Range(0, n)
select x[i].IsMember(v)).ToArray();
int[] v = {1, 3, 8, 120};
IntVar[] b = (from i in Enumerable
.Range(0, n) select x [i]
.IsMember(v))
.ToArray();
solver.Add(b.Sum() == 4);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -108,15 +103,7 @@ public class CuriousSetOfIntegers
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,10 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class DeBruijn
{
public class DeBruijn {
/**
*
* ToNum(solver, a, num, base)
@@ -31,53 +28,48 @@ public class DeBruijn
int len = a.Length;
IntVar[] tmp = new IntVar[len];
for(int i = 0; i < len; i++) {
tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var();
for (int i = 0; i < len; i++) {
tmp[i] = (a[i] * (int) Math.Pow(bbase, (len - i - 1))).Var();
}
return tmp.Sum() == num;
return tmp.Sum() == num;
}
/**
*
* Implements "arbitrary" de Bruijn sequences.
* See http://www.hakank.org/or-tools/debruijn_binary.py
*
*/
private static void Solve(int bbase, int n, int m)
{
private static void Solve(int bbase, int n, int m) {
Solver solver = new Solver("DeBruijn");
// Ensure that the number of each digit in bin_code is
// the same. Nice feature, but it can slow things down...
bool check_same_gcc = false; // true;
bool check_same_gcc = false; // true;
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(m, 0, (int)Math.Pow(bbase, n) - 1, "x");
IntVar[,] binary = solver.MakeIntVarMatrix(m, n, 0, bbase - 1, "binary");
IntVar[] x =
solver.MakeIntVarArray(m, 0, (int) Math.Pow(bbase, n) - 1, "x");
IntVar[, ] binary = solver.MakeIntVarMatrix(m, n, 0, bbase - 1, "binary");
// this is the de Bruijn sequence
IntVar[] bin_code =
solver.MakeIntVarArray(m, 0, bbase - 1, "bin_code");
IntVar[] bin_code = solver.MakeIntVarArray(m, 0, bbase - 1, "bin_code");
// occurences of each number in bin_code
IntVar[] gcc = solver.MakeIntVarArray(bbase, 0, m, "gcc");
// for the branching
IntVar[] all = new IntVar[2 * m + bbase];
for(int i = 0; i < m; i++) {
for (int i = 0; i < m; i++) {
all[i] = x[i];
all[m + i] = bin_code[i];
}
for(int i = 0; i < bbase; i++) {
for (int i = 0; i < bbase; i++) {
all[2 * m + i] = gcc[i];
}
//
// Constraints
//
@@ -85,10 +77,10 @@ public class DeBruijn
solver.Add(x.AllDifferent());
// converts x <-> binary
for(int i = 0; i < m; i++) {
for (int i = 0; i < m; i++) {
IntVar[] t = new IntVar[n];
for(int j = 0; j < n; j++) {
t[j] = binary[i,j];
for (int j = 0; j < n; j++) {
t[j] = binary[i, j];
}
solver.Add(ToNum(t, x[i], bbase));
}
@@ -96,30 +88,28 @@ public class DeBruijn
// the de Bruijn condition:
// the first elements in binary[i] is the same as the last
// elements in binary[i-1]
for(int i = 1; i < m; i++) {
for(int j = 1; j < n; j++) {
solver.Add(binary[i - 1,j] == binary[i,j - 1]);
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
solver.Add(binary[i - 1, j] == binary[i, j - 1]);
}
}
// ... and around the corner
for(int j = 1; j < n; j++) {
solver.Add(binary[m - 1,j] == binary[0,j - 1]);
for (int j = 1; j < n; j++) {
solver.Add(binary[m - 1, j] == binary[0, j - 1]);
}
// converts binary -> bin_code (de Bruijn sequence)
for(int i = 0; i < m; i++) {
solver.Add(bin_code[i] == binary[i,0]);
for (int i = 0; i < m; i++) {
solver.Add(bin_code[i] == binary[i, 0]);
}
// extra: ensure that all the numbers in the de Bruijn sequence
// (bin_code) has the same occurrences (if check_same_gcc is True
// and mathematically possible)
solver.Add(bin_code.Distribute(gcc));
if (check_same_gcc && m % bbase == 0) {
for(int i = 1; i < bbase; i++) {
for (int i = 1; i < bbase; i++) {
solver.Add(gcc[i] == gcc[i - 1]);
}
}
@@ -128,34 +118,37 @@ public class DeBruijn
// the minimum value of x should be first
// solver.Add(x[0] == x.Min());
//
// Search
//
DecisionBuilder db = solver.MakePhase(all,
Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db = solver.MakePhase(
all, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x: ");
for(int i = 0; i < m; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < m; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.Write("\nde Bruijn sequence:");
for(int i = 0; i < m; i++) {
Console.Write(bin_code[i].Value() + " ");
for (int i = 0; i < m; i++) {
Console.Write(bin_code [i]
.Value() +
" ");
}
Console.Write("\ngcc: ");
for(int i = 0; i < bbase; i++) {
Console.Write(gcc[i].Value() + " ");
for (int i = 0; i < bbase; i++) {
Console.Write(gcc [i]
.Value() +
" ");
}
Console.WriteLine("\n");
// for debugging etc: show the full binary table
/*
Console.Write("binary:");
@@ -167,7 +160,6 @@ public class DeBruijn
}
Console.WriteLine();
*/
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -176,14 +168,12 @@ public class DeBruijn
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int bbase = 2;
int n = 3;
int m = 8;
int n = 3;
int m = 8;
if (args.Length > 0) {
bbase = Convert.ToInt32(args[0]);

View File

@@ -20,31 +20,28 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class DiscreteTomography
{
public class DiscreteTomography {
// default problem
static int[] default_rowsums = {0,0,8,2,6,4,5,3,7,0,0};
static int[] default_colsums = {0,0,7,1,6,3,4,5,2,7,0,0};
static int[] default_rowsums = {0, 0, 8, 2, 6, 4, 5, 3, 7, 0, 0};
static int[] default_colsums = {0, 0, 7, 1, 6, 3, 4, 5, 2, 7, 0, 0};
static int[] rowsums2;
static int[] colsums2;
/**
*
* Discrete tomography
*
*
* Problem from http://eclipse.crosscoreop.com/examples/tomo.ecl.txt
* """
* This is a little 'tomography' problem, taken from an old issue
* of Scientific American.
*
*
* A matrix which contains zeroes and ones gets "x-rayed" vertically and
* horizontally, giving the total number of ones in each row and column.
* The problem is to reconstruct the contents of the matrix from this
* information. Sample run:
*
*
* ?- go.
* 0 0 7 1 6 3 4 5 2 7 0 0
* 0
@@ -65,9 +62,7 @@ public class DiscreteTomography
* See http://www.hakank.org/or-tools/discrete_tomography.py
*
*/
private static void Solve(int[] rowsums, int[] colsums)
{
private static void Solve(int[] rowsums, int[] colsums) {
Solver solver = new Solver("DiscreteTomography");
//
@@ -77,54 +72,52 @@ public class DiscreteTomography
int c = colsums.Length;
Console.Write("rowsums: ");
for(int i = 0; i < r; i++) {
for (int i = 0; i < r; i++) {
Console.Write(rowsums[i] + " ");
}
Console.Write("\ncolsums: ");
for(int j = 0; j < c; j++) {
for (int j = 0; j < c; j++) {
Console.Write(colsums[j] + " ");
}
Console.WriteLine("\n");
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(r, c, 0, 1, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(r, c, 0, 1, "x");
IntVar[] x_flat = x.Flatten();
//
// Constraints
//
// row sums
for(int i = 0; i < r; i++) {
var tmp = from j in Enumerable.Range(0, c) select x[i,j];
for (int i = 0; i < r; i++) {
var tmp = from j in Enumerable.Range(0, c) select x[i, j];
solver.Add(tmp.ToArray().Sum() == rowsums[i]);
}
// cols sums
for(int j = 0; j < c; j++) {
var tmp = from i in Enumerable.Range(0, r) select x[i,j];
for (int j = 0; j < c; j++) {
var tmp = from i in Enumerable.Range(0, r) select x[i, j];
solver.Add(tmp.ToArray().Sum() == colsums[j]);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
Console.Write("{0} ", x[i,j].Value() == 1 ? "#" : "." );
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
Console.Write("{0} ", x [i, j]
.Value() == 1
? "#"
: ".");
}
Console.WriteLine();
}
@@ -137,10 +130,8 @@ public class DiscreteTomography
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
/**
*
* Reads a discrete tomography file.
@@ -149,7 +140,7 @@ public class DiscreteTomography
* % a comment which also is ignored
* rowsums separated by [,\s]
* colsums separated by [,\s]
*
*
* e.g.
* """
* 0,0,8,2,6,4,5,3,7,0,0
@@ -160,17 +151,16 @@ public class DiscreteTomography
*
*/
private static void readFile(String file) {
Console.WriteLine("readFile(" + file + ")");
TextReader inr = new StreamReader(file);
String str;
int lineCount = 0;
while ((str = inr.ReadLine()) != null && str.Length > 0) {
while ((str = inr.ReadLine()) != null && str.Length > 0) {
str = str.Trim();
// ignore comments
if(str.StartsWith("#") || str.StartsWith("%")) {
if (str.StartsWith("#") || str.StartsWith("%")) {
continue;
}
@@ -180,37 +170,32 @@ public class DiscreteTomography
colsums2 = ConvLine(str);
break;
}
lineCount++;
} // end while
inr.Close();
} // end readFile
lineCount++;
} // end while
inr.Close();
} // end readFile
private static int[] ConvLine(String str) {
String[] tmp = Regex.Split(str, "[,\\s]+");
int len = tmp.Length;
int[] sums = new int[len];
for(int i = 0; i < len; i++) {
for (int i = 0; i < len; i++) {
sums[i] = Convert.ToInt32(tmp[i]);
}
return sums;
return sums;
}
public static void Main(String[] args)
{
if(args.Length > 0) {
public static void Main(String[] args) {
if (args.Length > 0) {
readFile(args[0]);
Solve(rowsums2, colsums2);
} else {
Solve(default_rowsums, default_colsums);
}
}
}

View File

@@ -19,10 +19,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class DivisibleBy9Through1
{
public class DivisibleBy9Through1 {
/**
*
* A simple propagator for modulo constraint.
@@ -35,13 +32,12 @@ public class DivisibleBy9Through1
*
*/
public static void MyMod(Solver solver, IntVar x, IntVar y, IntVar r) {
long lbx = x.Min();
long ubx = x.Max();
long ubx_neg = -ubx;
long lbx_neg = -lbx;
int min_x = (int)Math.Min(lbx, ubx_neg);
int max_x = (int)Math.Max(ubx, lbx_neg);
int min_x = (int) Math.Min(lbx, ubx_neg);
int max_x = (int) Math.Max(ubx, lbx_neg);
IntVar d = solver.MakeIntVar(min_x, max_x, "d");
@@ -49,7 +45,7 @@ public class DivisibleBy9Through1
solver.Add(r >= 0);
// x*r >= 0
solver.Add( x*r >= 0);
solver.Add(x * r >= 0);
// -abs(y) < r
solver.Add(-y.Abs() < r);
@@ -64,11 +60,9 @@ public class DivisibleBy9Through1
solver.Add(d <= max_x);
// x == y*d+r
solver.Add(x - (y*d + r) == 0);
solver.Add(x - (y * d + r) == 0);
}
/**
*
* ToNum(solver, a, num, base)
@@ -80,10 +74,10 @@ public class DivisibleBy9Through1
int len = a.Length;
IntVar[] tmp = new IntVar[len];
for(int i = 0; i < len; i++) {
tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var();
for (int i = 0; i < len; i++) {
tmp[i] = (a[i] * (int) Math.Pow(bbase, (len - i - 1))).Var();
}
return tmp.Sum() == num;
return tmp.Sum() == num;
}
/**
@@ -92,16 +86,14 @@ public class DivisibleBy9Through1
* See http://www.hakank.org/google_or_tools/divisible_by_9_through_1.py
*
*/
private static void Solve(int bbase)
{
private static void Solve(int bbase) {
Solver solver = new Solver("DivisibleBy9Through1");
int m = (int)Math.Pow(bbase,(bbase-1)) - 1;
int m = (int) Math.Pow(bbase, (bbase - 1)) - 1;
int n = bbase - 1;
String[] digits_str = {"_","0","1","2","3","4","5","6","7","8","9"};
String[] digits_str = {"_", "0", "1", "2", "3", "4",
"5", "6", "7", "8", "9"};
Console.WriteLine("base: " + bbase);
@@ -114,54 +106,58 @@ public class DivisibleBy9Through1
// the numbers. t[0] contains the answe
IntVar[] t = solver.MakeIntVarArray(n, 0, m, "t");
//
// Constraints
//
solver.Add(x.AllDifferent());
solver.Add(x.AllDifferent());
// Ensure the divisibility of base .. 1
IntVar zero = solver.MakeIntConst(0);
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
int mm = bbase - i - 1;
IntVar[] tt = new IntVar[mm];
for(int j = 0; j < mm; j++) {
for (int j = 0; j < mm; j++) {
tt[j] = x[j];
}
solver.Add(ToNum(tt, t[i], bbase));
MyMod(solver, t[i], solver.MakeIntConst(mm), zero);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x: ");
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine("\nt: ");
for(int i = 0; i < n; i++) {
Console.Write(t[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(t [i]
.Value() +
" ");
}
Console.WriteLine("\n");
if (bbase != 10) {
Console.Write("Number base 10: " + t[0].Value());
Console.Write("Number base 10: " + t [0]
.Value());
Console.Write(" Base " + bbase + ": ");
for(int i = 0; i < n; i++) {
Console.Write(digits_str[(int)x[i].Value() + 1]);
for (int i = 0; i < n; i++) {
Console.Write(digits_str [(int) x [i]
.Value() +
1]
);
}
Console.WriteLine("\n");
}
}
@@ -171,18 +167,16 @@ public class DivisibleBy9Through1
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int bbase = 10;
if (args.Length > 0) {
bbase = Convert.ToInt32(args[0]);
if (bbase > 12) {
// Though base = 12 has no solution...
Console.WriteLine("Sorry, max relevant base is 12. Setting base to 12.");
Console.WriteLine(
"Sorry, max relevant base is 12. Setting base to 12.");
bbase = 10;
}
}

View File

@@ -20,21 +20,17 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class DudeneyNumbers
{
public class DudeneyNumbers {
private static Constraint ToNum(IntVar[] a, IntVar num, int bbase) {
int len = a.Length;
IntVar[] tmp = new IntVar[len];
for(int i = 0; i < len; i++) {
tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var();
for (int i = 0; i < len; i++) {
tmp[i] = (a[i] * (int) Math.Pow(bbase, (len - i - 1))).Var();
}
return tmp.Sum() == num;
return tmp.Sum() == num;
}
/**
*
* Dudeney numbers
@@ -43,12 +39,12 @@ public class DudeneyNumbers
* http://cp-is-fun.blogspot.com/2010/09/test-python.html
* """
* I discovered yesterday Dudeney Numbers
* A Dudeney Numbers is a positive integer that is a perfect cube such that the sum
* of its decimal digits is equal to the cube root of the number. There are only six
* Dudeney Numbers and those are very easy to find with CP.
* I made my first experience with google cp solver so find these numbers (model below)
* and must say that I found it very convenient to build CP models in python!
* When you take a close look at the line:
* A Dudeney Numbers is a positive integer that is a perfect cube such that
* the sum of its decimal digits is equal to the cube root of the number.
* There are only six Dudeney Numbers and those are very easy to find with CP.
* I made my first experience with google cp solver so find these numbers
* (model below) and must say that I found it very convenient to build CP
* models in python! When you take a close look at the line:
* solver.Add(sum([10**(n-i-1)*x[i] for i in range(n)]) == nb)
* It is difficult to argue that it is very far from dedicated
* optimization languages!
@@ -57,9 +53,7 @@ public class DudeneyNumbers
* Also see: http://en.wikipedia.org/wiki/Dudeney_number
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("DudeneyNumbers");
//
@@ -71,30 +65,29 @@ public class DudeneyNumbers
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 0, 9, "x");
IntVar nb = solver.MakeIntVar(3, (int)Math.Pow(10,n), "nb");
IntVar s = solver.MakeIntVar(1,9*n+1,"s");
IntVar nb = solver.MakeIntVar(3, (int) Math.Pow(10, n), "nb");
IntVar s = solver.MakeIntVar(1, 9 * n + 1, "s");
//
// Constraints
//
solver.Add(nb == s*s*s);
solver.Add(nb == s * s * s);
solver.Add(x.Sum() == s);
// solver.Add(ToNum(x, nb, 10));
// alternative
solver.Add((from i in Enumerable.Range(0, n)
select (x[i]*(int)Math.Pow(10,n-i-1)).Var()).
ToArray().Sum() == nb);
solver.Add((from i in Enumerable
.Range(0, n) select(x[i] * (int) Math.Pow(10, n - i - 1))
.Var())
.ToArray()
.Sum() == nb);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
@@ -108,15 +101,7 @@ public class DudeneyNumbers
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,8 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class EinavPuzzle2
{
public class EinavPuzzle2 {
/**
*
* A programming puzzle from Einav.
@@ -60,15 +59,14 @@ public class EinavPuzzle2
* """
*
* Note:
* This is a port of Larent Perrons's Python version of my own einav_puzzle.py.
* He removed some of the decision variables and made it more efficient.
* Thanks!
* This is a port of Larent Perrons's Python version of my own
* einav_puzzle.py. He removed some of the decision variables and made it more
* efficient. Thanks!
*
* Also see http://www.hakank.org/or-tools/einav_puzzle2.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("EinavPuzzle2");
//
@@ -84,40 +82,36 @@ public class EinavPuzzle2
// {-17, -12, -14}
// };
// Full problem
int rows = 27;
int cols = 9;
int[,] data = {
{33,30,10,-6,18,-7,-11,23,-6},
{16,-19,9,-26,-8,-19,-8,-21,-14},
{17,12,-14,31,-30,13,-13,19,16},
{-6,-11,1,17,-12,-4,-7,14,-21},
{18,-31,34,-22,17,-19,20,24,6},
{33,-18,17,-15,31,-5,3,27,-3},
{-18,-20,-18,31,6,4,-2,-12,24},
{27,14,4,-29,-3,5,-29,8,-12},
{-15,-7,-23,23,-9,-8,6,8,-12},
{33,-23,-19,-4,-8,-7,11,-12,31},
{-20,19,-15,-30,11,32,7,14,-5},
{-23,18,-32,-2,-31,-7,8,24,16},
{32,-4,-10,-14,-6,-1,0,23,23},
{25,0,-23,22,12,28,-27,15,4},
{-30,-13,-16,-3,-3,-32,-3,27,-31},
{22,1,26,4,-2,-13,26,17,14},
{-9,-18,3,-20,-27,-32,-11,27,13},
{-17,33,-7,19,-32,13,-31,-2,-24},
{-31,27,-31,-29,15,2,29,-15,33},
{-18,-23,15,28,0,30,-4,12,-32},
{-3,34,27,-25,-18,26,1,34,26},
{-21,-31,-10,-13,-30,-17,-12,-26,31},
{23,-31,-19,21,-17,-10,2,-23,23},
{-3,6,0,-3,-32,0,-10,-25,14},
{-19,9,14,-27,20,15,-5,-27,18},
{11,-6,24,7,-17,26,20,-31,-25},
{-25,4,-16,30,33,23,-4,-4,23}
};
int[, ] data = {{33, 30, 10, -6, 18, -7, -11, 23, -6},
{16, -19, 9, -26, -8, -19, -8, -21, -14},
{17, 12, -14, 31, -30, 13, -13, 19, 16},
{-6, -11, 1, 17, -12, -4, -7, 14, -21},
{18, -31, 34, -22, 17, -19, 20, 24, 6},
{33, -18, 17, -15, 31, -5, 3, 27, -3},
{-18, -20, -18, 31, 6, 4, -2, -12, 24},
{27, 14, 4, -29, -3, 5, -29, 8, -12},
{-15, -7, -23, 23, -9, -8, 6, 8, -12},
{33, -23, -19, -4, -8, -7, 11, -12, 31},
{-20, 19, -15, -30, 11, 32, 7, 14, -5},
{-23, 18, -32, -2, -31, -7, 8, 24, 16},
{32, -4, -10, -14, -6, -1, 0, 23, 23},
{25, 0, -23, 22, 12, 28, -27, 15, 4},
{-30, -13, -16, -3, -3, -32, -3, 27, -31},
{22, 1, 26, 4, -2, -13, 26, 17, 14},
{-9, -18, 3, -20, -27, -32, -11, 27, 13},
{-17, 33, -7, 19, -32, 13, -31, -2, -24},
{-31, 27, -31, -29, 15, 2, 29, -15, 33},
{-18, -23, 15, 28, 0, 30, -4, 12, -32},
{-3, 34, 27, -25, -18, 26, 1, 34, 26},
{-21, -31, -10, -13, -30, -17, -12, -26, 31},
{23, -31, -19, 21, -17, -10, 2, -23, 23},
{-3, 6, 0, -3, -32, 0, -10, -25, 14},
{-19, 9, 14, -27, 20, 15, -5, -27, 18},
{11, -6, 24, 7, -17, 26, 20, -31, -25},
{-25, 4, -16, 30, 33, 23, -4, -4, 23}};
IEnumerable<int> ROWS = Enumerable.Range(0, rows);
IEnumerable<int> COLS = Enumerable.Range(0, cols);
@@ -125,15 +119,15 @@ public class EinavPuzzle2
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(rows, cols, -100, 100, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(rows, cols, -100, 100, "x");
IntVar[] x_flat = x.Flatten();
int[] signs_domain = {-1,1};
int[] signs_domain = {-1, 1};
// This don't work at the moment...
IntVar[] row_signs = solver.MakeIntVarArray(rows, signs_domain, "row_signs");
IntVar[] col_signs = solver.MakeIntVarArray(cols, signs_domain, "col_signs");
IntVar[] row_signs =
solver.MakeIntVarArray(rows, signs_domain, "row_signs");
IntVar[] col_signs =
solver.MakeIntVarArray(cols, signs_domain, "col_signs");
// To optimize
IntVar total_sum = x_flat.Sum().VarWithName("total_sum");
@@ -141,39 +135,41 @@ public class EinavPuzzle2
//
// Constraints
//
foreach(int i in ROWS) {
foreach(int j in COLS) {
solver.Add(x[i,j] == data[i,j] * row_signs[i] * col_signs[j]);
foreach (int i in ROWS) {
foreach (int j in COLS) {
solver.Add(x[i, j] == data[i, j] * row_signs[i] * col_signs[j]);
}
}
// row sums
IntVar[] row_sums = (from i in ROWS
select (from j in COLS
select x[i,j]
).ToArray().Sum().Var()).ToArray();
IntVar[] row_sums = (from i in ROWS select(from j in COLS select x[i, j])
.ToArray()
.Sum()
.Var())
.ToArray();
foreach(int i in ROWS) {
row_sums[i].SetMin(0);
foreach (int i in ROWS) {
row_sums [i]
.SetMin(0);
}
// col sums
IntVar[] col_sums = (from j in COLS
select (from i in ROWS
select x[i,j]
).ToArray().Sum().Var()).ToArray();
IntVar[] col_sums = (from j in COLS select(from i in ROWS select x[i, j])
.ToArray()
.Sum()
.Var())
.ToArray();
foreach(int j in COLS) {
col_sums[j].SetMin(0);
foreach (int j in COLS) {
col_sums [j]
.SetMin(0);
}
//
// Objective
//
OptimizeVar obj = total_sum.Minimize(1);
//
// Search
//
@@ -184,28 +180,37 @@ public class EinavPuzzle2
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("Sum: {0}",total_sum.Value());
Console.WriteLine("Sum: {0}", total_sum.Value());
Console.Write("row_sums: ");
foreach(int i in ROWS) {
Console.Write(row_sums[i].Value() + " ");
foreach (int i in ROWS) {
Console.Write(row_sums [i]
.Value() +
" ");
}
Console.Write("\nrow_signs: ");
foreach(int i in ROWS) {
Console.Write(row_signs[i].Value() + " ");
foreach (int i in ROWS) {
Console.Write(row_signs [i]
.Value() +
" ");
}
Console.Write("\ncol_sums: ");
foreach(int j in COLS) {
Console.Write(col_sums[j].Value() + " ");
foreach (int j in COLS) {
Console.Write(col_sums [j]
.Value() +
" ");
}
Console.Write("\ncol_signs: ");
foreach(int j in COLS) {
Console.Write(col_signs[j].Value() + " ");
foreach (int j in COLS) {
Console.Write(col_signs [j]
.Value() +
" ");
}
Console.WriteLine("\n");
foreach(int i in ROWS) {
foreach(int j in COLS) {
Console.Write("{0,3} ", x[i,j].Value());
foreach (int i in ROWS) {
foreach (int j in COLS) {
Console.Write("{0,3} ", x [i, j]
.Value());
}
Console.WriteLine();
}
@@ -218,11 +223,7 @@ public class EinavPuzzle2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,8 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Eq10
{
public class Eq10 {
/**
*
* Eq 10 in Google CP Solver.
@@ -27,8 +26,7 @@ public class Eq10
* Also see http://hakank.org/or-tools/eq10.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Eq10");
int n = 7;
@@ -44,54 +42,59 @@ public class Eq10
IntVar X6 = solver.MakeIntVar(0, 10, "X6");
IntVar X7 = solver.MakeIntVar(0, 10, "X7");
IntVar[] X = {X1,X2,X3,X4,X5,X6,X7};
IntVar[] X = {X1, X2, X3, X4, X5, X6, X7};
//
// Constraints
//
solver.Add(0+98527*X1+34588*X2+5872*X3+59422*X5+65159*X7
== 1547604+30704*X4+29649*X6);
solver.Add(0 + 98527 * X1 + 34588 * X2 + 5872 * X3 + 59422 * X5 +
65159 * X7 ==
1547604 + 30704 * X4 + 29649 * X6);
solver.Add(0+98957*X2+83634*X3+69966*X4+62038*X5+37164*X6+85413*X7
== 1823553+93989*X1);
solver.Add(0 + 98957 * X2 + 83634 * X3 + 69966 * X4 + 62038 * X5 +
37164 * X6 + 85413 * X7 ==
1823553 + 93989 * X1);
solver.Add(900032+10949*X1+77761*X2+67052*X5
== 0+80197*X3+61944*X4+92964*X6+44550*X7);
solver.Add(900032 + 10949 * X1 + 77761 * X2 + 67052 * X5 ==
0 + 80197 * X3 + 61944 * X4 + 92964 * X6 + 44550 * X7);
solver.Add(0+73947*X1+84391*X3+81310*X5
== 1164380+96253*X2+44247*X4+70582*X6+33054*X7);
solver.Add(0 + 73947 * X1 + 84391 * X3 + 81310 * X5 ==
1164380 + 96253 * X2 + 44247 * X4 + 70582 * X6 + 33054 * X7);
solver.Add(0+13057*X3+42253*X4+77527*X5+96552*X7
== 1185471+60152*X1+21103*X2+97932*X6);
solver.Add(0 + 13057 * X3 + 42253 * X4 + 77527 * X5 + 96552 * X7 ==
1185471 + 60152 * X1 + 21103 * X2 + 97932 * X6);
solver.Add(1394152+66920*X1+55679*X4
== 0+64234*X2+65337*X3+45581*X5+67707*X6+98038*X7);
solver.Add(1394152 + 66920 * X1 + 55679 * X4 ==
0 + 64234 * X2 + 65337 * X3 + 45581 * X5 + 67707 * X6 +
98038 * X7);
solver.Add(0+68550*X1+27886*X2+31716*X3+73597*X4+38835*X7
== 279091+88963*X5+76391*X6);
solver.Add(0 + 68550 * X1 + 27886 * X2 + 31716 * X3 + 73597 * X4 +
38835 * X7 ==
279091 + 88963 * X5 + 76391 * X6);
solver.Add(0+76132*X2+71860*X3+22770*X4+68211*X5+78587*X6
== 480923+48224*X1+82817*X7);
solver.Add(0 + 76132 * X2 + 71860 * X3 + 22770 * X4 + 68211 * X5 +
78587 * X6 ==
480923 + 48224 * X1 + 82817 * X7);
solver.Add(519878+94198*X2+87234*X3+37498*X4
== 0+71583*X1+25728*X5+25495*X6+70023*X7);
solver.Add(519878 + 94198 * X2 + 87234 * X3 + 37498 * X4 ==
0 + 71583 * X1 + 25728 * X5 + 25495 * X6 + 70023 * X7);
solver.Add(361921+78693*X1+38592*X5+38478*X6
== 0+94129*X2+43188*X3+82528*X4+69025*X7);
solver.Add(361921 + 78693 * X1 + 38592 * X5 + 38478 * X6 ==
0 + 94129 * X2 + 43188 * X3 + 82528 * X4 + 69025 * X7);
//
// Search
//
DecisionBuilder db = solver.MakePhase(X,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(X, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
Console.Write(X[i].ToString() + " ");
for (int i = 0; i < n; i++) {
Console.Write(X [i]
.ToString() +
" ");
}
Console.WriteLine();
}
@@ -102,11 +105,7 @@ public class Eq10
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,8 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Eq20
{
public class Eq20 {
/**
*
* Eq 20 in Google CP Solver.
@@ -27,8 +26,7 @@ public class Eq20
* Also see http://hakank.org/or-tools/eq20.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Eq20");
int n = 7;
@@ -44,66 +42,85 @@ public class Eq20
IntVar X5 = solver.MakeIntVar(0, 10, "X5");
IntVar X6 = solver.MakeIntVar(0, 10, "X6");
IntVar[] X = {X0,X1,X2,X3,X4,X5,X6};
IntVar[] X = {X0, X1, X2, X3, X4, X5, X6};
//
// Constraints
//
solver.Add(-76706*X0 + 98205*X1 + 23445*X2 + 67921*X3 + 24111*X4 +
-48614*X5 + -41906*X6 == 821228);
solver.Add(87059*X0 + -29101*X1 + -5513*X2 + -21219*X3 + 22128*X4 +
7276*X5 + 57308*X6 == 22167);
solver.Add(-60113*X0 + 29475*X1 + 34421*X2 + -76870*X3 + 62646*X4 +
29278*X5 + -15212*X6 == 251591);
solver.Add(49149*X0 + 52871*X1 + -7132*X2 + 56728*X3 + -33576*X4 +
-49530*X5 + -62089*X6 == 146074);
solver.Add(-10343*X0 + 87758*X1 + -11782*X2 + 19346*X3 + 70072*X4 +
-36991*X5 + 44529*X6 == 740061);
solver.Add(85176*X0 + -95332*X1 + -1268*X2 + 57898*X3 + 15883*X4 +
50547*X5 + 83287*X6 == 373854);
solver.Add(-85698*X0 + 29958*X1 + 57308*X2 + 48789*X3 + -78219*X4 +
4657*X5 + 34539*X6 == 249912);
solver.Add(-67456*X0 + 84750*X1 + -51553*X2 + 21239*X3 + 81675*X4 +
-99395*X5 + -4254*X6 == 277271);
solver.Add(94016*X0 + -82071*X1 + 35961*X2 + 66597*X3 + -30705*X4 +
-44404*X5 + -38304*X6 == 25334);
solver.Add(-60301*X0 + 31227*X1 + 93951*X2 + 73889*X3 + 81526*X4 +
-72702*X5 + 68026*X6 == 1410723);
solver.Add(-16835*X0 + 47385*X1 + 97715*X2 + -12640*X3 + 69028*X4 +
76212*X5 + -81102*X6 == 1244857);
solver.Add(-43277*X0 + 43525*X1 + 92298*X2 + 58630*X3 + 92590*X4 +
-9372*X5 + -60227*X6 == 1503588);
solver.Add(-64919*X0 + 80460*X1 + 90840*X2 + -59624*X3 + -75542*X4 +
25145*X5 + -47935*X6 == 18465);
solver.Add(-45086*X0 + 51830*X1 + -4578*X2 + 96120*X3 + 21231*X4 +
97919*X5 + 65651*X6 == 1198280);
solver.Add(85268*X0 + 54180*X1 + -18810*X2 + -48219*X3 + 6013*X4 +
78169*X5 + -79785*X6 == 90614);
solver.Add(8874*X0 + -58412*X1 + 73947*X2 + 17147*X3 + 62335*X4 +
16005*X5 + 8632*X6 == 752447);
solver.Add(71202*X0 + -11119*X1 + 73017*X2 + -38875*X3 + -14413*X4 +
-29234*X5 + 72370*X6 == 129768);
solver.Add(1671*X0 + -34121*X1 + 10763*X2 + 80609*X3 + 42532*X4 +
93520*X5 + -33488*X6 == 915683);
solver.Add(51637*X0 + 67761*X1 + 95951*X2 + 3834*X3 + -96722*X4 +
59190*X5 + 15280*X6 == 533909);
solver.Add(-16105*X0 + 62397*X1 + -6704*X2 + 43340*X3 + 95100*X4 +
-68610*X5 + 58301*X6 == 876370);
solver.Add(-76706 * X0 + 98205 * X1 + 23445 * X2 + 67921 * X3 + 24111 * X4 +
-48614 * X5 + -41906 * X6 ==
821228);
solver.Add(87059 * X0 + -29101 * X1 + -5513 * X2 + -21219 * X3 +
22128 * X4 + 7276 * X5 + 57308 * X6 ==
22167);
solver.Add(-60113 * X0 + 29475 * X1 + 34421 * X2 + -76870 * X3 +
62646 * X4 + 29278 * X5 + -15212 * X6 ==
251591);
solver.Add(49149 * X0 + 52871 * X1 + -7132 * X2 + 56728 * X3 + -33576 * X4 +
-49530 * X5 + -62089 * X6 ==
146074);
solver.Add(-10343 * X0 + 87758 * X1 + -11782 * X2 + 19346 * X3 +
70072 * X4 + -36991 * X5 + 44529 * X6 ==
740061);
solver.Add(85176 * X0 + -95332 * X1 + -1268 * X2 + 57898 * X3 + 15883 * X4 +
50547 * X5 + 83287 * X6 ==
373854);
solver.Add(-85698 * X0 + 29958 * X1 + 57308 * X2 + 48789 * X3 +
-78219 * X4 + 4657 * X5 + 34539 * X6 ==
249912);
solver.Add(-67456 * X0 + 84750 * X1 + -51553 * X2 + 21239 * X3 +
81675 * X4 + -99395 * X5 + -4254 * X6 ==
277271);
solver.Add(94016 * X0 + -82071 * X1 + 35961 * X2 + 66597 * X3 +
-30705 * X4 + -44404 * X5 + -38304 * X6 ==
25334);
solver.Add(-60301 * X0 + 31227 * X1 + 93951 * X2 + 73889 * X3 + 81526 * X4 +
-72702 * X5 + 68026 * X6 ==
1410723);
solver.Add(-16835 * X0 + 47385 * X1 + 97715 * X2 + -12640 * X3 +
69028 * X4 + 76212 * X5 + -81102 * X6 ==
1244857);
solver.Add(-43277 * X0 + 43525 * X1 + 92298 * X2 + 58630 * X3 + 92590 * X4 +
-9372 * X5 + -60227 * X6 ==
1503588);
solver.Add(-64919 * X0 + 80460 * X1 + 90840 * X2 + -59624 * X3 +
-75542 * X4 + 25145 * X5 + -47935 * X6 ==
18465);
solver.Add(-45086 * X0 + 51830 * X1 + -4578 * X2 + 96120 * X3 + 21231 * X4 +
97919 * X5 + 65651 * X6 ==
1198280);
solver.Add(85268 * X0 + 54180 * X1 + -18810 * X2 + -48219 * X3 + 6013 * X4 +
78169 * X5 + -79785 * X6 ==
90614);
solver.Add(8874 * X0 + -58412 * X1 + 73947 * X2 + 17147 * X3 + 62335 * X4 +
16005 * X5 + 8632 * X6 ==
752447);
solver.Add(71202 * X0 + -11119 * X1 + 73017 * X2 + -38875 * X3 +
-14413 * X4 + -29234 * X5 + 72370 * X6 ==
129768);
solver.Add(1671 * X0 + -34121 * X1 + 10763 * X2 + 80609 * X3 + 42532 * X4 +
93520 * X5 + -33488 * X6 ==
915683);
solver.Add(51637 * X0 + 67761 * X1 + 95951 * X2 + 3834 * X3 + -96722 * X4 +
59190 * X5 + 15280 * X6 ==
533909);
solver.Add(-16105 * X0 + 62397 * X1 + -6704 * X2 + 43340 * X3 + 95100 * X4 +
-68610 * X5 + 58301 * X6 ==
876370);
//
// Search
//
DecisionBuilder db = solver.MakePhase(X,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(X, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
Console.Write(X[i].ToString() + " ");
for (int i = 0; i < n; i++) {
Console.Write(X [i]
.ToString() +
" ");
}
Console.WriteLine();
}
@@ -114,11 +131,7 @@ public class Eq20
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,10 +20,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class FillAPix
{
public class FillAPix {
static int X = -1;
//
@@ -33,27 +30,23 @@ public class FillAPix
//
static int default_n = 10;
static int[,] default_puzzle = {{X,X,X,X,X,X,X,X,0,X},
{X,8,8,X,2,X,0,X,X,X},
{5,X,8,X,X,X,X,X,X,X},
{X,X,X,X,X,2,X,X,X,2},
{1,X,X,X,4,5,6,X,X,X},
{X,0,X,X,X,7,9,X,X,6},
{X,X,X,6,X,X,9,X,X,6},
{X,X,6,6,8,7,8,7,X,5},
{X,4,X,6,6,6,X,6,X,4},
{X,X,X,X,X,X,3,X,X,X}};
static int[, ] default_puzzle = {
{X, X, X, X, X, X, X, X, 0, X}, {X, 8, 8, X, 2, X, 0, X, X, X},
{5, X, 8, X, X, X, X, X, X, X}, {X, X, X, X, X, 2, X, X, X, 2},
{1, X, X, X, 4, 5, 6, X, X, X}, {X, 0, X, X, X, 7, 9, X, X, 6},
{X, X, X, 6, X, X, 9, X, X, 6}, {X, X, 6, 6, 8, 7, 8, 7, X, 5},
{X, 4, X, 6, 6, 6, X, 6, X, 4}, {X, X, X, X, X, X, 3, X, X, X}};
// for the actual problem
static int n;
static int[,] puzzle;
static int[, ] puzzle;
/**
*
* Fill-a-Pix problem
*
* From http://www.conceptispuzzles.com/index.aspx?uri=puzzle/fill-a-pix/basiclogic
* From
* http://www.conceptispuzzles.com/index.aspx?uri=puzzle/fill-a-pix/basiclogic
* """
* Each puzzle consists of a grid containing clues in various places. The
* object is to reveal a hidden picture by painting the squares around each
@@ -76,8 +69,7 @@ public class FillAPix
*
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("FillAPix");
//
@@ -86,10 +78,10 @@ public class FillAPix
int[] S = {-1, 0, 1};
Console.WriteLine("Problem:");
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if (puzzle[i,j] > X) {
Console.Write(puzzle[i,j] + " ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (puzzle[i, j] > X) {
Console.Write(puzzle[i, j] + " ");
} else {
Console.Write("X ");
}
@@ -98,40 +90,31 @@ public class FillAPix
}
Console.WriteLine();
//
// Decision variables
//
IntVar[,] pict = solver.MakeIntVarMatrix(n, n, 0, 1, "pict");
IntVar[] pict_flat = pict.Flatten(); // for branching
IntVar[, ] pict = solver.MakeIntVarMatrix(n, n, 0, 1, "pict");
IntVar[] pict_flat = pict.Flatten(); // for branching
//
// Constraints
//
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if (puzzle[i,j] > X) {
//
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (puzzle[i, j] > X) {
// this cell is the sum of all surrounding cells
var tmp = from a in S from b in S where
i + a >= 0 &&
j + b >= 0 &&
i + a < n &&
j + b < n
select(pict[i+a,j+b]);
solver.Add(tmp.ToArray().Sum() == puzzle[i,j]);
var tmp = from a in S from b in S where i + a >= 0 && j + b >= 0 &&
i + a < n && j + b < n select(pict[i + a, j + b]);
solver.Add(tmp.ToArray().Sum() == puzzle[i, j]);
}
}
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(pict_flat,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(pict_flat, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
@@ -140,13 +123,16 @@ public class FillAPix
while (solver.NextSolution()) {
sol++;
Console.WriteLine("Solution #{0} ", sol + " ");
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++){
Console.Write(pict[i,j].Value() == 1 ? "#" : " ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write(pict [i, j]
.Value() == 1
? "#"
: " ");
}
Console.WriteLine();
}
Console.WriteLine();
}
@@ -156,10 +142,8 @@ public class FillAPix
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
/**
*
* Reads a Fill-a-Pix file.
@@ -170,9 +154,9 @@ public class FillAPix
* <
* row number of neighbours lines...
* >
*
*
* 0..8 means number of neighbours, "." mean unknown (may be a mine)
*
*
* Example (from fill_a_pix1.txt):
*
* 10
@@ -189,51 +173,45 @@ public class FillAPix
*
*/
private static void readFile(String file) {
Console.WriteLine("readFile(" + file + ")");
int lineCount = 0;
TextReader inr = new StreamReader(file);
String str;
while ((str = inr.ReadLine()) != null && str.Length > 0) {
str = str.Trim();
// ignore comments
if(str.StartsWith("#") || str.StartsWith("%")) {
if (str.StartsWith("#") || str.StartsWith("%")) {
continue;
}
Console.WriteLine(str);
if (lineCount == 0) {
n = Convert.ToInt32(str); // number of rows
puzzle = new int[n,n];
n = Convert.ToInt32(str); // number of rows
puzzle = new int[n, n];
} else {
// the problem matrix
String[] row = Regex.Split(str, "");
for(int j = 1; j <= n; j++) {
for (int j = 1; j <= n; j++) {
String s = row[j];
if (s.Equals(".")) {
puzzle[lineCount-1, j-1] = -1;
puzzle[lineCount - 1, j - 1] = -1;
} else {
puzzle[lineCount-1, j-1] = Convert.ToInt32(s);
puzzle[lineCount - 1, j - 1] = Convert.ToInt32(s);
}
}
}
lineCount++;
} // end while
} // end while
inr.Close();
} // end readFile
} // end readFile
public static void Main(String[] args)
{
public static void Main(String[] args) {
String file = "";
if (args.Length > 0) {
file = args[0];

View File

@@ -18,9 +18,7 @@ using System.Collections;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class FurnitureMoving
{
public class FurnitureMoving {
/*
* Decompositon of cumulative.
*
@@ -43,22 +41,21 @@ public class FurnitureMoving
*
*
*/
static void MyCumulative(Solver solver,
IntVar[] s,
int[] d,
int[] r,
static void MyCumulative(Solver solver, IntVar[] s, int[] d, int[] r,
IntVar b) {
int[] tasks = (from i in Enumerable.Range(0, s.Length)
where r[i] > 0 && d[i] > 0
select i).ToArray();
int times_min = tasks.Min(i => (int)s[i].Min());
int[] tasks = (from i in Enumerable.Range(0, s.Length) where r[i] > 0 &&
d[i] > 0 select i)
.ToArray();
int times_min = tasks.Min(i =>(int) s [i]
.Min());
int d_max = d.Max();
int times_max = tasks.Max(i => (int)s[i].Max() + d_max);
for(int t = times_min; t <= times_max; t++) {
int times_max = tasks.Max(i =>(int) s [i]
.Max() +
d_max);
for (int t = times_min; t <= times_max; t++) {
ArrayList bb = new ArrayList();
foreach(int i in tasks) {
bb.Add(((s[i] <= t) * (s[i] + d[i]> t) * r[i]).Var());
foreach (int i in tasks) {
bb.Add(((s[i] <= t) * (s[i] + d[i] > t) * r[i]).Var());
}
solver.Add((bb.ToArray(typeof(IntVar)) as IntVar[]).Sum() <= b);
}
@@ -68,9 +65,7 @@ public class FurnitureMoving
if (b is IntVar) {
solver.Add(b <= r.Sum());
}
}
}
/**
*
@@ -84,38 +79,36 @@ public class FurnitureMoving
* Also see http://www.hakank.org/or-tools/furniture_moving.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("FurnitureMoving");
int n = 4;
int[] duration = {30,10,15,15};
int[] demand = { 3, 1, 3, 2};
int[] duration = {30, 10, 15, 15};
int[] demand = {3, 1, 3, 2};
int upper_limit = 160;
//
// Decision variables
//
IntVar[] start_times = solver.MakeIntVarArray(n, 0, upper_limit, "start_times");
IntVar[] end_times = solver.MakeIntVarArray(n, 0, upper_limit * 2, "end_times");
IntVar[] start_times =
solver.MakeIntVarArray(n, 0, upper_limit, "start_times");
IntVar[] end_times =
solver.MakeIntVarArray(n, 0, upper_limit * 2, "end_times");
IntVar end_time = solver.MakeIntVar(0, upper_limit * 2, "end_time");
// number of needed resources, to be minimized or constrained
IntVar num_resources = solver.MakeIntVar(0, 10, "num_resources");
IntVar num_resources = solver.MakeIntVar(0, 10, "num_resources");
//
// Constraints
//
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
solver.Add(end_times[i] == start_times[i] + duration[i]);
}
solver.Add(end_time == end_times.Max());
MyCumulative(solver, start_times, duration, demand, num_resources);
//
// Some extra constraints to play with
//
@@ -128,12 +121,10 @@ public class FurnitureMoving
// solver.Add(start_times[i] == 0);
// }
// limitation of the number of people
// solver.Add(num_resources <= 3);
solver.Add(num_resources <= 4);
//
// Objective
//
@@ -144,21 +135,22 @@ public class FurnitureMoving
//
// Search
//
DecisionBuilder db = solver.MakePhase(start_times,
Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db = solver.MakePhase(
start_times, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("num_resources: {0} end_time: {1}",
num_resources.Value(), end_time.Value());
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
Console.WriteLine("Task {0,1}: {1,2} -> {2,2} -> {3,2} (demand: {4})",
i,
start_times[i].Value(),
start_times [i]
.Value(),
duration[i],
end_times[i].Value(),
end_times [i]
.Value(),
demand[i]);
}
Console.WriteLine();
@@ -170,11 +162,7 @@ public class FurnitureMoving
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,8 +16,7 @@ using System.Collections;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class FurnitureMovingIntervals
{
public class FurnitureMovingIntervals {
/**
*
* Moving furnitures (scheduling) problem in Google CP Solver.
@@ -27,12 +26,11 @@ public class FurnitureMovingIntervals
* Also see http://www.hakank.org/or-tools/furniture_moving.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("FurnitureMovingIntervals");
const int n = 4;
int[] durations = {30,10,15,15};
int[] durations = {30, 10, 15, 15};
int[] demand = {3, 1, 3, 2};
const int upper_limit = 160;
const int max_num_workers = 5;
@@ -41,40 +39,34 @@ public class FurnitureMovingIntervals
// Decision variables
//
IntervalVar[] tasks = new IntervalVar[n];
for (int i = 0; i < n; ++i)
{
tasks[i] = solver.MakeFixedDurationIntervalVar(0,
upper_limit - durations[i],
durations[i],
false,
"task_" + i);
for (int i = 0; i < n; ++i) {
tasks[i] = solver.MakeFixedDurationIntervalVar(
0, upper_limit - durations[i], durations[i], false, "task_" + i);
}
// Fillers that span the whole resource and limit the available
// number of workers.
IntervalVar[] fillers = new IntervalVar[max_num_workers];
for (int i = 0; i < max_num_workers; ++i)
{
fillers[i] = solver.MakeFixedDurationIntervalVar(0,
0,
upper_limit,
true,
for (int i = 0; i < max_num_workers; ++i) {
fillers[i] = solver.MakeFixedDurationIntervalVar(0, 0, upper_limit, true,
"filler_" + i);
}
// Number of needed resources, to be minimized or constrained.
IntVar num_workers = solver.MakeIntVar(0, max_num_workers, "num_workers");
IntVar num_workers = solver.MakeIntVar(0, max_num_workers, "num_workers");
// Links fillers and num_workers.
for (int i = 0; i < max_num_workers; ++i)
{
solver.Add((num_workers > i) + fillers[i].PerformedExpr() == 1);
for (int i = 0; i < max_num_workers; ++i) {
solver.Add((num_workers > i) + fillers [i]
.PerformedExpr() ==
1);
}
// Creates makespan.
IntVar[] ends = new IntVar[n];
for (int i = 0; i < n; ++i)
{
ends[i] = tasks[i].EndExpr().Var();
for (int i = 0; i < n; ++i) {
ends[i] = tasks [i]
.EndExpr()
.Var();
}
IntVar end_time = ends.Max().VarWithName("end_time");
@@ -83,13 +75,11 @@ public class FurnitureMovingIntervals
//
IntervalVar[] all_tasks = new IntervalVar[n + max_num_workers];
int[] all_demands = new int[n + max_num_workers];
for (int i = 0; i < n; ++i)
{
for (int i = 0; i < n; ++i) {
all_tasks[i] = tasks[i];
all_demands[i] = demand[i];
}
for (int i = 0; i < max_num_workers; ++i)
{
for (int i = 0; i < max_num_workers; ++i) {
all_tasks[i + n] = fillers[i];
all_demands[i + n] = 1;
}
@@ -107,7 +97,6 @@ public class FurnitureMovingIntervals
// solver.Add(tasks[i].StartAt(0));
// }
// limitation of the number of people
// solver.Add(num_workers <= 3);
solver.Add(num_workers <= 4);
@@ -128,8 +117,11 @@ public class FurnitureMovingIntervals
while (solver.NextSolution()) {
Console.WriteLine(num_workers.ToString() + ", " + end_time.ToString());
for(int i = 0; i < n; i++) {
Console.WriteLine("{0} (demand:{1})", tasks[i].ToString(), demand[i]);
for (int i = 0; i < n; i++) {
Console.WriteLine("{0} (demand:{1})",
tasks [i]
.ToString(),
demand[i]);
}
Console.WriteLine();
}
@@ -140,11 +132,7 @@ public class FurnitureMovingIntervals
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,10 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class Futoshiki
{
public class Futoshiki {
/**
*
* Futoshiki problem.
@@ -41,9 +38,7 @@ public class Futoshiki
* Also see http://www.hakank.org/or-tools/futoshiki.py
*
*/
private static void Solve(int[,] values, int[,] lt)
{
private static void Solve(int[, ] values, int[, ] lt) {
Solver solver = new Solver("Futoshiki");
int size = values.GetLength(0);
@@ -53,61 +48,54 @@ public class Futoshiki
//
// Decision variables
//
IntVar[,] field = solver.MakeIntVarMatrix(size, size, 1, size, "field");
IntVar[, ] field = solver.MakeIntVarMatrix(size, size, 1, size, "field");
IntVar[] field_flat = field.Flatten();
//
// Constraints
//
// set initial values
foreach(int row in RANGE) {
foreach(int col in RANGE) {
if (values[row,col] > 0) {
solver.Add(field[row,col] == values[row,col]);
foreach (int row in RANGE) {
foreach (int col in RANGE) {
if (values[row, col] > 0) {
solver.Add(field[row, col] == values[row, col]);
}
}
}
// all rows have to be different
foreach(int row in RANGE) {
solver.Add((from col in RANGE
select field[row,col]).ToArray().AllDifferent());
foreach (int row in RANGE) {
solver.Add(
(from col in RANGE select field[row, col]).ToArray().AllDifferent());
}
// all columns have to be different
foreach(int col in RANGE) {
solver.Add((from row in RANGE
select field[row,col]).ToArray().AllDifferent());
foreach (int col in RANGE) {
solver.Add(
(from row in RANGE select field[row, col]).ToArray().AllDifferent());
}
// all < constraints are satisfied
// Also: make 0-based
foreach(int i in NUMQD) {
solver.Add(field[ lt[i,0]-1, lt[i,1]-1 ] <
field[ lt[i,2]-1, lt[i,3]-1 ] );
foreach (int i in NUMQD) {
solver.Add(field[lt[i, 0] - 1, lt[i, 1] - 1] <
field[lt[i, 2] - 1, lt[i, 3] - 1]);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(field_flat,
Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db = solver.MakePhase(
field_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
foreach(int i in RANGE) {
foreach(int j in RANGE) {
Console.Write("{0} ", field[i,j].Value());
foreach (int i in RANGE) {
foreach (int j in RANGE) {
Console.Write("{0} ", field [i, j]
.Value());
}
Console.WriteLine();
}
@@ -121,13 +109,9 @@ public class Futoshiki
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
//
// Example from Tailor model futoshiki.param/futoshiki.param
// Solution:
@@ -140,29 +124,17 @@ public class Futoshiki
// Futoshiki instance, by Andras Salamon
// specify the numbers in the grid
//
int[,] values1 = {
{0, 0, 3, 2, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}};
int[, ] values1 = {{0, 0, 3, 2, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}};
// [i1,j1, i2,j2] requires that values[i1,j1] < values[i2,j2]
// Note: 1-based
int [,] lt1 = {
{1,2, 1,1},
{1,4, 1,5},
{2,3, 1,3},
{3,3, 2,3},
{3,4, 2,4},
{2,5, 3,5},
{3,2, 4,2},
{4,4, 4,3},
{5,2, 5,1},
{5,4, 5,3},
{5,5, 4,5}};
int[, ] lt1 = {{1, 2, 1, 1}, {1, 4, 1, 5}, {2, 3, 1, 3}, {3, 3, 2, 3},
{3, 4, 2, 4}, {2, 5, 3, 5}, {3, 2, 4, 2}, {4, 4, 4, 3},
{5, 2, 5, 1}, {5, 4, 5, 3}, {5, 5, 4, 5}};
//
// Example from http://en.wikipedia.org/wiki/Futoshiki
@@ -173,28 +145,20 @@ public class Futoshiki
// 3 5 2 1 4
// 1 2 5 4 3
//
int[,] values2 = {
{0, 0, 0, 0, 0},
{4, 0, 0, 0, 2},
{0, 0, 4, 0, 0},
{0, 0, 0, 0, 4},
{0, 0, 0, 0, 0}};
int[, ] values2 = {{0, 0, 0, 0, 0},
{4, 0, 0, 0, 2},
{0, 0, 4, 0, 0},
{0, 0, 0, 0, 4},
{0, 0, 0, 0, 0}};
// Note: 1-based
int[,] lt2 = {
{1,2, 1,1},
{1,4, 1,3},
{1,5, 1,4},
{4,4, 4,5},
{5,1, 5,2},
{5,2, 5,3}
};
int[, ] lt2 = {{1, 2, 1, 1}, {1, 4, 1, 3}, {1, 5, 1, 4},
{4, 4, 4, 5}, {5, 1, 5, 2}, {5, 2, 5, 3}};
Console.WriteLine("Problem 1");
Solve(values1, lt1);
Console.WriteLine("\nProblem 2");
Solve(values2, lt2);
}
}

View File

@@ -19,10 +19,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class GolombRuler
{
public class GolombRuler {
/**
*
* Golomb Ruler problem.
@@ -32,35 +29,29 @@ public class GolombRuler
* http://code.google.com/p/or-tools/source/browse/trunk/com/google/ortools/constraintsolver/samples/GolombRuler.java
*
*/
private static void Solve(int m = 8)
{
private static void Solve(int m = 8) {
Solver solver = new Solver("GolombRuler");
//
// Decision variables
//
IntVar[] ticks = solver.MakeIntVarArray(m,
0,
((m < 31) ? (1 << (m + 1)) - 1 : 9999),
"ticks");
IntVar[] ticks = solver.MakeIntVarArray(
m, 0, ((m < 31) ? (1 << (m + 1)) - 1 : 9999), "ticks");
IntVar[] diff = new IntVar[(m * m - m) / 2];
//
// Constraints
//
solver.Add(ticks[0] == 0);
for(int i = 0; i < ticks.Length - 1; i++) {
solver.Add(ticks[i] < ticks[i+1]);
for (int i = 0; i < ticks.Length - 1; i++) {
solver.Add(ticks[i] < ticks[i + 1]);
}
for (int k = 0, i = 0; i < m - 1; i++) {
for (int j = i + 1; j < m; j++, k++) {
diff[k] = (ticks[j]-ticks[i]).Var();
diff[k] = (ticks[j] - ticks[i]).Var();
solver.Add(diff[k] >= (j - i) * (j - i + 1) / 2);
}
}
@@ -72,36 +63,33 @@ public class GolombRuler
solver.Add(diff[0] < diff[diff.Length - 1]);
}
//
// Optimization
//
OptimizeVar opt = ticks[m - 1].Minimize(1);
OptimizeVar opt = ticks [m - 1]
.Minimize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(ticks,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db = solver.MakePhase(
ticks, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE);
// We just want the debug info for larger instances.
if (m >= 11) {
SearchMonitor log = solver.MakeSearchLog(10000, opt);
solver.NewSearch(db, opt, log);
} else {
solver.NewSearch(db, opt);
}
while (solver.NextSolution()) {
Console.Write("opt: {0} [ ", ticks[m-1].Value());
for(int i = 0; i < m; i++) {
Console.Write("{0} ", ticks[i].Value());
Console.Write("opt: {0} [ ", ticks [m - 1]
.Value());
for (int i = 0; i < m; i++) {
Console.Write("{0} ", ticks [i]
.Value());
}
Console.WriteLine("]");
}
@@ -112,12 +100,9 @@ public class GolombRuler
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 8;
if (args.Length > 0) {
n = Convert.ToInt32(args[0]);

View File

@@ -16,13 +16,10 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Grocery
{
public class Grocery {
public static void Decreasing(Solver solver, IntVar[] x) {
for(int i = 0; i < x.Length - 1; i++) {
solver.Add(x[i] <= x[i+1]);
for (int i = 0; i < x.Length - 1; i++) {
solver.Add(x[i] <= x[i + 1]);
}
}
@@ -33,14 +30,13 @@ public class Grocery
int len = x.Length;
IntVar[] tmp = new IntVar[len];
tmp[0] = x[0];
for(int i = 1; i < len; i++) {
tmp[i] = (tmp[i-1]*x[i]).Var();
for (int i = 1; i < len; i++) {
tmp[i] = (tmp[i - 1] * x[i]).Var();
}
return tmp[len-1] == prod;
return tmp[len - 1] == prod;
}
/**
*
* Grocery problem.
@@ -57,8 +53,7 @@ public class Grocery
* """
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Grocery");
int n = 4;
@@ -76,8 +71,7 @@ public class Grocery
solver.Add(item.Sum() == c);
// solver.Add(item[0] * item[1] * item[2] * item[3] == c * 100*100*100);
// solver.Add(item.Prod() == c * 100*100*100);
solver.Add(MyProd(item, c * 100*100*100));
solver.Add(MyProd(item, c * 100 * 100 * 100));
// Symmetry breaking
Decreasing(solver, item);
@@ -85,14 +79,15 @@ public class Grocery
//
// Search
//
DecisionBuilder db = solver.MakePhase(item,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(item, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
Console.Write(item[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(item [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -102,11 +97,7 @@ public class Grocery
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -18,10 +18,7 @@ using System.Collections;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class HidatoTable
{
public class HidatoTable {
/*
* Build closeness pairs for consecutive numbers.
*
@@ -35,32 +32,27 @@ public class HidatoTable
* rows: the number of rows in the grid
* cols: the number of columns in the grid
*/
public static IntTupleSet BuildPairs(int rows, int cols)
{
public static IntTupleSet BuildPairs(int rows, int cols) {
int[] ix = {-1, 0, 1};
var result_tmp = (from x in Enumerable.Range(0, rows)
from y in Enumerable.Range(0, cols)
from dx in ix
from dy in ix
where
x + dx >= 0 &&
x + dx < rows &&
y + dy >= 0 &&
y + dy < cols &&
(dx != 0 || dy != 0)
select new int[] {x * cols + y, (x + dx) * cols + (y + dy)}
).ToArray();
var result_tmp =
(from x in Enumerable.Range(0, rows) from y in Enumerable.Range(0, cols)
from dx in ix from dy in ix where x +
dx >=
0 &&
x + dx < rows && y + dy >= 0 && y + dy < cols &&
(dx != 0 || dy != 0)
select new int[]{x * cols + y, (x + dx) * cols + (y + dy)})
.ToArray();
// Convert to len x 2 matrix
int len = result_tmp.Length;
IntTupleSet result = new IntTupleSet(2);
foreach(int[] r in result_tmp) {
foreach (int[] r in result_tmp) {
result.Insert(r);
}
return result;
}
/**
*
* Hidato puzzle in Google CP Solver.
@@ -79,79 +71,65 @@ public class HidatoTable
* based on my (much slower) model hidato.py.
*
*/
private static void Solve(int model = 1)
{
private static void Solve(int model = 1) {
Solver solver = new Solver("HidatoTable");
//
// models, a 0 indicates an open cell which number is not yet known.
//
int[,] puzzle = null;
int[, ] puzzle = null;
if (model == 1) {
// Simple problem
// Solution 1:
// 6 7 9
// 5 2 8
// 1 4 3
int[,] puzzle1 = {{6, 0, 9},
{0, 2, 8},
{1, 0, 0}};
int[, ] puzzle1 = {{6, 0, 9}, {0, 2, 8}, {1, 0, 0}};
puzzle = puzzle1;
} else if (model == 2) {
int[,] puzzle2 = {{0, 44, 41, 0, 0, 0, 0},
{0, 43, 0, 28, 29, 0, 0},
{0, 1, 0, 0, 0, 33, 0},
{0, 2, 25, 4, 34, 0, 36},
{49, 16, 0, 23, 0, 0, 0},
{0, 19, 0, 0, 12, 7, 0},
{0, 0, 0, 14, 0, 0, 0}};
int[, ] puzzle2 = {{0, 44, 41, 0, 0, 0, 0}, {0, 43, 0, 28, 29, 0, 0},
{0, 1, 0, 0, 0, 33, 0}, {0, 2, 25, 4, 34, 0, 36},
{49, 16, 0, 23, 0, 0, 0}, {0, 19, 0, 0, 12, 7, 0},
{0, 0, 0, 14, 0, 0, 0}};
puzzle = puzzle2;
} else if (model == 3) {
// Problems from the book:
// Gyora Bededek: "Hidato: 2000 Pure Logic Puzzles"
// Problem 1 (Practice)
int[,] puzzle3 = {{0, 0, 20, 0, 0},
{0, 0, 0, 16, 18},
{22, 0, 15, 0, 0},
{23, 0, 1, 14, 11},
{0, 25, 0, 0, 12}};
int[, ] puzzle3 = {{0, 0, 20, 0, 0},
{0, 0, 0, 16, 18},
{22, 0, 15, 0, 0},
{23, 0, 1, 14, 11},
{0, 25, 0, 0, 12}};
puzzle = puzzle3;
} else if (model == 4) {
// problem 2 (Practice)
int[,] puzzle4 = {{0, 0, 0, 0, 14},
{0, 18, 12, 0, 0},
{0, 0, 17, 4, 5},
{0, 0, 7, 0, 0},
{9, 8, 25, 1, 0}};
int[, ] puzzle4 = {{0, 0, 0, 0, 14},
{0, 18, 12, 0, 0},
{0, 0, 17, 4, 5},
{0, 0, 7, 0, 0},
{9, 8, 25, 1, 0}};
puzzle = puzzle4;
} else if (model == 5) {
// problem 3 (Beginner)
int[,] puzzle5 = {{0, 26, 0, 0, 0, 18},
{0, 0, 27, 0, 0, 19},
{31, 23, 0, 0, 14, 0},
{0, 33, 8, 0, 15, 1},
{0, 0, 0, 5, 0, 0},
{35, 36, 0, 10, 0, 0}};
int[, ] puzzle5 = {{0, 26, 0, 0, 0, 18}, {0, 0, 27, 0, 0, 19},
{31, 23, 0, 0, 14, 0}, {0, 33, 8, 0, 15, 1},
{0, 0, 0, 5, 0, 0}, {35, 36, 0, 10, 0, 0}};
puzzle = puzzle5;
} else if (model == 6) {
// Problem 15 (Intermediate)
int[,] puzzle6 = {{64, 0, 0, 0, 0, 0, 0, 0},
{1, 63, 0, 59, 15, 57, 53, 0},
{0, 4, 0, 14, 0, 0, 0, 0},
{3, 0, 11, 0, 20, 19, 0, 50},
{0, 0, 0, 0, 22, 0, 48, 40},
{9, 0, 0, 32, 23, 0, 0, 41},
{27, 0, 0, 0, 36, 0, 46, 0},
{28, 30, 0, 35, 0, 0, 0, 0}};
int[, ] puzzle6 = {
{64, 0, 0, 0, 0, 0, 0, 0}, {1, 63, 0, 59, 15, 57, 53, 0},
{0, 4, 0, 14, 0, 0, 0, 0}, {3, 0, 11, 0, 20, 19, 0, 50},
{0, 0, 0, 0, 22, 0, 48, 40}, {9, 0, 0, 32, 23, 0, 0, 41},
{27, 0, 0, 0, 36, 0, 46, 0}, {28, 30, 0, 35, 0, 0, 0, 0}};
puzzle = puzzle6;
}
@@ -167,8 +145,7 @@ public class HidatoTable
//
// Decision variables
//
IntVar[] positions = solver.MakeIntVarArray(r*c, 0, r * c - 1, "p");
IntVar[] positions = solver.MakeIntVarArray(r * c, 0, r * c - 1, "p");
//
// Constraints
@@ -178,10 +155,10 @@ public class HidatoTable
//
// Fill in the clues
//
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
if (puzzle[i,j] > 0) {
solver.Add(positions[puzzle[i,j] - 1] == i * c + j);
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (puzzle[i, j] > 0) {
solver.Add(positions[puzzle[i, j] - 1] == i * c + j);
}
}
}
@@ -189,18 +166,16 @@ public class HidatoTable
// Consecutive numbers much touch each other in the grid.
// We use an allowed assignment constraint to model it.
IntTupleSet close_tuples = BuildPairs(r, c);
for(int k = 1; k < r * c - 1; k++) {
IntVar[] tmp = new IntVar[] {positions[k], positions[k + 1]};
for (int k = 1; k < r * c - 1; k++) {
IntVar[] tmp = new IntVar[]{positions[k], positions[k + 1]};
solver.Add(tmp.AllowedAssignments(close_tuples));
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(positions,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db = solver.MakePhase(
positions, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
@@ -216,49 +191,42 @@ public class HidatoTable
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
// Print the current solution
public static void PrintOneSolution(IntVar[] positions,
int rows,
int cols,
int num_solution)
{
public static void PrintOneSolution(IntVar[] positions, int rows, int cols,
int num_solution) {
Console.WriteLine("Solution {0}", num_solution);
// Create empty board
int[,] board = new int[rows, cols];
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
board[i,j] = 0;
int[, ] board = new int[rows, cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
board[i, j] = 0;
}
}
// Fill board with solution value
for(int k = 0; k < rows*cols; k++) {
int position = (int)positions[k].Value();
for (int k = 0; k < rows * cols; k++) {
int position = (int) positions [k]
.Value();
board[position / cols, position % cols] = k + 1;
}
PrintMatrix(board);
}
// Pretty print of the matrix
public static void PrintMatrix(int[,] game)
{
public static void PrintMatrix(int[, ] game) {
int rows = game.GetLength(0);
int cols = game.GetLength(1);
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
if (game[i,j] == 0) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (game[i, j] == 0) {
Console.Write(" .");
} else {
Console.Write(" {0,2}", game[i,j] );
Console.Write(" {0,2}", game[i, j]);
}
}
Console.WriteLine();
@@ -266,22 +234,16 @@ public class HidatoTable
Console.WriteLine();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int model = 1;
if (args.Length > 0) {
model = Convert.ToInt32(args[0]);
Solve(model);
} else {
for(int m = 1; m <= 6; m++) {
for (int m = 1; m <= 6; m++) {
Solve(m);
}
}
}
}

View File

@@ -20,12 +20,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class JustForgotten
{
public class JustForgotten {
/**
*
* Just forgotten puzzle (Enigma 1517) in Google CP Solver.
@@ -52,20 +47,17 @@ public class JustForgotten
* Also see http://www.hakank.org/google_or_tools/just_forgotten.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("JustForgotten");
int rows = 4;
int cols = 10;
// The four tries
int[,] a = {{9,4,6,2,1,5,7,8,3,0},
{8,6,0,4,3,9,1,2,5,7},
{1,6,4,0,2,9,7,8,5,3},
{6,8,2,4,3,1,9,0,7,5}};
int[, ] a = {{9, 4, 6, 2, 1, 5, 7, 8, 3, 0},
{8, 6, 0, 4, 3, 9, 1, 2, 5, 7},
{1, 6, 4, 0, 2, 9, 7, 8, 5, 3},
{6, 8, 2, 4, 3, 1, 9, 0, 7, 5}};
//
// Decision variables
@@ -76,36 +68,38 @@ public class JustForgotten
// Constraints
//
solver.Add(x.AllDifferent());
for(int r = 0; r < rows; r++) {
solver.Add( (from c in Enumerable.Range(0, cols)
select x[c] == a[r,c]).ToArray().Sum() == 4);
for (int r = 0; r < rows; r++) {
solver.Add((from c in Enumerable.Range(0, cols) select x[c] == a[r, c])
.ToArray()
.Sum() == 4);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.WriteLine("Account number:");
for(int j = 0; j < cols; j++) {
Console.Write(x[j].Value() + " ");
for (int j = 0; j < cols; j++) {
Console.Write(x [j]
.Value() +
" ");
}
Console.WriteLine("\n");
Console.WriteLine("The four tries, where '!' represents a correct digit:");
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
Console.WriteLine(
"The four tries, where '!' represents a correct digit:");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
String c = " ";
if (a[i,j] == x[j].Value()) {
if (a[i, j] == x [j]
.Value()) {
c = "!";
}
Console.Write("{0}{1} ", a[i,j], c);
Console.Write("{0}{1} ", a[i, j], c);
}
Console.WriteLine();
}
@@ -118,12 +112,7 @@ public class JustForgotten
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,35 +19,26 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class Kakuro
{
public class Kakuro {
/**
* Ensure that the sum of the segments
* in cc == res
*
*/
public static void calc(Solver solver,
int[] cc,
IntVar[,] x,
int res)
{
public static void calc(Solver solver, int[] cc, IntVar[, ] x, int res) {
// ensure that the values are positive
int len = cc.Length / 2;
for(int i = 0; i < len; i++) {
solver.Add(x[cc[i*2]-1,cc[i*2+1]-1] >= 1);
for (int i = 0; i < len; i++) {
solver.Add(x[cc[i * 2] - 1, cc[i * 2 + 1] - 1] >= 1);
}
// sum the numbers
solver.Add( (from i in Enumerable.Range(0, len)
select x[cc[i*2]-1,cc[i*2+1]-1])
.ToArray().Sum() == res);
solver.Add((from i in Enumerable.Range(0, len)
select x[cc[i * 2] - 1, cc[i * 2 + 1] - 1])
.ToArray()
.Sum() == res);
}
/**
*
* Kakuru puzzle.
@@ -85,9 +76,7 @@ public class Kakuro
* the problem instance.
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Kakuro");
// size of matrix
@@ -96,58 +85,47 @@ public class Kakuro
// segments:
// sum, the segments
// Note: this is 1-based
int[][] problem =
{
new int[] {16, 1,1, 1,2},
new int[] {24, 1,5, 1,6, 1,7},
new int[] {17, 2,1, 2,2},
new int[] {29, 2,4, 2,5, 2,6, 2,7},
new int[] {35, 3,1, 3,2, 3,3, 3,4, 3,5},
new int[] { 7, 4,2, 4,3},
new int[] { 8, 4,5, 4,6},
new int[] {16, 5,3, 5,4, 5,5, 5,6, 5,7},
new int[] {21, 6,1, 6,2, 6,3, 6,4},
new int[] { 5, 6,6, 6,7},
new int[] { 6, 7,1, 7,2, 7,3},
new int[] { 3, 7,6, 7,7},
int[][] problem = {new int[]{16, 1, 1, 1, 2},
new int[]{24, 1, 5, 1, 6, 1, 7},
new int[]{17, 2, 1, 2, 2},
new int[]{29, 2, 4, 2, 5, 2, 6, 2, 7},
new int[]{35, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5},
new int[]{7, 4, 2, 4, 3},
new int[]{8, 4, 5, 4, 6},
new int[]{16, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7},
new int[]{21, 6, 1, 6, 2, 6, 3, 6, 4},
new int[]{5, 6, 6, 6, 7},
new int[]{6, 7, 1, 7, 2, 7, 3},
new int[]{3, 7, 6, 7, 7},
new int[] {23, 1,1, 2,1, 3,1},
new int[] {30, 1,2, 2,2, 3,2, 4,2},
new int[] {27, 1,5, 2,5, 3,5, 4,5, 5,5},
new int[] {12, 1,6, 2,6},
new int[] {16, 1,7, 2,7},
new int[] {17, 2,4, 3,4},
new int[] {15, 3,3, 4,3, 5,3, 6,3, 7,3},
new int[] {12, 4,6, 5,6, 6,6, 7,6},
new int[] { 7, 5,4, 6,4},
new int[] { 7, 5,7, 6,7, 7,7},
new int[] {11, 6,1, 7,1},
new int[] {10, 6,2, 7,2}
new int[]{23, 1, 1, 2, 1, 3, 1},
new int[]{30, 1, 2, 2, 2, 3, 2, 4, 2},
new int[]{27, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5},
new int[]{12, 1, 6, 2, 6},
new int[]{16, 1, 7, 2, 7},
new int[]{17, 2, 4, 3, 4},
new int[]{15, 3, 3, 4, 3, 5, 3, 6, 3, 7, 3},
new int[]{12, 4, 6, 5, 6, 6, 6, 7, 6},
new int[]{7, 5, 4, 6, 4},
new int[]{7, 5, 7, 6, 7, 7, 7},
new int[]{11, 6, 1, 7, 1},
new int[]{10, 6, 2, 7, 2}
};
};
int num_p = 24; // Number of segments
int num_p = 24; // Number of segments
// The blanks
// Note: 1-based
int[,] blanks = {
{1,3}, {1,4},
{2,3},
{3,6}, {3,7},
{4,1}, {4,4}, {4,7},
{5,1}, {5,2},
{6,5},
{7,4}, {7,5}
};
int[, ] blanks = {{1, 3}, {1, 4}, {2, 3}, {3, 6}, {3, 7}, {4, 1}, {4, 4},
{4, 7}, {5, 1}, {5, 2}, {6, 5}, {7, 4}, {7, 5}};
int num_blanks = blanks.GetLength(0);
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 0, 9, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 0, 9, "x");
IntVar[] x_flat = x.Flatten();
//
@@ -155,17 +133,17 @@ public class Kakuro
//
// fill the blanks with 0
for(int i = 0; i < num_blanks; i++) {
solver.Add(x[blanks[i,0]-1,blanks[i,1]-1]==0);
for (int i = 0; i < num_blanks; i++) {
solver.Add(x[blanks[i, 0] - 1, blanks[i, 1] - 1] == 0);
}
for(int i = 0; i < num_p; i++) {
for (int i = 0; i < num_p; i++) {
int[] segment = problem[i];
// Remove the sum from the segment
int[] s2 = new int[segment.Length-1];
for(int j = 1; j < segment.Length; j++) {
s2[j-1] = segment[j];
int[] s2 = new int[segment.Length - 1];
for (int j = 1; j < segment.Length; j++) {
s2[j - 1] = segment[j];
}
// sum this segment
@@ -173,24 +151,25 @@ public class Kakuro
// all numbers in this segment must be distinct
int len = segment.Length / 2;
solver.Add( (from j in Enumerable.Range(0, len)
select x[s2[j * 2] - 1, s2[j * 2 + 1] - 1])
.ToArray().AllDifferent());
solver.Add((from j in Enumerable.Range(0, len)
select x[s2[j * 2] - 1, s2[j * 2 + 1] - 1])
.ToArray()
.AllDifferent());
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
int v = (int)x[i,j].Value();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int v = (int) x [i, j]
.Value();
if (v > 0) {
Console.Write(v + " ");
} else {
@@ -207,13 +186,7 @@ public class Kakuro
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,28 +19,19 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class KenKen2
{
public class KenKen2 {
/**
* Ensure that the sum of the segments
* in cc == res
*
*/
public static void calc(Solver solver,
int[] cc,
IntVar[,] x,
int res)
{
public static void calc(Solver solver, int[] cc, IntVar[, ] x, int res) {
int ccLen = cc.Length;
if (ccLen == 4) {
// for two operands there's
// a lot of possible variants
IntVar a = x[cc[0]-1, cc[1]-1];
IntVar b = x[cc[2]-1, cc[3]-1];
IntVar a = x[cc[0] - 1, cc[1] - 1];
IntVar b = x[cc[2] - 1, cc[3] - 1];
IntVar r1 = a + b == res;
IntVar r2 = a * b == res;
@@ -49,17 +40,17 @@ public class KenKen2
IntVar r5 = a - b == res;
IntVar r6 = b - a == res;
solver.Add(r1+r2+r3+r4+r5+r6 >= 1);
solver.Add(r1 + r2 + r3 + r4 + r5 + r6 >= 1);
} else {
// For length > 2 then res is either the sum
// the the product of the segment
// sum the numbers
int len = cc.Length / 2;
IntVar[] xx = (from i in Enumerable.Range(0, len)
select x[cc[i*2]-1,cc[i*2+1]-1]).ToArray();
select x[cc[i * 2] - 1, cc[i * 2 + 1] - 1])
.ToArray();
// Sum
IntVar this_sum = xx.Sum() == res;
@@ -68,25 +59,17 @@ public class KenKen2
// IntVar this_prod = (xx.Prod() == res).Var(); // don't work
IntVar this_prod;
if (xx.Length == 3) {
this_prod = (x[cc[0]-1,cc[1]-1] *
x[cc[2]-1,cc[3]-1] *
x[cc[4]-1,cc[5]-1]) == res;
this_prod = (x[cc[0] - 1, cc[1] - 1] * x[cc[2] - 1, cc[3] - 1] *
x[cc[4] - 1, cc[5] - 1]) == res;
} else {
this_prod = (x[cc[0]-1,cc[1]-1] *
x[cc[2]-1,cc[3]-1] *
x[cc[4]-1,cc[5]-1] *
x[cc[6]-1,cc[7]-1]) == res;
this_prod = (x[cc[0] - 1, cc[1] - 1] * x[cc[2] - 1, cc[3] - 1] *
x[cc[4] - 1, cc[5] - 1] * x[cc[6] - 1, cc[7] - 1]) == res;
}
solver.Add(this_sum + this_prod >= 1);
}
}
/**
*
* KenKen puzzle.
@@ -130,9 +113,7 @@ public class KenKen2
* the problem instance.
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("KenKen2");
// size of matrix
@@ -145,32 +126,28 @@ public class KenKen2
// hints
// sum, the hints
// Note: this is 1-based
int[][] problem =
{
new int[] { 11, 1,1, 2,1},
new int[] { 2, 1,2, 1,3},
new int[] { 20, 1,4, 2,4},
new int[] { 6, 1,5, 1,6, 2,6, 3,6},
new int[] { 3, 2,2, 2,3},
new int[] { 3, 2,5, 3,5},
new int[] {240, 3,1, 3,2, 4,1, 4,2},
new int[] { 6, 3,3, 3,4},
new int[] { 6, 4,3, 5,3},
new int[] { 7, 4,4, 5,4, 5,5},
new int[] { 30, 4,5, 4,6},
new int[] { 6, 5,1, 5,2},
new int[] { 9, 5,6, 6,6},
new int[] { 8, 6,1, 6,2, 6,3},
new int[] { 2, 6,4, 6,5}
};
int[][] problem = {new int[]{11, 1, 1, 2, 1},
new int[]{2, 1, 2, 1, 3},
new int[]{20, 1, 4, 2, 4},
new int[]{6, 1, 5, 1, 6, 2, 6, 3, 6},
new int[]{3, 2, 2, 2, 3},
new int[]{3, 2, 5, 3, 5},
new int[]{240, 3, 1, 3, 2, 4, 1, 4, 2},
new int[]{6, 3, 3, 3, 4},
new int[]{6, 4, 3, 5, 3},
new int[]{7, 4, 4, 5, 4, 5, 5},
new int[]{30, 4, 5, 4, 6},
new int[]{6, 5, 1, 5, 2},
new int[]{9, 5, 6, 6, 6},
new int[]{8, 6, 1, 6, 2, 6, 3},
new int[]{2, 6, 4, 6, 5}};
int num_p = problem.GetLength(0); // Number of segments
int num_p = problem.GetLength(0); // Number of segments
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
IntVar[] x_flat = x.Flatten();
//
@@ -179,44 +156,41 @@ public class KenKen2
//
// alldifferent rows and columns
foreach(int i in RANGE) {
foreach (int i in RANGE) {
// rows
solver.Add( (from j in RANGE select x[i,j]).ToArray().AllDifferent());
solver.Add((from j in RANGE select x[i, j]).ToArray().AllDifferent());
// cols
solver.Add( (from j in RANGE select x[j,i]).ToArray().AllDifferent());
solver.Add((from j in RANGE select x[j, i]).ToArray().AllDifferent());
}
// Calculate the segments
for(int i = 0; i < num_p; i++) {
for (int i = 0; i < num_p; i++) {
int[] segment = problem[i];
// Remove the sum from the segment
int len = segment.Length-1;
int len = segment.Length - 1;
int[] s2 = new int[len];
Array.Copy(segment, 1, s2, 0, len);
// sum this segment
calc(solver, s2, x, segment[0]);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
Console.Write(x[i,j].Value() + " ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write(x [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -229,13 +203,7 @@ public class KenKen2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,29 +19,21 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class KillerSudoku
{
public class KillerSudoku {
/**
* Ensure that the sum of the segments
* in cc == res
*
*/
public static void calc(Solver solver,
int[] cc,
IntVar[,] x,
int res)
{
public static void calc(Solver solver, int[] cc, IntVar[, ] x, int res) {
// sum the numbers
int len = cc.Length / 2;
solver.Add( (from i in Enumerable.Range(0, len)
select x[cc[i*2]-1,cc[i*2+1]-1]).ToArray().Sum() == res);
solver.Add((from i in Enumerable.Range(0, len)
select x[cc[i * 2] - 1, cc[i * 2 + 1] - 1])
.ToArray()
.Sum() == res);
}
/**
*
* Killer Sudoku.
@@ -89,15 +81,13 @@ public class KillerSudoku
* the problem instance.
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("KillerSudoku");
// size of matrix
int cell_size = 3;
IEnumerable<int> CELL = Enumerable.Range(0, cell_size);
int n = cell_size*cell_size;
int n = cell_size * cell_size;
IEnumerable<int> RANGE = Enumerable.Range(0, n);
// For a better view of the problem, see
@@ -106,47 +96,44 @@ public class KillerSudoku
// hints
// sum, the hints
// Note: this is 1-based
int[][] problem =
{
new int[] { 3, 1,1, 1,2},
new int[] {15, 1,3, 1,4, 1,5},
new int[] {22, 1,6, 2,5, 2,6, 3,5},
new int[] {4, 1,7, 2,7},
new int[] {16, 1,8, 2,8},
new int[] {15, 1,9, 2,9, 3,9, 4,9},
new int[] {25, 2,1, 2,2, 3,1, 3,2},
new int[] {17, 2,3, 2,4},
new int[] { 9, 3,3, 3,4, 4,4},
new int[] { 8, 3,6, 4,6, 5,6},
new int[] {20, 3,7, 3,8, 4,7},
new int[] { 6, 4,1, 5,1},
new int[] {14, 4,2, 4,3},
new int[] {17, 4,5, 5,5, 6,5},
new int[] {17, 4,8, 5,7, 5,8},
new int[] {13, 5,2, 5,3, 6,2},
new int[] {20, 5,4, 6,4, 7,4},
new int[] {12, 5,9, 6,9},
new int[] {27, 6,1, 7,1, 8,1, 9,1},
new int[] { 6, 6,3, 7,2, 7,3},
new int[] {20, 6,6, 7,6, 7,7},
new int[] { 6, 6,7, 6,8},
new int[] {10, 7,5, 8,4, 8,5, 9,4},
new int[] {14, 7,8, 7,9, 8,8, 8,9},
new int[] { 8, 8,2, 9,2},
new int[] {16, 8,3, 9,3},
new int[] {15, 8,6, 8,7},
new int[] {13, 9,5, 9,6, 9,7},
new int[] {17, 9,8, 9,9}
int[][] problem = {new int[]{3, 1, 1, 1, 2},
new int[]{15, 1, 3, 1, 4, 1, 5},
new int[]{22, 1, 6, 2, 5, 2, 6, 3, 5},
new int[]{4, 1, 7, 2, 7},
new int[]{16, 1, 8, 2, 8},
new int[]{15, 1, 9, 2, 9, 3, 9, 4, 9},
new int[]{25, 2, 1, 2, 2, 3, 1, 3, 2},
new int[]{17, 2, 3, 2, 4},
new int[]{9, 3, 3, 3, 4, 4, 4},
new int[]{8, 3, 6, 4, 6, 5, 6},
new int[]{20, 3, 7, 3, 8, 4, 7},
new int[]{6, 4, 1, 5, 1},
new int[]{14, 4, 2, 4, 3},
new int[]{17, 4, 5, 5, 5, 6, 5},
new int[]{17, 4, 8, 5, 7, 5, 8},
new int[]{13, 5, 2, 5, 3, 6, 2},
new int[]{20, 5, 4, 6, 4, 7, 4},
new int[]{12, 5, 9, 6, 9},
new int[]{27, 6, 1, 7, 1, 8, 1, 9, 1},
new int[]{6, 6, 3, 7, 2, 7, 3},
new int[]{20, 6, 6, 7, 6, 7, 7},
new int[]{6, 6, 7, 6, 8},
new int[]{10, 7, 5, 8, 4, 8, 5, 9, 4},
new int[]{14, 7, 8, 7, 9, 8, 8, 8, 9},
new int[]{8, 8, 2, 9, 2},
new int[]{16, 8, 3, 9, 3},
new int[]{15, 8, 6, 8, 7},
new int[]{13, 9, 5, 9, 6, 9, 7},
new int[]{17, 9, 8, 9, 9}
};
};
int num_p = 29; // Number of segments
int num_p = 29; // Number of segments
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 0, 9, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 0, 9, "x");
IntVar[] x_flat = x.Flatten();
//
@@ -157,36 +144,32 @@ public class KillerSudoku
// The first three constraints is the same as for sudokus.cs
//
// alldifferent rows and columns
foreach(int i in RANGE) {
foreach (int i in RANGE) {
// rows
solver.Add( (from j in RANGE
select x[i,j]).ToArray().AllDifferent());
solver.Add((from j in RANGE select x[i, j]).ToArray().AllDifferent());
// cols
solver.Add( (from j in RANGE
select x[j,i]).ToArray().AllDifferent());
solver.Add((from j in RANGE select x[j, i]).ToArray().AllDifferent());
}
// cells
foreach(int i in CELL) {
foreach(int j in CELL) {
solver.Add( (from di in CELL
from dj in CELL
select x[i*cell_size+di, j*cell_size+dj]
).ToArray().AllDifferent());
foreach (int i in CELL) {
foreach (int j in CELL) {
solver.Add((from di in CELL from dj in CELL select
x[i * cell_size + di, j * cell_size + dj])
.ToArray()
.AllDifferent());
}
}
// Sum the segments and ensure alldifferent
for(int i = 0; i < num_p; i++) {
for (int i = 0; i < num_p; i++) {
int[] segment = problem[i];
// Remove the sum from the segment
int[] s2 = new int[segment.Length-1];
for(int j = 1; j < segment.Length; j++) {
s2[j-1] = segment[j];
int[] s2 = new int[segment.Length - 1];
for (int j = 1; j < segment.Length; j++) {
s2[j - 1] = segment[j];
}
// sum this segment
@@ -194,24 +177,25 @@ public class KillerSudoku
// all numbers in this segment must be distinct
int len = segment.Length / 2;
solver.Add( (from j in Enumerable.Range(0, len)
select x[s2[j*2]-1, s2[j*2+1]-1])
.ToArray().AllDifferent());
solver.Add((from j in Enumerable.Range(0, len)
select x[s2[j * 2] - 1, s2[j * 2 + 1] - 1])
.ToArray()
.AllDifferent());
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
int v = (int)x[i,j].Value();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int v = (int) x [i, j]
.Value();
if (v > 0) {
Console.Write(v + " ");
} else {
@@ -228,13 +212,7 @@ public class KillerSudoku
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,10 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class LabeledDice
{
public class LabeledDice {
/**
*
* Labeled dice problem.
@@ -49,9 +46,7 @@ public class LabeledDice
* Also see http://www.hakank.org/or-tools/labeled_dice.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("LabeledDice");
//
@@ -85,45 +80,31 @@ public class LabeledDice
int W = 22;
int Y = 23;
String[] letters_str = {"A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","Y"};
String[] letters_str = {"A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P",
"Q", "R", "S", "T", "U", "V", "W", "Y"};
int num_words = 13;
int[,] words =
{
{B,U,O,Y},
{C,A,V,E},
{C,E,L,T},
{F,L,U,B},
{F,O,R,K},
{H,E,M,P},
{J,U,D,Y},
{J,U,N,K},
{L,I,M,N},
{Q,U,I,P},
{S,W,A,G},
{V,I,S,A},
{W,I,S,H}
};
int[, ] words = {{B, U, O, Y}, {C, A, V, E}, {C, E, L, T}, {F, L, U, B},
{F, O, R, K}, {H, E, M, P}, {J, U, D, Y}, {J, U, N, K},
{L, I, M, N}, {Q, U, I, P}, {S, W, A, G}, {V, I, S, A},
{W, I, S, H}};
//
// Decision variables
//
IntVar[] dice = solver.MakeIntVarArray(m, 0, n-1, "dice");
IntVar[] gcc = solver.MakeIntVarArray(n, 6, 6, "gcc");
IntVar[] dice = solver.MakeIntVarArray(m, 0, n - 1, "dice");
IntVar[] gcc = solver.MakeIntVarArray(n, 6, 6, "gcc");
//
// Constraints
//
// the letters in a word must be on a different die
for(int i = 0; i < num_words; i++) {
solver.Add( (from j in Enumerable.Range(0, n)
select dice[words[i,j]]
).ToArray().AllDifferent());
for (int i = 0; i < num_words; i++) {
solver.Add((from j in Enumerable.Range(0, n) select dice[words[i, j]])
.ToArray()
.AllDifferent());
}
// there must be exactly 6 letters of each die
@@ -140,17 +121,17 @@ public class LabeledDice
//
// Search
//
DecisionBuilder db = solver.MakePhase(dice,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(dice, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int d = 0; d < n; d++) {
for (int d = 0; d < n; d++) {
Console.Write("die {0}: ", d);
for(int i = 0; i < m; i++) {
if (dice[i].Value() == d) {
for (int i = 0; i < m; i++) {
if (dice [i]
.Value() == d) {
Console.Write(letters_str[i]);
}
}
@@ -158,9 +139,10 @@ public class LabeledDice
}
Console.WriteLine("The words with the cube label:");
for(int i = 0; i < num_words; i++) {
for(int j = 0; j < n; j++) {
Console.Write("{0} ({1})", letters_str[words[i,j]], dice[words[i,j]].Value());
for (int i = 0; i < num_words; i++) {
for (int j = 0; j < n; j++) {
Console.Write("{0} ({1})", letters_str[words[i, j]],
dice[words[i, j]].Value());
}
Console.WriteLine();
}
@@ -173,12 +155,7 @@ public class LabeledDice
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,18 +19,14 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class Langford
{
public class Langford {
/**
*
* Langford number problem.
* See http://www.hakank.org/or-tools/langford.py
*
*/
private static void Solve(int k = 8, int num_sol = 0)
{
private static void Solve(int k = 8, int num_sol = 0) {
Solver solver = new Solver("Langford");
Console.WriteLine("k: {0}", k);
@@ -38,12 +34,12 @@ public class Langford
//
// data
//
int p = 2*k;
int p = 2 * k;
//
// Decision variables
//
IntVar[] position = solver.MakeIntVarArray(p, 0, p-1, "position");
IntVar[] position = solver.MakeIntVarArray(p, 0, p - 1, "position");
IntVar[] solution = solver.MakeIntVarArray(p, 1, k, "solution");
//
@@ -51,30 +47,32 @@ public class Langford
//
solver.Add(position.AllDifferent());
for(int i = 1; i <= k; i++) {
solver.Add(position[i+k-1] - (position[i-1] + solver.MakeIntVar(i+1,i+1)) == 0);
solver.Add(solution.Element(position[i-1]) == i);
solver.Add(solution.Element(position[k+i-1]) == i);
for (int i = 1; i <= k; i++) {
solver.Add(position[i + k - 1] -
(position[i - 1] + solver.MakeIntVar(i + 1, i + 1)) ==
0);
solver.Add(solution.Element(position[i - 1]) == i);
solver.Add(solution.Element(position[k + i - 1]) == i);
}
// Symmetry breaking
solver.Add(solution[0] < solution[2*k-1]);
solver.Add(solution[0] < solution[2 * k - 1]);
//
// Search
//
DecisionBuilder db = solver.MakePhase(position,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(position, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
int num_solutions = 0;
while (solver.NextSolution()) {
Console.Write("solution : ");
for(int i = 0; i < p; i++) {
Console.Write(solution[i].Value() + " ");
for (int i = 0; i < p; i++) {
Console.Write(solution [i]
.Value() +
" ");
}
Console.WriteLine();
num_solutions++;
@@ -89,15 +87,11 @@ public class Langford
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int k = 8;
int num_sol = 0; // 0: print all solutions
int num_sol = 0; // 0: print all solutions
if (args.Length > 0) {
k = Convert.ToInt32(args[0]);
@@ -108,6 +102,5 @@ public class Langford
}
Solve(k, num_sol);
}
}

View File

@@ -16,16 +16,14 @@
using System;
using Google.OrTools.ConstraintSolver;
public class LeastDiff
{
public class LeastDiff {
/**
*
* Solve the Least diff problem
* For more info, see http://www.hakank.org/google_or_tools/least_diff.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("LeastDiff");
//
@@ -42,13 +40,12 @@ public class LeastDiff
IntVar I = solver.MakeIntVar(0, 9, "I");
IntVar J = solver.MakeIntVar(0, 9, "J");
IntVar[] all = new IntVar[] {A,B,C,D,E,F,G,H,I,J};
int[] coeffs = {10000,1000,100,10,1};
IntVar x = new IntVar[]{A,B,C,D,E}.ScalProd(coeffs).Var();
IntVar y = new IntVar[]{F,G,H,I,J}.ScalProd(coeffs).Var();
IntVar[] all = new IntVar[]{A, B, C, D, E, F, G, H, I, J};
int[] coeffs = {10000, 1000, 100, 10, 1};
IntVar x = new IntVar[]{A, B, C, D, E}.ScalProd(coeffs).Var();
IntVar y = new IntVar[]{F, G, H, I, J}.ScalProd(coeffs).Var();
IntVar diff = (x - y).VarWithName("diff");
//
// Constraints
//
@@ -57,7 +54,6 @@ public class LeastDiff
solver.Add(F > 0);
solver.Add(diff > 0);
//
// Objective
//
@@ -66,13 +62,13 @@ public class LeastDiff
//
// Search
//
DecisionBuilder db = solver.MakePhase(all,
Solver.CHOOSE_PATH,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db =
solver.MakePhase(all, Solver.CHOOSE_PATH, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("{0} - {1} = {2} ({3}",x.Value(), y.Value(), diff.Value(), diff.ToString());
Console.WriteLine("{0} - {1} = {2} ({3}", x.Value(), y.Value(),
diff.Value(), diff.ToString());
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -81,11 +77,7 @@ public class LeastDiff
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -18,9 +18,7 @@ using System.Collections;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class Lectures
{
public class Lectures {
/**
*
* Lectures problem in Google CP Solver.
@@ -45,27 +43,17 @@ public class Lectures
* Note: This can be seen as a coloring problem.
*
* Also see http://www.hakank.org/or-tools/lectures.py
*
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Lectures");
//
// The schedule requirements:
// lecture a cannot be held at the same time as b
// Note: 1-based (compensated in the constraints).
int[,] g =
{
{1, 2},
{1, 4},
{3, 5},
{2, 6},
{4, 5},
{5, 6},
{1, 6}
};
int[, ] g = {{1, 2}, {1, 4}, {3, 5}, {2, 6}, {4, 5}, {5, 6}, {1, 6}};
// number of nodes
int n = 6;
@@ -78,22 +66,21 @@ public class Lectures
//
// declare variables
//
IntVar[] v = solver.MakeIntVarArray(n, 0, n-1,"v");
IntVar[] v = solver.MakeIntVarArray(n, 0, n - 1, "v");
// Maximum color (hour) to minimize.
// Note: since C# is 0-based, the
// number of colors is max_c+1.
IntVar max_c = v.Max().VarWithName("max_c");
//
// Constraints
//
// Ensure that there are no clashes
// also, adjust to 0-base.
for(int i = 0; i < edges; i++) {
solver.Add(v[g[i,0]-1] != v[g[i,1]-1]);
for (int i = 0; i < edges; i++) {
solver.Add(v[g[i, 0] - 1] != v[g[i, 1] - 1]);
}
// Symmetry breaking:
@@ -102,7 +89,6 @@ public class Lectures
solver.Add(v[0] == 0);
solver.Add(v[1] <= 1);
//
// Objective
//
@@ -111,19 +97,21 @@ public class Lectures
//
// Search
//
DecisionBuilder db = solver.MakePhase(v,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
DecisionBuilder db = solver.MakePhase(v, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("\nmax hours: {0}", max_c.Value()+1);
Console.WriteLine("v: " +
String.Join(" ", (from i in Enumerable.Range(0, n)
select v[i].Value()).ToArray()));
for(int i = 0; i < n; i++) {
Console.WriteLine("Lecture {0} at {1}h", i, v[i].Value());
Console.WriteLine("\nmax hours: {0}", max_c.Value() + 1);
Console.WriteLine("v: " + String.Join(" ", (from i in Enumerable
.Range(0, n) select v [i]
.Value())
.ToArray()));
for (int i = 0; i < n; i++) {
Console.WriteLine("Lecture {0} at {1}h", i,
v [i]
.Value());
}
Console.WriteLine("\n");
}
@@ -134,49 +122,42 @@ public class Lectures
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
// Print the current solution
public static void PrintOneSolution(IntVar[] positions,
int rows,
int cols,
int num_solution)
{
public static void PrintOneSolution(IntVar[] positions, int rows, int cols,
int num_solution) {
Console.WriteLine("Solution {0}", num_solution);
// Create empty board
int[,] board = new int[rows, cols];
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
board[i,j] = 0;
int[, ] board = new int[rows, cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
board[i, j] = 0;
}
}
}
// Fill board with solution value
for(int k = 0; k < rows*cols; k++) {
int position = (int)positions[k].Value();
for (int k = 0; k < rows * cols; k++) {
int position = (int) positions [k]
.Value();
board[position / cols, position % cols] = k + 1;
}
PrintMatrix(board);
}
// Pretty print of the matrix
public static void PrintMatrix(int[,] game)
{
public static void PrintMatrix(int[, ] game) {
int rows = game.GetLength(0);
int cols = game.GetLength(1);
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
if (game[i,j] == 0) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (game[i, j] == 0) {
Console.Write(" .");
} else {
Console.Write(" {0,2}", game[i,j] );
Console.Write(" {0,2}", game[i, j]);
}
}
Console.WriteLine();
@@ -184,10 +165,5 @@ public class Lectures
Console.WriteLine();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,9 +20,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class MagicSequence
{
public class MagicSequence {
/**
*
* Magic sequence problem.
@@ -37,9 +35,7 @@ public class MagicSequence
* """
*
*/
private static void Solve(int size)
{
private static void Solve(int size) {
Solver solver = new Solver("MagicSequence");
Console.WriteLine("\nSize: {0}", size);
@@ -55,7 +51,7 @@ public class MagicSequence
//
// Decision variables
//
IntVar[] all_vars = solver.MakeIntVarArray(size, 0, size - 1, "vars");
IntVar[] all_vars = solver.MakeIntVarArray(size, 0, size - 1, "vars");
//
// Constraints
@@ -63,19 +59,19 @@ public class MagicSequence
solver.Add(all_vars.Distribute(all_values, all_vars));
solver.Add(all_vars.Sum() == size);
//
// Search
//
DecisionBuilder db = solver.MakePhase(all_vars,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(all_vars, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < size; i++) {
Console.Write(all_vars[i].Value() + " ");
for (int i = 0; i < size; i++) {
Console.Write(all_vars [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -86,27 +82,18 @@ public class MagicSequence
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
if (args.Length > 0) {
int size = Convert.ToInt32(args[0]);
Solve(size);
} else {
// Let's test some diferent sizes
foreach(int i in new int[] {2, 10, 100, 200, 500}) {
foreach (int i in new int[]{2, 10, 100, 200, 500}) {
Solve(i);
}
}
}
}

View File

@@ -16,17 +16,14 @@
using System;
using Google.OrTools.ConstraintSolver;
public class MagicSquare
{
public class MagicSquare {
/**
*
* Solves the Magic Square problem.
* See http://www.hakank.org/or-tools/magic_square.py
*
*/
private static void Solve(int n = 4, int num = 0, int print = 1)
{
private static void Solve(int n = 4, int num = 0, int print = 1) {
Solver solver = new Solver("MagicSquare");
Console.WriteLine("n: {0}", n);
@@ -34,11 +31,10 @@ public class MagicSquare
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n*n, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n * n, "x");
// for the branching
IntVar[] x_flat = x.Flatten();
//
// Constraints
//
@@ -47,16 +43,16 @@ public class MagicSquare
IntVar[] diag1 = new IntVar[n];
IntVar[] diag2 = new IntVar[n];
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
IntVar[] row = new IntVar[n];
for(int j = 0; j < n; j++) {
row[j] = x[i,j];
for (int j = 0; j < n; j++) {
row[j] = x[i, j];
}
// sum row to s
solver.Add(row.Sum() == s);
diag1[i] = x[i,i];
diag2[i] = x[i,n - i - 1];
diag1[i] = x[i, i];
diag2[i] = x[i, n - i - 1];
}
// sum diagonals to s
@@ -64,10 +60,10 @@ public class MagicSquare
solver.Add(diag2.Sum() == s);
// sum columns to s
for(int j = 0; j < n; j++) {
for (int j = 0; j < n; j++) {
IntVar[] col = new IntVar[n];
for(int i = 0; i < n; i++) {
col[i] = x[i,j];
for (int i = 0; i < n; i++) {
col[i] = x[i, j];
}
solver.Add(col.Sum() == s);
}
@@ -78,24 +74,23 @@ public class MagicSquare
// symmetry breaking: upper left is 1
// solver.Add(x[0,0] == 1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_CENTER_VALUE);
solver.NewSearch(db);
int c = 0;
while (solver.NextSolution()) {
if (print != 0) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
Console.Write(x[i,j].Value() + " ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write(x [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -114,11 +109,9 @@ public class MagicSquare
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 4;
int num = 0;
int print = 1;

View File

@@ -19,10 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class MagicSquareAndCards
{
public class MagicSquareAndCards {
/**
*
* Magic squares and cards problem.
@@ -37,21 +34,18 @@ public class MagicSquareAndCards
* Also see http://www.hakank.org/or-tools/magic_square_and_cards.py
*
*/
private static void Solve(int n=3)
{
private static void Solve(int n = 3) {
Solver solver = new Solver("MagicSquareAndCards");
IEnumerable<int> RANGE = Enumerable.Range(0, n);
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, 13, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, 13, "x");
IntVar[] x_flat = x.Flatten();
IntVar s = solver.MakeIntVar(1, 13*4, "s");
IntVar s = solver.MakeIntVar(1, 13 * 4, "s");
IntVar[] counts = solver.MakeIntVarArray(14, 0, 4, "counts");
//
@@ -61,22 +55,20 @@ public class MagicSquareAndCards
solver.Add(x_flat.Distribute(counts));
// the standard magic square constraints (sans all_different)
foreach(int i in RANGE) {
foreach (int i in RANGE) {
// rows
solver.Add( (from j in RANGE select x[i,j]).ToArray().Sum() == s);
solver.Add((from j in RANGE select x[i, j]).ToArray().Sum() == s);
// columns
solver.Add( (from j in RANGE select x[j,i]).ToArray().Sum() == s);
solver.Add((from j in RANGE select x[j, i]).ToArray().Sum() == s);
}
// diagonals
solver.Add( (from i in RANGE select x[i,i]).ToArray().Sum() == s);
solver.Add( (from i in RANGE select x[i,n-i-1]).ToArray().Sum() == s);
solver.Add((from i in RANGE select x[i, i]).ToArray().Sum() == s);
solver.Add((from i in RANGE select x[i, n - i - 1]).ToArray().Sum() == s);
// redundant constraint
solver.Add(counts.Sum() == n*n);
solver.Add(counts.Sum() == n * n);
//
// Objective
@@ -86,8 +78,7 @@ public class MagicSquareAndCards
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MAX_VALUE);
solver.NewSearch(db, obj);
@@ -95,13 +86,17 @@ public class MagicSquareAndCards
while (solver.NextSolution()) {
Console.WriteLine("s: {0}", s.Value());
Console.Write("counts:");
for(int i = 0; i < 14; i++) {
Console.Write(counts[i].Value() + " ");
for (int i = 0; i < 14; i++) {
Console.Write(counts [i]
.Value() +
" ");
}
Console.WriteLine();
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
Console.Write(x[i,j].Value() + " ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write(x [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -114,12 +109,9 @@ public class MagicSquareAndCards
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 3;
if (args.Length > 0) {

View File

@@ -16,8 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Map
{
public class Map {
/**
*
* Solves a simple map coloring problem.
@@ -25,19 +24,18 @@ public class Map
* See http://www.hakank.org/google_or_tools/map.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Map");
//
// data
//
int Belgium = 0;
int Denmark = 1;
int France = 2;
int Germany = 3;
int Belgium = 0;
int Denmark = 1;
int France = 2;
int Germany = 3;
int Netherlands = 4;
int Luxembourg = 5;
int Luxembourg = 5;
int n = 6;
int max_num_colors = 4;
@@ -66,15 +64,15 @@ public class Map
//
// Search
//
DecisionBuilder db = solver.MakePhase(color,
Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
Solver.ASSIGN_CENTER_VALUE);
DecisionBuilder db = solver.MakePhase(
color, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_CENTER_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("colors: ");
for(int i = 0; i < n; i++) {
Console.Write("{0} ", color[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", color [i]
.Value());
}
Console.WriteLine();
@@ -86,11 +84,7 @@ public class Map
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,8 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Map2
{
public class Map2 {
/**
*
* Solves a simple map coloring problem.
@@ -29,34 +28,26 @@ public class Map2
*
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Map2");
//
// data
//
int Belgium = 0;
int Denmark = 1;
int France = 2;
int Germany = 3;
int Belgium = 0;
int Denmark = 1;
int France = 2;
int Germany = 3;
int Netherlands = 4;
int Luxembourg = 5;
int Luxembourg = 5;
int n = 6;
int max_num_colors = 4;
int[,] neighbours = {{France, Belgium},
{France, Luxembourg},
{France, Germany},
{Luxembourg, Germany},
{Luxembourg, Belgium},
{Belgium, Netherlands},
{Belgium, Germany},
{Germany, Netherlands},
{Germany, Denmark}};
int[, ] neighbours = {
{France, Belgium}, {France, Luxembourg}, {France, Germany},
{Luxembourg, Germany}, {Luxembourg, Belgium}, {Belgium, Netherlands},
{Belgium, Germany}, {Germany, Netherlands}, {Germany, Denmark}};
//
// Decision variables
@@ -66,26 +57,25 @@ public class Map2
//
// Constraints
//
for(int i = 0; i < neighbours.GetLength(0); i++) {
solver.Add(color[neighbours[i,0]] != color[neighbours[i,1]]);
for (int i = 0; i < neighbours.GetLength(0); i++) {
solver.Add(color[neighbours[i, 0]] != color[neighbours[i, 1]]);
}
// Symmetry breaking
solver.Add(color[Belgium] == 1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(color,
Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
Solver.ASSIGN_CENTER_VALUE);
DecisionBuilder db = solver.MakePhase(
color, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX, Solver.ASSIGN_CENTER_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("colors: ");
for(int i = 0; i < n; i++) {
Console.Write("{0} ", color[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", color [i]
.Value());
}
Console.WriteLine();
@@ -97,11 +87,7 @@ public class Map2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,8 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Marathon2
{
public class Marathon2 {
/**
*
* Marathon puzzle.
@@ -45,28 +44,26 @@ public class Marathon2
* Also see http://www.hakank.org/or-tools/marathon2.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Marathon2");
//
// Data
//
int n = 6;
String[] runners_str = {"Dominique", "Ignace", "Naren",
"Olivier", "Philippe", "Pascal"};
String[] runners_str = {"Dominique", "Ignace", "Naren",
"Olivier", "Philippe", "Pascal"};
//
// Decision variables
//
IntVar[] runners = solver.MakeIntVarArray(n, 1, n, "runners");
IntVar Dominique = runners[0];
IntVar Ignace = runners[1];
IntVar Naren = runners[2];
IntVar Olivier = runners[3];
IntVar Philippe = runners[4];
IntVar Pascal = runners[5];
IntVar Ignace = runners[1];
IntVar Naren = runners[2];
IntVar Olivier = runners[3];
IntVar Philippe = runners[4];
IntVar Pascal = runners[5];
//
// Constraints
@@ -77,50 +74,49 @@ public class Marathon2
solver.Add(Olivier != n);
// b: Dominique, Pascal and Ignace before Naren and Olivier
solver.Add(Dominique < Naren);
solver.Add(Dominique < Olivier);
solver.Add(Pascal < Naren);
solver.Add(Pascal < Olivier);
solver.Add(Ignace < Naren);
solver.Add(Ignace < Olivier);
solver.Add(Dominique < Naren);
solver.Add(Dominique < Olivier);
solver.Add(Pascal < Naren);
solver.Add(Pascal < Olivier);
solver.Add(Ignace < Naren);
solver.Add(Ignace < Olivier);
// c: Dominique better than third
solver.Add(Dominique < 3);
solver.Add(Dominique < 3);
// d: Philippe is among the first four
solver.Add(Philippe <= 4);
solver.Add(Philippe <= 4);
// e: Ignace neither second nor third
solver.Add(Ignace != 2);
solver.Add(Ignace != 3);
solver.Add(Ignace != 2);
solver.Add(Ignace != 3);
// f: Pascal three places earlier than Naren
solver.Add(Pascal + 3 == Naren);
// g: Neither Ignace nor Dominique on fourth position
solver.Add(Ignace != 4);
solver.Add(Dominique != 4);
solver.Add(Ignace != 4);
solver.Add(Dominique != 4);
//
// Search
//
DecisionBuilder db = solver.MakePhase(runners,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_CENTER_VALUE);
DecisionBuilder db = solver.MakePhase(
runners, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_CENTER_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
int[] runners_val = new int[n];
int[] runners_val = new int[n];
Console.Write("runners: ");
for(int i = 0; i < n; i++) {
runners_val[i] = (int)runners[i].Value();
for (int i = 0; i < n; i++) {
runners_val[i] = (int) runners [i]
.Value();
Console.Write(runners_val[i] + " ");
}
Console.WriteLine("\nPlaces:");
for(int i = 1; i < n+1; i++) {
for(int j = 0; j < n; j++) {
for (int i = 1; i < n + 1; i++) {
for (int j = 0; j < n; j++) {
if (runners_val[j] == i) {
Console.WriteLine("{0}: {1}", i, runners_str[j]);
}
@@ -134,11 +130,7 @@ public class Marathon2
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,8 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class MaxFlowTaha
{
public class MaxFlowTaha {
/**
*
* Max flow problem.
@@ -33,38 +32,32 @@ public class MaxFlowTaha
* Also see http://www.hakank.org/or-tools/max_flow_taha.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("MaxFlowTaha");
//
// Data
//
int n = 5;
int n = 5;
int start = 0;
int end = n-1;
int end = n - 1;
IEnumerable<int> NODES = Enumerable.Range(0, n);
// cost matrix
int[,] c = {
{0, 20, 30, 10, 0},
{0, 0, 40, 0, 30},
{0, 0, 0, 10, 20},
{0, 0, 5, 0, 20},
{0, 0, 0, 0, 0}
};
int[, ] c = {{0, 20, 30, 10, 0},
{0, 0, 40, 0, 30},
{0, 0, 0, 10, 20},
{0, 0, 5, 0, 20},
{0, 0, 0, 0, 0}};
//
// Decision variables
//
IntVar[,] x = new IntVar[n,n];
foreach(int i in NODES) {
foreach(int j in NODES) {
x[i,j] = solver.MakeIntVar(0, c[i,j], "x");
IntVar[, ] x = new IntVar[n, n];
foreach (int i in NODES) {
foreach (int j in NODES) {
x[i, j] = solver.MakeIntVar(0, c[i, j], "x");
}
}
@@ -77,49 +70,39 @@ public class MaxFlowTaha
//
// Constraints
//
solver.Add( (from j in NODES
where c[start,j] > 0
select x[start,j]
).ToArray().Sum() == total);
solver.Add((from j in NODES where c[start, j] > 0 select x[start, j])
.ToArray()
.Sum() == total);
foreach(int i in NODES) {
var in_flow_sum = (from j in NODES
where c[j,i] > 0
select x[j,i]
);
foreach (int i in NODES) {
var in_flow_sum = (from j in NODES where c[j, i] > 0 select x[j, i]);
if (in_flow_sum.Count() > 0) {
solver.Add(in_flow_sum.ToArray().Sum() == in_flow[i]);
solver.Add(in_flow_sum.ToArray().Sum() == in_flow[i]);
}
var out_flow_sum = (from j in NODES
where c[i,j] > 0
select x[i,j]
);
var out_flow_sum = (from j in NODES where c[i, j] > 0 select x[i, j]);
if (out_flow_sum.Count() > 0) {
solver.Add(out_flow_sum.ToArray().Sum() == out_flow[i]);
solver.Add(out_flow_sum.ToArray().Sum() == out_flow[i]);
}
}
// in_flow == out_flow
foreach(int i in NODES) {
foreach (int i in NODES) {
if (i != start && i != end) {
solver.Add(out_flow[i] == in_flow[i]);
}
}
var s1 = (from i in NODES where c[i,start] > 0 select x[i,start]);
var s1 = (from i in NODES where c[i, start] > 0 select x[i, start]);
if (s1.Count() > 0) {
solver.Add(s1.ToArray().Sum() == 0);
}
var s2 = (from j in NODES where c[end, j] > 0 select x[end,j]);
var s2 = (from j in NODES where c[end, j] > 0 select x[end, j]);
if (s2.Count() > 0) {
solver.Add(s2.ToArray().Sum() == 0);
}
//
// Objective
//
@@ -128,30 +111,34 @@ public class MaxFlowTaha
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat.Concat(in_flow).Concat(out_flow).ToArray(),
Solver.INT_VAR_DEFAULT,
Solver.ASSIGN_MAX_VALUE);
DecisionBuilder db =
solver.MakePhase(x_flat.Concat(in_flow).Concat(out_flow).ToArray(),
Solver.INT_VAR_DEFAULT, Solver.ASSIGN_MAX_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("total: {0}",total.Value());
Console.WriteLine("total: {0}", total.Value());
Console.Write("in_flow : ");
foreach(int i in NODES) {
Console.Write(in_flow[i].Value() + " ");
foreach (int i in NODES) {
Console.Write(in_flow [i]
.Value() +
" ");
}
Console.Write("\nout_flow: ");
foreach(int i in NODES) {
Console.Write(out_flow[i].Value() + " ");
foreach (int i in NODES) {
Console.Write(out_flow [i]
.Value() +
" ");
}
Console.WriteLine();
foreach(int i in NODES) {
foreach(int j in NODES) {
Console.Write("{0,2} ", x[i,j].Value());
foreach (int i in NODES) {
foreach (int j in NODES) {
Console.Write("{0,2} ", x [i, j]
.Value());
}
Console.WriteLine();
}
Console.WriteLine();
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -160,11 +147,7 @@ public class MaxFlowTaha
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,8 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class MaxFlowWinston1
{
public class MaxFlowWinston1 {
/**
*
* Max flow problem.
@@ -32,99 +31,88 @@ public class MaxFlowWinston1
* Also see http://www.hakank.org/or-tools/max_flow_winston1.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("MaxFlowWinston1");
//
// Data
//
int n = 5;
int n = 5;
IEnumerable<int> NODES = Enumerable.Range(0, n);
// The arcs
// Note:
// This is 1-based to be compatible with other implementations.
//
int[,] arcs1 = {
{1, 2},
{1, 3},
{2, 3},
{2, 4},
{3, 5},
{4, 5},
{5, 1}
};
int[, ] arcs1 = {{1, 2}, {1, 3}, {2, 3}, {2, 4}, {3, 5}, {4, 5}, {5, 1}};
// Capacities
int [] cap = {2,3,3,4,2,1,100};
int[] cap = {2, 3, 3, 4, 2, 1, 100};
// Convert arcs to 0-based
int num_arcs = arcs1.GetLength(0);
IEnumerable<int> ARCS = Enumerable.Range(0, num_arcs);
int[,] arcs = new int[num_arcs, 2];
foreach(int i in ARCS) {
for(int j = 0; j < 2; j++) {
arcs[i,j] = arcs1[i,j] - 1;
int[, ] arcs = new int[num_arcs, 2];
foreach (int i in ARCS) {
for (int j = 0; j < 2; j++) {
arcs[i, j] = arcs1[i, j] - 1;
}
}
// Convert arcs to matrix (for sanity checking below)
int[,] mat = new int[num_arcs, num_arcs];
foreach(int i in NODES) {
foreach(int j in NODES) {
int[, ] mat = new int[num_arcs, num_arcs];
foreach (int i in NODES) {
foreach (int j in NODES) {
int c = 0;
foreach(int k in ARCS) {
if (arcs[k,0] == i && arcs[k,1] == j) {
foreach (int k in ARCS) {
if (arcs[k, 0] == i && arcs[k, 1] == j) {
c = 1;
}
}
mat[i,j] = c;
mat[i, j] = c;
}
}
//
// Decision variables
//
IntVar[,] flow = solver.MakeIntVarMatrix(n, n, 0, 200, "flow");
IntVar z = flow[n-1, 0].VarWithName("z");
IntVar[, ] flow = solver.MakeIntVarMatrix(n, n, 0, 200, "flow");
IntVar z = flow [n - 1, 0]
.VarWithName("z");
//
// Constraints
//
// capacity of arcs
foreach(int i in ARCS) {
solver.Add(flow[arcs[i,0], arcs[i,1]] <= cap[i]);
foreach (int i in ARCS) {
solver.Add(flow[arcs[i, 0], arcs[i, 1]] <= cap[i]);
}
// inflows == outflows
foreach(int i in NODES) {
var s1 = (from k in ARCS
where arcs[k,1] == i
select flow[arcs[k,0], arcs[k,1]]
).ToArray().Sum();
foreach (int i in NODES) {
var s1 = (from k in ARCS where arcs[k, 1] ==
i select flow[arcs[k, 0], arcs[k, 1]])
.ToArray()
.Sum();
var s2 = (from k in ARCS
where arcs[k,0] == i
select flow[arcs[k,0], arcs[k,1]]
).ToArray().Sum();
var s2 = (from k in ARCS where arcs[k, 0] ==
i select flow[arcs[k, 0], arcs[k, 1]])
.ToArray()
.Sum();
solver.Add(s1 == s2);
}
// Sanity check: just arcs with connections can have a flow.
foreach(int i in NODES) {
foreach(int j in NODES) {
if (mat[i,j] == 0) {
solver.Add(flow[i,j] == 0);
foreach (int i in NODES) {
foreach (int j in NODES) {
if (mat[i, j] == 0) {
solver.Add(flow[i, j] == 0);
}
}
}
//
// Objective
//
@@ -133,16 +121,17 @@ public class MaxFlowWinston1
//
// Search
//
DecisionBuilder db = solver.MakePhase(flow.Flatten(),
Solver.INT_VAR_DEFAULT,
Solver.ASSIGN_MAX_VALUE);
DecisionBuilder db = solver.MakePhase(
flow.Flatten(), Solver.INT_VAR_DEFAULT, Solver.ASSIGN_MAX_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("z: {0}",z.Value());
foreach(int i in NODES) {
foreach(int j in NODES) {
Console.Write(flow[i,j].Value() + " ");
Console.WriteLine("z: {0}", z.Value());
foreach (int i in NODES) {
foreach (int j in NODES) {
Console.Write(flow [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -155,11 +144,7 @@ public class MaxFlowWinston1
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,10 +20,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class Minesweeper
{
public class Minesweeper {
static int X = -1;
//
@@ -32,20 +29,16 @@ public class Minesweeper
//
static int default_r = 8;
static int default_c = 8;
static int[,] default_game = {{2, 3, X, 2, 2, X, 2, 1},
{X, X, 4, X, X, 4, X, 2},
{X, X, X, X, X, X, 4, X},
{X, 5, X, 6, X, X, X, 2},
{2, X, X, X, 5, 5, X, 2},
{1, 3, 4, X, X, X, 4, X},
{0, 1, X, 4, X, X, X, 3},
{0, 1, 2, X, 2, 3, X, 2}};
static int[, ] default_game = {
{2, 3, X, 2, 2, X, 2, 1}, {X, X, 4, X, X, 4, X, 2},
{X, X, X, X, X, X, 4, X}, {X, 5, X, 6, X, X, X, 2},
{2, X, X, X, 5, 5, X, 2}, {1, 3, 4, X, X, X, 4, X},
{0, 1, X, 4, X, X, X, 3}, {0, 1, 2, X, 2, 3, X, 2}};
// for the actual problem
static int r;
static int c;
static int[,] game;
static int[, ] game;
/**
*
@@ -54,8 +47,7 @@ public class Minesweeper
* See http://www.hakank.org/google_or_tools/minesweeper.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Minesweeper");
//
@@ -64,10 +56,10 @@ public class Minesweeper
int[] S = {-1, 0, 1};
Console.WriteLine("Problem:");
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
if (game[i,j] > X) {
Console.Write(game[i,j] + " ");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (game[i, j] > X) {
Console.Write(game[i, j] + " ");
} else {
Console.Write("X ");
}
@@ -76,48 +68,40 @@ public class Minesweeper
}
Console.WriteLine();
//
// Decision variables
//
IntVar[,] mines = solver.MakeIntVarMatrix(r, c, 0, 1, "mines");
IntVar[, ] mines = solver.MakeIntVarMatrix(r, c, 0, 1, "mines");
// for branching
IntVar[] mines_flat = mines.Flatten();
//
// Constraints
//
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
if (game[i,j] >= 0) {
solver.Add( mines[i,j] == 0);
//
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (game[i, j] >= 0) {
solver.Add(mines[i, j] == 0);
// this cell is the sum of all its neighbours
var tmp = from a in S from b in S where
i + a >= 0 &&
j + b >= 0 &&
i + a < r &&
j + b < c
select(mines[i+a,j+b]);
solver.Add(tmp.ToArray().Sum() == game[i,j]);
var tmp = from a in S from b in S where i + a >= 0 && j + b >= 0 &&
i + a < r && j + b < c select(mines[i + a, j + b]);
solver.Add(tmp.ToArray().Sum() == game[i, j]);
}
if (game[i,j] > X) {
// This cell cannot be a mine since it
if (game[i, j] > X) {
// This cell cannot be a mine since it
// has some value assigned to it
solver.Add(mines[i,j] == 0);
solver.Add(mines[i, j] == 0);
}
}
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(mines_flat,
Solver.CHOOSE_PATH,
DecisionBuilder db = solver.MakePhase(mines_flat, Solver.CHOOSE_PATH,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
@@ -126,13 +110,14 @@ public class Minesweeper
while (solver.NextSolution()) {
sol++;
Console.WriteLine("Solution #{0} ", sol + " ");
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++){
Console.Write("{0} ", mines[i,j].Value());
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
Console.Write("{0} ", mines [i, j]
.Value());
}
Console.WriteLine();
}
Console.WriteLine();
}
@@ -142,7 +127,6 @@ public class Minesweeper
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
/**
@@ -156,9 +140,9 @@ public class Minesweeper
* <
* row number of neighbours lines...
* >
*
*
* 0..8 means number of neighbours, "." mean unknown (may be a mine)
*
*
* Example (from minesweeper0.txt)
* # Problem from Gecode/examples/minesweeper.cc problem 0
* 6
@@ -172,51 +156,47 @@ public class Minesweeper
*
*/
private static void readFile(String file) {
Console.WriteLine("readFile(" + file + ")");
int lineCount = 0;
TextReader inr = new StreamReader(file);
String str;
while ((str = inr.ReadLine()) != null && str.Length > 0) {
str = str.Trim();
// ignore comments
if(str.StartsWith("#") || str.StartsWith("%")) {
if (str.StartsWith("#") || str.StartsWith("%")) {
continue;
}
Console.WriteLine(str);
if (lineCount == 0) {
r = Convert.ToInt32(str); // number of rows
r = Convert.ToInt32(str); // number of rows
} else if (lineCount == 1) {
c = Convert.ToInt32(str); // number of columns
game = new int[r,c];
c = Convert.ToInt32(str); // number of columns
game = new int[r, c];
} else {
// the problem matrix
String[] row = Regex.Split(str, "");
for(int j = 1; j <= c; j++) {
for (int j = 1; j <= c; j++) {
String s = row[j];
if (s.Equals(".")) {
game[lineCount-2,j-1] = -1;
game[lineCount - 2, j - 1] = -1;
} else {
game[lineCount-2,j-1] = Convert.ToInt32(s);
game[lineCount - 2, j - 1] = Convert.ToInt32(s);
}
}
}
lineCount++;
} // end while
} // end while
inr.Close();
} // end readFile
} // end readFile
public static void Main(String[] args)
{
public static void Main(String[] args) {
String file = "";
if (args.Length > 0) {
file = args[0];

View File

@@ -16,8 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class MrSmith
{
public class MrSmith {
/**
*
* Mr Smith problem.
@@ -34,7 +33,7 @@ public class MrSmith
* o If Matt comes, then John and his father will
* also come.
* """
*
*
* The answer should be:
* Mr_Smith_comes = 0
* Mrs_Smith_comes = 0
@@ -46,8 +45,7 @@ public class MrSmith
* Also see http://www.hakank.org/or-tools/mr_smith.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("MrSmith");
//
@@ -59,12 +57,11 @@ public class MrSmith
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 0, 1, "x");
IntVar Mr_Smith = x[0];
IntVar Mr_Smith = x[0];
IntVar Mrs_Smith = x[1];
IntVar Matt = x[2];
IntVar John = x[3];
IntVar Tim = x[4];
IntVar Matt = x[2];
IntVar John = x[3];
IntVar Tim = x[4];
//
// Constraints
@@ -81,7 +78,7 @@ public class MrSmith
// At least one of their two sons Matt and John will come.
// (Matt \/ John)
solver.Add(Matt+John >= 1);
solver.Add(Matt + John >= 1);
// Either Mrs Smith or Tim will come but not both.
// bool2int(Mrs_Smith) + bool2int(Tim) = 1
@@ -94,22 +91,21 @@ public class MrSmith
// If Matt comes /\ then John and his father will also come.
// (Matt -> (John /\ Mr_Smith))
solver.Add(Matt - (John*Mr_Smith) <= 0);
solver.Add(Matt - (John * Mr_Smith) <= 0);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_CENTER_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine("\n");
Console.WriteLine("Mr Smith : {0}", Mr_Smith.Value());
@@ -117,7 +113,6 @@ public class MrSmith
Console.WriteLine("Matt : {0}", Matt.Value());
Console.WriteLine("John : {0}", John.Value());
Console.WriteLine("Tim : {0}", Tim.Value());
}
Console.WriteLine("\nSolutions: " + solver.Solutions());
@@ -126,11 +121,7 @@ public class MrSmith
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,10 +19,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class NonTransitiveDice
{
public class NonTransitiveDice {
/**
*
* Nontransitive dice.
@@ -43,9 +40,7 @@ public class NonTransitiveDice
*
*
*/
private static void Solve(int m=3, int n=6, int minimize_val=0)
{
private static void Solve(int m = 3, int n = 6, int minimize_val = 0) {
Solver solver = new Solver("Nontransitive_dice");
Console.WriteLine("Number of dice: {0}", m);
@@ -57,26 +52,25 @@ public class NonTransitiveDice
//
// The dice
IntVar[,] dice = solver.MakeIntVarMatrix(m, n, 1, n*2, "dice");
IntVar[, ] dice = solver.MakeIntVarMatrix(m, n, 1, n * 2, "dice");
IntVar[] dice_flat = dice.Flatten();
// For comparison (probability)
IntVar[,] comp = solver.MakeIntVarMatrix(m, 2, 0, n*n, "dice");
IntVar[, ] comp = solver.MakeIntVarMatrix(m, 2, 0, n * n, "dice");
IntVar[] comp_flat = comp.Flatten();
// For branching
IntVar[] all = dice_flat.Concat(comp_flat).ToArray();
// The following variables are for summaries or objectives
IntVar[] gap = solver.MakeIntVarArray(m, 0, n*n, "gap");
IntVar[] gap = solver.MakeIntVarArray(m, 0, n * n, "gap");
IntVar gap_sum = gap.Sum().Var();
IntVar max_val = dice_flat.Max().Var();
IntVar max_win = comp_flat.Max().Var();
// number of occurrences of each value of the dice
IntVar[] counts = solver.MakeIntVarArray(n*2+1, 0, n*m, "counts");
IntVar[] counts = solver.MakeIntVarArray(n * 2 + 1, 0, n * m, "counts");
//
// Constraints
@@ -86,48 +80,50 @@ public class NonTransitiveDice
solver.Add(dice_flat.Distribute(counts));
// Order of the number of each die, lowest first
for(int i = 0; i < m; i++) {
for(int j = 0; j < n-1; j++) {
solver.Add(dice[i,j] <= dice[i,j+1]);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n - 1; j++) {
solver.Add(dice[i, j] <= dice[i, j + 1]);
}
}
// Nontransitivity
for(int i = 0; i < m; i++) {
solver.Add(comp[i,0] > comp[i,1]);
for (int i = 0; i < m; i++) {
solver.Add(comp[i, 0] > comp[i, 1]);
}
// Probability gap
for(int i = 0; i < m; i++) {
solver.Add(gap[i] == comp[i,0] - comp[i,1]);
for (int i = 0; i < m; i++) {
solver.Add(gap[i] == comp[i, 0] - comp[i, 1]);
solver.Add(gap[i] > 0);
}
// And now we roll...
// comp[] is the number of wins for [A vs B, B vs A]
for(int d = 0; d < m; d++) {
IntVar sum1 = ( from r1 in Enumerable.Range(0, n)
from r2 in Enumerable.Range(0, n)
select (dice[d % m, r1] > dice[(d+1) % m, r2])
).ToArray().Sum().Var();
for (int d = 0; d < m; d++) {
IntVar sum1 =
(from r1 in Enumerable.Range(0, n) from r2 in Enumerable.Range(0, n)
select(dice[d % m, r1] > dice[(d + 1) % m, r2]))
.ToArray()
.Sum()
.Var();
solver.Add(comp[d%m,0] == sum1);
solver.Add(comp[d % m, 0] == sum1);
IntVar sum2 = ( from r1 in Enumerable.Range(0, n)
from r2 in Enumerable.Range(0, n)
select (dice[(d+1) % m, r1] > dice[d % m, r2])
).ToArray().Sum().Var();
IntVar sum2 =
(from r1 in Enumerable.Range(0, n) from r2 in Enumerable.Range(0, n)
select(dice[(d + 1) % m, r1] > dice[d % m, r2]))
.ToArray()
.Sum()
.Var();
solver.Add(comp[d%m,1] == sum2);
solver.Add(comp[d % m, 1] == sum2);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(all,
Solver.INT_VAR_DEFAULT,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db =
solver.MakePhase(all, Solver.INT_VAR_DEFAULT, Solver.ASSIGN_MIN_VALUE);
if (minimize_val > 0) {
Console.WriteLine("Minimizing max_val");
@@ -146,29 +142,35 @@ public class NonTransitiveDice
while (solver.NextSolution()) {
Console.WriteLine("gap_sum: {0}", gap_sum.Value());
Console.WriteLine("gap: {0}", (from i in Enumerable.Range(0, m)
select gap[i].Value().ToString()
).ToArray()
);
Console.WriteLine("gap: {0}", (from i in Enumerable
.Range(0, m) select gap [i]
.Value()
.ToString())
.ToArray());
Console.WriteLine("max_val: {0}", max_val.Value());
Console.WriteLine("max_win: {0}", max_win.Value());
Console.WriteLine("dice:");
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
Console.Write(dice[i,j].Value() + " ");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
Console.Write(dice [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
Console.WriteLine("comp:");
for(int i = 0; i < m; i++) {
for(int j = 0; j < 2; j++) {
Console.Write(comp[i,j].Value() + " ");
for (int i = 0; i < m; i++) {
for (int j = 0; j < 2; j++) {
Console.Write(comp [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
Console.WriteLine("counts:");
for(int i = 1; i < n*2+1; i++) {
int c = (int)counts[i].Value();
for (int i = 1; i < n * 2 + 1; i++) {
int c = (int) counts [i]
.Value();
if (c > 0) {
Console.Write("{0}({1}) ", i, c);
}
@@ -182,16 +184,12 @@ public class NonTransitiveDice
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
int m = 3; // number of dice
int n = 6; // number of sides of each die
int minimize_val = 0; // minimizing max_max (0: no, 1: yes)
public static void Main(String[] args) {
int m = 3; // number of dice
int n = 6; // number of sides of each die
int minimize_val = 0; // minimizing max_max (0: no, 1: yes)
if (args.Length > 0) {
m = Convert.ToInt32(args[0]);

View File

@@ -17,37 +17,34 @@ using System;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class NQueens
{
public class NQueens {
/**
*
* Solves the N-Queens problem.
*
* Syntax: nqueens.exe n num print
* where
* where
* n : size of board
* num : number of solutions to calculate
* print: print the results (if > 0)
*
*/
private static void Solve(int n=8, int num=0, int print=1)
{
private static void Solve(int n = 8, int num = 0, int print = 1) {
Solver solver = new Solver("N-Queens");
//
// Decision variables
//
IntVar[] q = solver.MakeIntVarArray(n, 0, n-1, "q");
IntVar[] q = solver.MakeIntVarArray(n, 0, n - 1, "q");
//
// Constraints
//
//
solver.Add(q.AllDifferent());
IntVar[] q1 = new IntVar[n];
IntVar[] q2 = new IntVar[n];
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
q1[i] = (q[i] + i).Var();
q2[i] = (q[i] - i).Var();
}
@@ -66,18 +63,18 @@ public class NQueens
//
// Search
//
DecisionBuilder db = solver.MakePhase(q,
Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
DecisionBuilder db = solver.MakePhase(q, Solver.CHOOSE_MIN_SIZE_LOWEST_MAX,
Solver.ASSIGN_CENTER_VALUE);
solver.NewSearch(db);
int c = 0;
while (solver.NextSolution()) {
if (print > 0) {
for(int i = 0; i < n; i++) {
Console.Write("{0} ", q[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0} ", q [i]
.Value());
}
Console.WriteLine();
}
c++;
@@ -92,11 +89,9 @@ public class NQueens
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 8;
int num = 0;
int print = 1;

View File

@@ -20,10 +20,7 @@ using System.Linq;
using System.Diagnostics;
using Google.OrTools.ConstraintSolver;
public class NurseRostering
{
public class NurseRostering {
/*
* Global constraint regular
*
@@ -46,16 +43,8 @@ public class NurseRostering
* F : accepting states
*
*/
static void MyRegular(Solver solver,
IntVar[] x,
int Q,
int S,
int[,] d,
int q0,
int[] F) {
static void MyRegular(Solver solver, IntVar[] x, int Q, int S, int[, ] d,
int q0, int[] F) {
Debug.Assert(Q > 0, "regular: 'Q' must be greater than zero");
Debug.Assert(S > 0, "regular: 'S' must be greater than zero");
@@ -63,22 +52,25 @@ public class NurseRostering
// each possible input; each extra transition is from state zero
// to state zero. This allows us to continue even if we hit a
// non-accepted input.
int[][] d2 = new int[Q+1][];
for(int i = 0; i <= Q; i++) {
int[][] d2 = new int [Q + 1]
[];
for (int i = 0; i <= Q; i++) {
int[] row = new int[S];
for(int j = 0; j < S; j++) {
for (int j = 0; j < S; j++) {
if (i == 0) {
row[j] = 0;
} else {
row[j] = d[i-1,j];
row[j] = d[i - 1, j];
}
}
d2[i] = row;
}
int[] d2_flatten = (from i in Enumerable.Range(0, Q+1)
from j in Enumerable.Range(0, S)
select d2[i][j]).ToArray();
int[] d2_flatten =
(from i in Enumerable.Range(0, Q + 1) from j in Enumerable.Range(0, S)
select d2 [i]
[j])
.ToArray();
// If x has index set m..n, then a[m-1] holds the initial state
// (q0), and a[i+1] holds the state we're in after processing
@@ -87,23 +79,21 @@ public class NurseRostering
int m = 0;
int n = x.Length;
IntVar[] a = solver.MakeIntVarArray(n+1-m, 0,Q+1, "a");
IntVar[] a = solver.MakeIntVarArray(n + 1 - m, 0, Q + 1, "a");
// Check that the final state is in F
solver.Add(a[a.Length-1].Member(F));
solver.Add(a [a.Length - 1]
.Member(F));
// First state is q0
solver.Add(a[m] == q0);
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
solver.Add(x[i] >= 1);
solver.Add(x[i] <= S);
// Determine a[i+1]: a[i+1] == d2[a[i], x[i]]
solver.Add(a[i+1] == d2_flatten.Element(((a[i])*S)+(x[i]-1)));
solver.Add(a[i + 1] == d2_flatten.Element(((a[i]) * S) + (x[i] - 1)));
}
}
/**
*
* Nurse rostering
@@ -118,8 +108,7 @@ public class NurseRostering
* Also see http://www.hakank.org/or-tools/nurse_rostering.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("NurseRostering");
//
@@ -143,27 +132,27 @@ public class NurseRostering
// the DFA (for regular)
int n_states = 6;
int input_max = 3;
int initial_state = 1; // 0 is for the failing state
int[] accepting_states = {1,2,3,4,5,6};
int initial_state = 1; // 0 is for the failing state
int[] accepting_states = {1, 2, 3, 4, 5, 6};
int[,] transition_fn = {
// d,n,o
{2,3,1}, // state 1
{4,4,1}, // state 2
{4,5,1}, // state 3
{6,6,1}, // state 4
{6,0,1}, // state 5
{0,0,1} // state 6
int[, ] transition_fn = {
// d,n,o
{2, 3, 1}, // state 1
{4, 4, 1}, // state 2
{4, 5, 1}, // state 3
{6, 6, 1}, // state 4
{6, 0, 1}, // state 5
{0, 0, 1} // state 6
};
string[] days = {"d","n","o"}; // for presentation
string[] days = {"d", "n", "o"}; // for presentation
//
// Decision variables
//
// For regular
IntVar[,] x =
IntVar[, ] x =
solver.MakeIntVarMatrix(num_nurses, num_days, valid_shifts, "x");
IntVar[] x_flat = x.Flatten();
@@ -173,38 +162,33 @@ public class NurseRostering
// summary of the shifts per day
int num_shifts = shifts.Length;
IntVar[,] day_stat = new IntVar[num_days, num_shifts];
for(int i = 0; i < num_days; i++) {
for(int j = 0; j < num_shifts; j++) {
day_stat[i,j] = solver.MakeIntVar(0, num_nurses, "day_stat");
IntVar[, ] day_stat = new IntVar[num_days, num_shifts];
for (int i = 0; i < num_days; i++) {
for (int j = 0; j < num_shifts; j++) {
day_stat[i, j] = solver.MakeIntVar(0, num_nurses, "day_stat");
}
}
//
// Constraints
//
for(int i = 0; i < num_nurses; i++) {
for (int i = 0; i < num_nurses; i++) {
IntVar[] reg_input = new IntVar[num_days];
for(int j = 0; j < num_days; j++) {
reg_input[j] = x[i,j];
for (int j = 0; j < num_days; j++) {
reg_input[j] = x[i, j];
}
MyRegular(solver, reg_input, n_states, input_max, transition_fn,
initial_state, accepting_states);
}
//
// Statistics and constraints for each nurse
//
for(int i = 0; i < num_nurses; i++) {
for (int i = 0; i < num_nurses; i++) {
// Number of worked days (either day or night shift)
IntVar[] b = new IntVar[num_days];
for(int j = 0; j < num_days; j++) {
b[j] = ((x[i,j] == day_shift) + (x[i,j] == night_shift)).Var();
for (int j = 0; j < num_days; j++) {
b[j] = ((x[i, j] == day_shift) + (x[i, j] == night_shift)).Var();
}
solver.Add(b.Sum() == nurse_stat[i]);
@@ -212,20 +196,18 @@ public class NurseRostering
// days/nights during this period
solver.Add(nurse_stat[i] >= 7);
solver.Add(nurse_stat[i] <= 10);
}
//
// Statistics and constraints for each day
//
for(int j = 0; j < num_days; j++) {
for(int t = 0; t < num_shifts; t++) {
for (int j = 0; j < num_days; j++) {
for (int t = 0; t < num_shifts; t++) {
IntVar[] b = new IntVar[num_nurses];
for(int i = 0; i < num_nurses; i++) {
b[i] = x[i,j] == t;
for (int i = 0; i < num_nurses; i++) {
b[i] = x[i, j] == t;
}
solver.Add(b.Sum() == day_stat[j,t]);
solver.Add(b.Sum() == day_stat[j, t]);
}
//
@@ -238,27 +220,25 @@ public class NurseRostering
//
if (j % 7 == 5 || j % 7 == 6) {
// special constraints for the weekends
solver.Add(day_stat[j,day_shift] == 2);
solver.Add(day_stat[j,night_shift] == 1);
solver.Add(day_stat[j,off_shift] == 4 );
solver.Add(day_stat[j, day_shift] == 2);
solver.Add(day_stat[j, night_shift] == 1);
solver.Add(day_stat[j, off_shift] == 4);
} else {
// for workdays:
// - exactly 3 on day shift
solver.Add(day_stat[j,day_shift] == 3);
solver.Add(day_stat[j, day_shift] == 3);
// - exactly 2 on night
solver.Add(day_stat[j,night_shift] == 2);
solver.Add(day_stat[j, night_shift] == 2);
// - exactly 2 off duty
solver.Add(day_stat[j,off_shift] == 2 );
solver.Add(day_stat[j, off_shift] == 2);
}
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
@@ -266,11 +246,13 @@ public class NurseRostering
int num_solutions = 0;
while (solver.NextSolution()) {
num_solutions++;
for(int i = 0; i < num_nurses; i++) {
for (int i = 0; i < num_nurses; i++) {
Console.Write("Nurse #{0,-2}: ", i);
var occ = new Dictionary<int, int>();
for(int j = 0; j < num_days; j++) {
int v = (int)x[i,j].Value()-1;
for (int j = 0; j < num_days; j++) {
int v = (int) x [i, j]
.Value() -
1;
if (!occ.ContainsKey(v)) {
occ[v] = 0;
}
@@ -278,24 +260,26 @@ public class NurseRostering
Console.Write(days[v] + " ");
}
Console.Write(" #workdays: {0,2}", nurse_stat[i].Value());
foreach(int s in valid_shifts) {
Console.Write(" #workdays: {0,2}", nurse_stat [i]
.Value());
foreach (int s in valid_shifts) {
int v = 0;
if (occ.ContainsKey(s-1)) {
v = occ[s-1];
if (occ.ContainsKey(s - 1)) {
v = occ[s - 1];
}
Console.Write(" {0}:{1}", days[s-1], v);
Console.Write(" {0}:{1}", days[s - 1], v);
}
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("Statistics per day:\nDay d n o");
for(int j = 0; j < num_days; j++) {
for (int j = 0; j < num_days; j++) {
Console.Write("Day #{0,2}: ", j);
foreach(int t in valid_shifts) {
Console.Write(day_stat[j,t].Value() + " ");
foreach (int t in valid_shifts) {
Console.Write(day_stat [j, t]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -313,11 +297,7 @@ public class NurseRostering
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,9 +20,7 @@ using System.Linq;
using System.Diagnostics;
using Google.OrTools.ConstraintSolver;
public class NurseRostering
{
public class NurseRostering {
/**
*
* Nurse rostering
@@ -40,8 +38,7 @@ public class NurseRostering
* which use (a decomposition of) regular constraint
*
*/
private static void Solve(int nurse_multiplier, int week_multiplier)
{
private static void Solve(int nurse_multiplier, int week_multiplier) {
Console.WriteLine("Starting Nurse Rostering");
Console.WriteLine(" - {0} teams of 7 nurses", nurse_multiplier);
Console.WriteLine(" - {0} blocks of 14 days", week_multiplier);
@@ -68,7 +65,7 @@ public class NurseRostering
// the DFA (for regular)
int initial_state = 1;
int[] accepting_states = {1,2,3,4,5,6};
int[] accepting_states = {1, 2, 3, 4, 5, 6};
/*
// This is the transition function
@@ -87,24 +84,14 @@ public class NurseRostering
// For TransitionConstraint
IntTupleSet transition_tuples = new IntTupleSet(3);
// state, input, next state
transition_tuples.InsertAll(new long[][] {
new long[] {1,1,2},
new long[] {1,2,3},
new long[] {1,3,1},
new long[] {2,1,4},
new long[] {2,2,4},
new long[] {2,3,1},
new long[] {3,1,4},
new long[] {3,2,5},
new long[] {3,3,1},
new long[] {4,1,6},
new long[] {4,2,6},
new long[] {4,3,1},
new long[] {5,1,6},
new long[] {5,3,1},
new long[] {6,3,1} });
transition_tuples.InsertAll(new long[][]{
new long[]{1, 1, 2}, new long[]{1, 2, 3}, new long[]{1, 3, 1},
new long[]{2, 1, 4}, new long[]{2, 2, 4}, new long[]{2, 3, 1},
new long[]{3, 1, 4}, new long[]{3, 2, 5}, new long[]{3, 3, 1},
new long[]{4, 1, 6}, new long[]{4, 2, 6}, new long[]{4, 3, 1},
new long[]{5, 1, 6}, new long[]{5, 3, 1}, new long[]{6, 3, 1}});
string[] days = {"d","n","o"}; // for presentation
string[] days = {"d", "n", "o"}; // for presentation
//
// Decision variables
@@ -113,7 +100,7 @@ public class NurseRostering
//
// For TransitionConstraint
//
IntVar[,] x =
IntVar[, ] x =
solver.MakeIntVarMatrix(num_nurses, num_days, valid_shifts, "x");
IntVar[] x_flat = x.Flatten();
@@ -126,37 +113,35 @@ public class NurseRostering
// summary of the shifts per day
//
int num_shifts = shifts.Length;
IntVar[,] day_stat = new IntVar[num_days, num_shifts];
for(int i = 0; i < num_days; i++) {
for(int j = 0; j < num_shifts; j++) {
day_stat[i,j] = solver.MakeIntVar(0, num_nurses, "day_stat");
IntVar[, ] day_stat = new IntVar[num_days, num_shifts];
for (int i = 0; i < num_days; i++) {
for (int j = 0; j < num_shifts; j++) {
day_stat[i, j] = solver.MakeIntVar(0, num_nurses, "day_stat");
}
}
//
// Constraints
//
for(int i = 0; i < num_nurses; i++) {
for (int i = 0; i < num_nurses; i++) {
IntVar[] reg_input = new IntVar[num_days];
for(int j = 0; j < num_days; j++) {
reg_input[j] = x[i,j];
for (int j = 0; j < num_days; j++) {
reg_input[j] = x[i, j];
}
solver.Add(reg_input.Transition(transition_tuples,
initial_state,
solver.Add(reg_input.Transition(transition_tuples, initial_state,
accepting_states));
}
//
// Statistics and constraints for each nurse
//
for(int nurse = 0; nurse < num_nurses; nurse++) {
for (int nurse = 0; nurse < num_nurses; nurse++) {
// Number of worked days (either day or night shift)
IntVar[] nurse_days = new IntVar[num_days];
for(int day = 0; day < num_days; day++) {
nurse_days[day] =
x[nurse, day].IsMember(new int[] { day_shift, night_shift });
for (int day = 0; day < num_days; day++) {
nurse_days[day] = x [nurse, day]
.IsMember(new int[]{day_shift, night_shift});
}
nurse_stat[nurse] = nurse_days.Sum().Var();
@@ -164,20 +149,18 @@ public class NurseRostering
// days/nights during this period
solver.Add(nurse_stat[nurse] >= 7 * week_multiplier / nurse_multiplier);
solver.Add(nurse_stat[nurse] <= 10 * week_multiplier / nurse_multiplier);
}
//
// Statistics and constraints for each day
//
for(int day = 0; day < num_days; day++) {
for (int day = 0; day < num_days; day++) {
IntVar[] nurses = new IntVar[num_nurses];
for(int nurse = 0; nurse < num_nurses; nurse++) {
for (int nurse = 0; nurse < num_nurses; nurse++) {
nurses[nurse] = x[nurse, day];
}
IntVar[] stats = new IntVar[num_shifts];
for (int shift = 0; shift < num_shifts; ++shift)
{
for (int shift = 0; shift < num_shifts; ++shift) {
stats[shift] = day_stat[day, shift];
}
solver.Add(nurses.Distribute(stats));
@@ -210,8 +193,7 @@ public class NurseRostering
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
SearchMonitor log = solver.MakeSearchLog(1000000);
@@ -221,11 +203,13 @@ public class NurseRostering
int num_solutions = 0;
while (solver.NextSolution()) {
num_solutions++;
for(int i = 0; i < num_nurses; i++) {
for (int i = 0; i < num_nurses; i++) {
Console.Write("Nurse #{0,-2}: ", i);
var occ = new Dictionary<int, int>();
for(int j = 0; j < num_days; j++) {
int v = (int)x[i,j].Value()-1;
for (int j = 0; j < num_days; j++) {
int v = (int) x [i, j]
.Value() -
1;
if (!occ.ContainsKey(v)) {
occ[v] = 0;
}
@@ -233,24 +217,26 @@ public class NurseRostering
Console.Write(days[v] + " ");
}
Console.Write(" #workdays: {0,2}", nurse_stat[i].Value());
foreach(int s in valid_shifts) {
Console.Write(" #workdays: {0,2}", nurse_stat [i]
.Value());
foreach (int s in valid_shifts) {
int v = 0;
if (occ.ContainsKey(s-1)) {
v = occ[s-1];
if (occ.ContainsKey(s - 1)) {
v = occ[s - 1];
}
Console.Write(" {0}:{1}", days[s-1], v);
Console.Write(" {0}:{1}", days[s - 1], v);
}
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine("Statistics per day:\nDay d n o");
for(int j = 0; j < num_days; j++) {
for (int j = 0; j < num_days; j++) {
Console.Write("Day #{0,2}: ", j);
foreach(int t in valid_shifts) {
Console.Write(day_stat[j,t].Value() + " ");
foreach (int t in valid_shifts) {
Console.Write(day_stat [j, t]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -268,11 +254,9 @@ public class NurseRostering
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int nurse_multiplier = 1;
int week_multiplier = 1;
if (args.Length > 0) {

View File

@@ -16,23 +16,15 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Olympic
{
public static void minus(Solver solver,
IntVar x,
IntVar y,
IntVar z)
{
public class Olympic {
public static void minus(Solver solver, IntVar x, IntVar y, IntVar z) {
solver.Add(z == (x - y).Abs());
}
/**
*
* Olympic puzzle.
*
*
* Benchmark for Prolog (BProlog)
* """
* File : olympic.pl
@@ -66,8 +58,7 @@ public class Olympic
* Also see http://www.hakank.org/or-tools/olympic.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Olympic");
//
@@ -79,18 +70,17 @@ public class Olympic
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x");
IntVar X1 = x[0];
IntVar X2 = x[1];
IntVar X3 = x[2];
IntVar X4 = x[3];
IntVar X5 = x[4];
IntVar X6 = x[5];
IntVar X7 = x[6];
IntVar X8 = x[7];
IntVar X9 = x[8];
IntVar X1 = x[0];
IntVar X2 = x[1];
IntVar X3 = x[2];
IntVar X4 = x[3];
IntVar X5 = x[4];
IntVar X6 = x[5];
IntVar X7 = x[6];
IntVar X8 = x[7];
IntVar X9 = x[8];
IntVar X10 = x[9];
//
// Constraints
//
@@ -104,19 +94,18 @@ public class Olympic
minus(solver, X8, X9, X5);
minus(solver, X9, X10, X6);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_SIMPLE,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
Console.Write("{0,2} ", x[i].Value());
for (int i = 0; i < n; i++) {
Console.Write("{0,2} ", x [i]
.Value());
}
Console.WriteLine();
}
@@ -127,11 +116,7 @@ public class Olympic
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -20,23 +20,15 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class OrganizeDay
{
public class OrganizeDay {
//
// No overlapping of tasks s1 and s2
//
public static void NoOverlap(Solver solver,
IntVar s1, int d1,
IntVar s2, int d2)
{
public static void NoOverlap(Solver solver, IntVar s1, int d1, IntVar s2,
int d2) {
solver.Add((s1 + d1 <= s2) + (s2 + d2 <= s1) == 1);
}
/**
*
*
@@ -52,31 +44,24 @@ public class OrganizeDay
* Also see http://www.hakank.org/google_or_tools/organize_day.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("OrganizeDay");
int n = 4;
int work = 0;
int mail = 1;
int shop = 2;
int bank = 3;
int[] tasks = {work, mail, shop, bank};
int[] durations = {4,1,2,1};
int[] durations = {4, 1, 2, 1};
// task [i,0] must be finished before task [i,1]
int[,] before_tasks = {
{bank, shop},
{mail, work}
};
int[, ] before_tasks = {{bank, shop}, {mail, work}};
// the valid times of the day
int begin = 9;
int end = 17;
int end = 17;
//
// Decision variables
@@ -87,46 +72,41 @@ public class OrganizeDay
//
// Constraints
//
foreach(int t in tasks) {
foreach (int t in tasks) {
solver.Add(ends[t] == begins[t] + durations[t]);
}
foreach(int i in tasks) {
foreach(int j in tasks) {
foreach (int i in tasks) {
foreach (int j in tasks) {
if (i < j) {
NoOverlap(solver,
begins[i], durations[i],
begins[j], durations[j]);
NoOverlap(solver, begins[i], durations[i], begins[j], durations[j]);
}
}
}
// specific constraints
for(int t = 0; t < before_tasks.GetLength(0); t++) {
solver.Add(ends[before_tasks[t,0]] <= begins[before_tasks[t,1]]);
for (int t = 0; t < before_tasks.GetLength(0); t++) {
solver.Add(ends[before_tasks[t, 0]] <= begins[before_tasks[t, 1]]);
}
solver.Add(begins[work] >= 11);
//
// Search
//
DecisionBuilder db = solver.MakePhase(begins,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(begins, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
foreach(int t in tasks) {
Console.WriteLine("Task {0}: {1,2} .. ({2}) .. {3,2}",
t,
begins[t].Value(),
foreach (int t in tasks) {
Console.WriteLine("Task {0}: {1,2} .. ({2}) .. {3,2}", t,
begins [t]
.Value(),
durations[t],
ends[t].Value());
ends [t]
.Value());
}
Console.WriteLine();
}
@@ -137,12 +117,7 @@ public class OrganizeDay
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -18,8 +18,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class OrganizeDay
{
public class OrganizeDay {
/**
*
*
@@ -35,47 +34,34 @@ public class OrganizeDay
* Also see http://www.hakank.org/google_or_tools/organize_day.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("OrganizeDayIntervals");
int n = 4;
int work = 0;
int mail = 1;
int shop = 2;
int bank = 3;
// the valid times of the day
int begin = 9;
int end = 17;
int end = 17;
// tasks
int[] tasks = {work, mail, shop, bank};
// durations
int[] durations = {4,1,2,1};
int[] durations = {4, 1, 2, 1};
// Arrays for interval variables.
int[] starts_max = { begin,begin,begin,begin };
int[] ends_max = { end -4, end - 1, end - 2, end - 1 };
int[] starts_max = {begin, begin, begin, begin};
int[] ends_max = {end - 4, end - 1, end - 2, end - 1};
// task [i,0] must be finished before task [i,1]
int[,] before_tasks = {
{bank, shop},
{mail, work}
};
int[, ] before_tasks = {{bank, shop}, {mail, work}};
//
// Decision variables
//
IntervalVar[] intervals =
solver.MakeFixedDurationIntervalVarArray(n,
starts_max,
ends_max,
durations,
false,
"task");
IntervalVar[] intervals = solver.MakeFixedDurationIntervalVarArray(
n, starts_max, ends_max, durations, false, "task");
//
// Constraints
//
@@ -83,26 +69,29 @@ public class OrganizeDay
solver.Add(disjunctive);
// specific constraints
for(int t = 0; t < before_tasks.GetLength(0); t++) {
for (int t = 0; t < before_tasks.GetLength(0); t++) {
int before = before_tasks[t, 0];
int after = before_tasks[t, 1];
solver.Add(intervals[after].StartsAfterEnd(intervals[before]));
solver.Add(intervals [after]
.StartsAfterEnd(intervals[before]));
}
solver.Add(intervals[work].StartsAfter(11));
solver.Add(intervals [work]
.StartsAfter(11));
//
// Search
//
SequenceVar var = disjunctive.SequenceVar();
SequenceVar[] seq_array = new SequenceVar[] { var };
SequenceVar[] seq_array = new SequenceVar[]{var};
DecisionBuilder db = solver.MakePhase(seq_array, Solver.SEQUENCE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
foreach(int t in tasks) {
Console.WriteLine(intervals[t].ToString());
foreach (int t in tasks) {
Console.WriteLine(intervals [t]
.ToString());
}
Console.WriteLine();
}
@@ -113,12 +102,7 @@ public class OrganizeDay
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,8 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class PMedian
{
public class PMedian {
/**
*
* P-median problem.
@@ -38,9 +37,7 @@ public class PMedian
* Also see http://www.hakank.org/or-tools/p_median.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("PMedian");
//
@@ -53,44 +50,38 @@ public class PMedian
int num_warehouses = 3;
IEnumerable<int> WAREHOUSES = Enumerable.Range(0, num_warehouses);
int[] demand = {100,80,80,70};
int [,] distance = {
{ 2, 10, 50},
{ 2, 10, 52},
{50, 60, 3},
{40, 60, 1}
};
int[] demand = {100, 80, 80, 70};
int[, ] distance = {{2, 10, 50}, {2, 10, 52}, {50, 60, 3}, {40, 60, 1}};
//
// Decision variables
//
IntVar[] open = solver.MakeIntVarArray(num_warehouses, 0, num_warehouses, "open");
IntVar[,] ship = solver.MakeIntVarMatrix(num_customers, num_warehouses,
0, 1, "ship");
IntVar[] open =
solver.MakeIntVarArray(num_warehouses, 0, num_warehouses, "open");
IntVar[, ] ship =
solver.MakeIntVarMatrix(num_customers, num_warehouses, 0, 1, "ship");
IntVar z = solver.MakeIntVar(0, 1000, "z");
//
// Constraints
//
solver.Add((from c in CUSTOMERS
from w in WAREHOUSES
select (demand[c]*distance[c,w]*ship[c,w])
).ToArray().Sum() == z);
solver.Add((from c in CUSTOMERS from w in WAREHOUSES select(
demand[c] * distance[c, w] * ship[c, w]))
.ToArray()
.Sum() == z);
solver.Add(open.Sum() == p);
foreach(int c in CUSTOMERS) {
foreach(int w in WAREHOUSES) {
solver.Add(ship[c,w] <= open[w]);
foreach (int c in CUSTOMERS) {
foreach (int w in WAREHOUSES) {
solver.Add(ship[c, w] <= open[w]);
}
solver.Add((from w in WAREHOUSES select ship[c,w]).ToArray().Sum() == 1);
solver.Add((from w in WAREHOUSES select ship[c, w]).ToArray().Sum() == 1);
}
//
// Objective
//
@@ -99,22 +90,26 @@ public class PMedian
//
// Search
//
DecisionBuilder db = solver.MakePhase(open.Concat(ship.Flatten()).ToArray(),
Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db =
solver.MakePhase(open.Concat(ship.Flatten()).ToArray(),
Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("z: {0}",z.Value());
Console.WriteLine("z: {0}", z.Value());
Console.Write("open:");
foreach(int w in WAREHOUSES) {
Console.Write(open[w].Value() + " ");
foreach (int w in WAREHOUSES) {
Console.Write(open [w]
.Value() +
" ");
}
Console.WriteLine();
foreach(int c in CUSTOMERS) {
foreach(int w in WAREHOUSES) {
Console.Write(ship[c,w].Value()+ " ");
foreach (int c in CUSTOMERS) {
foreach (int w in WAREHOUSES) {
Console.Write(ship [c, w]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -127,11 +122,7 @@ public class PMedian
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,9 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class PandigitalNumbers
{
public class PandigitalNumbers {
/**
*
* toNum(solver, a, num, base)
@@ -29,18 +27,15 @@ public class PandigitalNumbers
* channelling between the array a and the number num.
*
*/
private static Constraint ToNum(IntVar[] a,
IntVar num,
int bbase) {
private static Constraint ToNum(IntVar[] a, IntVar num, int bbase) {
int len = a.Length;
IntVar[] tmp = new IntVar[len];
for(int i = 0; i < len; i++) {
tmp[i] = (a[i]*(int)Math.Pow(bbase,len-i-1)).Var();
for (int i = 0; i < len; i++) {
tmp[i] = (a[i] * (int) Math.Pow(bbase, len - i - 1)).Var();
}
return tmp.Sum() == num;
}
/**
*
* Pandigital numbers in Google CP Solver.
@@ -80,63 +75,59 @@ public class PandigitalNumbers
* Also see http://www.hakank.org/or-tools/pandigital_numbers.py
*
*/
private static void Solve(int bbase=10, int start=1, int len1=1, int len2=4)
{
private static void Solve(int bbase = 10, int start = 1, int len1 = 1,
int len2 = 4) {
Solver solver = new Solver("PandigitalNumbers");
//
// Data
//
int max_d = bbase-1;
int x_len = max_d + 1 - start;
int max_num = (int)Math.Pow(bbase,4)-1;
int max_d = bbase - 1;
int x_len = max_d + 1 - start;
int max_num = (int) Math.Pow(bbase, 4) - 1;
//
// Decision variables
//
IntVar num1 = solver.MakeIntVar(1, max_num, "num1");
IntVar num2 = solver.MakeIntVar(1, max_num, "num2");
IntVar res = solver.MakeIntVar(1, max_num, "res");
IntVar res = solver.MakeIntVar(1, max_num, "res");
IntVar[] x = solver.MakeIntVarArray(x_len, start, max_d, "x");
// for labeling
IntVar[] all = new IntVar[x_len+3];
for(int i = 0; i < x_len; i++) {
IntVar[] all = new IntVar[x_len + 3];
for (int i = 0; i < x_len; i++) {
all[i] = x[i];
}
all[x_len] = num1;
all[x_len+1] = num2;
all[x_len+2] = res;
all[x_len] = num1;
all[x_len + 1] = num2;
all[x_len + 2] = res;
//
// Constraints
//
solver.Add(x.AllDifferent());
solver.Add(ToNum(( from i in Enumerable.Range(0, len1)
select x[i]).ToArray(),
num1,
bbase));
solver.Add(
ToNum((from i in Enumerable.Range(0, len1) select x[i]).ToArray(), num1,
bbase));
solver.Add(ToNum(( from i in Enumerable.Range(len1, len2)
select x[i]).ToArray(),
num2,
bbase));
solver.Add(
ToNum((from i in Enumerable.Range(len1, len2) select x[i]).ToArray(),
num2, bbase));
solver.Add(ToNum(( from i in Enumerable.Range(len1+len2, x_len-(len1+len2))
select x[i]).ToArray(),
res,
bbase));
solver.Add(ToNum((from i in Enumerable.Range(
len1 + len2, x_len - (len1 + len2)) select x[i])
.ToArray(),
res, bbase));
solver.Add(num1*num2 == res);
solver.Add(num1 * num2 == res);
// no number must start with 0
solver.Add(x[0] > 0);
solver.Add(x[len1] > 0);
solver.Add(x[len1+len2] > 0);
solver.Add(x[len1 + len2] > 0);
// symmetry breaking
solver.Add(num1 < num2);
@@ -144,14 +135,14 @@ public class PandigitalNumbers
//
// Search
//
DecisionBuilder db = solver.MakePhase(all,
Solver.INT_VAR_SIMPLE,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(all, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.WriteLine("{0} * {1} = {2}", num1.Value(), num2.Value(), res.Value());
Console.WriteLine("{0} * {1} = {2}", num1.Value(), num2.Value(),
res.Value());
}
/*
@@ -162,32 +153,27 @@ public class PandigitalNumbers
*/
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int bbase = 10;
int start = 1;
if(args.Length > 0) {
if (args.Length > 0) {
bbase = Convert.ToInt32(args[0]);
}
if(args.Length > 1) {
if (args.Length > 1) {
start = Convert.ToInt32(args[1]);
}
int x_len = bbase - 1 + 1-start;
for(int len1 = 0; len1 <= x_len; len1++) {
for(int len2 = 0; len2 <= x_len; len2++) {
if (x_len > len1 + len2
&& len1 > 0 && len2 > 0
) {
int x_len = bbase - 1 + 1 - start;
for (int len1 = 0; len1 <= x_len; len1++) {
for (int len2 = 0; len2 <= x_len; len2++) {
if (x_len > len1 + len2 && len1 > 0 && len2 > 0) {
Solve(bbase, start, len1, len2);
}
}
}
}
}

View File

@@ -19,9 +19,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class Partition
{
public class Partition {
/**
*
* This is a port of Charles Prud'homme's Java model
@@ -34,23 +32,19 @@ public class Partition
* """
*
*/
private static void Solve(int m)
{
private static void Solve(int m) {
Solver solver = new Solver("Partition");
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(m, 1, 2 * m, "x");
IntVar[] y = solver.MakeIntVarArray(m, 1, 2 * m, "y");
//
// Constraints
//
// break symmetries
// break symmetries
for (int i = 0; i < m - 1; i++) {
solver.Add(x[i] < x[i + 1]);
solver.Add(y[i] < y[i + 1]);
@@ -77,9 +71,13 @@ public class Partition
sx = new IntVar[m];
sy = new IntVar[m];
for (int i = m - 1; i >= 0; i--) {
sx[i] = x[i].Square().Var();
sx[i] = x [i]
.Square()
.Var();
sxy[i] = sx[i];
sy[i] = y[i].Square().Var();
sy[i] = y [i]
.Square()
.Var();
sxy[m + i] = sy[i];
}
solver.Add(sxy.ScalProd(coeffs) == 0);
@@ -98,12 +96,18 @@ public class Partition
solver.NewSearch(db, log);
while (solver.NextSolution()) {
for(int i = 0; i < m; i++) {
Console.Write("[" + xy[i].Value() + "] ");
for (int i = 0; i < m; i++) {
Console.Write("[" +
xy [i]
.Value() +
"] ");
}
Console.WriteLine();
for(int i = 0; i < m; i++) {
Console.Write("[" + xy[m+i].Value() + "] ");
for (int i = 0; i < m; i++) {
Console.Write("[" +
xy [m + i]
.Value() +
"] ");
}
Console.WriteLine("\n");
}
@@ -114,12 +118,9 @@ public class Partition
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int m = 32;
if (args.Length > 0) {
m = Convert.ToInt32(args[0]);

View File

@@ -19,10 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class PerfectSquareSequence
{
public class PerfectSquareSequence {
/**
*
* Perfect square sequence.
@@ -31,17 +28,18 @@ public class PerfectSquareSequence
* "Sequence"
* http://benvitale-funwithnum3ers.blogspot.com/2010/11/sequence.html
* """
* If we take the numbers from 1 to 15
* (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
* and rearrange them in such an order that any two consecutive
* If we take the numbers from 1 to 15
* (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
* and rearrange them in such an order that any two consecutive
* numbers in the sequence add up to a perfect square, we get,
*
* 8 1 15 10 6 3 13 12 4 5 11 14 2 7 9
* 9 16 25 16 9 16 25 16 9 16 25 16 9 16
*
*
* 8 1 15 10 6 3 13 12 4 5 11 14 2
* 7 9 9 16 25 16 9 16 25 16 9 16 25 16
* 9 16
*
*
* I ask the readers the following:
*
*
* Can you take the numbers from 1 to 25 to produce such an arrangement?
* How about the numbers from 1 to 100?
* """
@@ -49,20 +47,19 @@ public class PerfectSquareSequence
* Via http://wildaboutmath.com/2010/11/26/wild-about-math-bloggers-111910
*
*
* Also see http://www.hakank.org/or-tools/perfect_square_sequence.py
* Also see http://www.hakank.org/or-tools/perfect_square_sequence.py
*
*/
private static int Solve(int n = 15, int print_solutions=1, int show_num_sols=0)
{
private static int Solve(int n = 15, int print_solutions = 1,
int show_num_sols = 0) {
Solver solver = new Solver("PerfectSquareSequence");
IEnumerable<int> RANGE = Enumerable.Range(0, n);
// create the table of possible squares
int[] squares = new int[n-1];
for(int i = 1; i < n; i++) {
squares[i-1] = i*i;
int[] squares = new int[n - 1];
for (int i = 1; i < n; i++) {
squares[i - 1] = i * i;
}
//
@@ -70,26 +67,23 @@ public class PerfectSquareSequence
//
IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x");
//
// Constraints
//
solver.Add(x.AllDifferent());
for(int i = 1; i < n; i++) {
solver.Add((x[i-1]+x[i]).Member(squares));
for (int i = 1; i < n; i++) {
solver.Add((x[i - 1] + x[i]).Member(squares));
}
// symmetry breaking
solver.Add(x[0] < x[n-1]);
solver.Add(x[0] < x[n - 1]);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
@@ -99,8 +93,10 @@ public class PerfectSquareSequence
num_solutions++;
if (print_solutions > 0) {
Console.Write("x: ");
foreach(int i in RANGE) {
Console.Write(x[i].Value() + " ");
foreach (int i in RANGE) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -114,28 +110,26 @@ public class PerfectSquareSequence
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
Console.WriteLine("WallTime: {0}ms", solver.WallTime());
Console.WriteLine("Failures: {0}", solver.Failures());
Console.WriteLine("Branches: {0} ", solver.Branches());
Console.WriteLine("Branches: {0} ", solver.Branches());
}
solver.EndSearch();
return num_solutions;
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 15;
if (args.Length > 0) {
n = Convert.ToInt32(args[0]);
}
if (n == 0) {
for(int i = 2; i < 100; i++) {
for (int i = 2; i < 100; i++) {
int num_solutions = Solve(i, 0, 0);
Console.WriteLine("{0}: {1} solution(s)", i, num_solutions);
}
} else {
int num_solutions = Solve(n);
Console.WriteLine("{0}: {1} solution(s)", n, num_solutions);

View File

@@ -19,11 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class PhotoProblem
{
public class PhotoProblem {
/**
*
* Photo problem.
@@ -45,35 +41,34 @@ public class PhotoProblem
* """
*
* Oz solution:
* 6 # alignment(betty:5 chris:6 donald:1 fred:3 gary:7 mary:4 paul:2)
* [5, 6, 1, 3, 7, 4, 2]
* 6 # alignment(betty:5 chris:6 donald:1 fred:3 gary:7 mary:4
* paul:2) [5, 6, 1, 3, 7, 4, 2]
*
*
* Also see http://www.hakank.org/or-tools/photo_problem.py
*
*/
private static void Solve(int show_all_max=0)
{
private static void Solve(int show_all_max = 0) {
Solver solver = new Solver("PhotoProblem");
//
// Data
//
String[] persons = {"Betty", "Chris", "Donald", "Fred", "Gary", "Mary", "Paul"};
String[] persons = {"Betty", "Chris", "Donald", "Fred",
"Gary", "Mary", "Paul"};
int n = persons.Length;
IEnumerable<int> RANGE = Enumerable.Range(0, n);
int[,] preferences = {
// 0 1 2 3 4 5 6
// B C D F G M P
{ 0,0,0,0,1,1,0 }, // Betty 0
{ 1,0,0,0,1,0,0 }, // Chris 1
{ 0,0,0,0,0,0,0 }, // Donald 2
{ 0,0,1,0,0,1,0 }, // Fred 3
{ 0,0,0,0,0,0,0 }, // Gary 4
{ 0,0,0,0,0,0,0 }, // Mary 5
{ 0,0,1,1,0,0,0 } // Paul 6
int[, ] preferences = {
// 0 1 2 3 4 5 6
// B C D F G M P
{0, 0, 0, 0, 1, 1, 0}, // Betty 0
{1, 0, 0, 0, 1, 0, 0}, // Chris 1
{0, 0, 0, 0, 0, 0, 0}, // Donald 2
{0, 0, 1, 0, 0, 1, 0}, // Fred 3
{0, 0, 0, 0, 0, 0, 0}, // Gary 4
{0, 0, 0, 0, 0, 0, 0}, // Mary 5
{0, 0, 1, 1, 0, 0, 0} // Paul 6
};
Console.WriteLine("Preferences:");
@@ -82,13 +77,12 @@ public class PhotoProblem
Console.WriteLine("3. Fred wants to stand next to Mary and Donald.");
Console.WriteLine("4. Paul wants to stand next to Fred and Donald.\n");
//
// Decision variables
//
IntVar[] positions = solver.MakeIntVarArray(n, 0, n-1, "positions");
IntVar[] positions = solver.MakeIntVarArray(n, 0, n - 1, "positions");
// successful preferences (to Maximize)
IntVar z = solver.MakeIntVar(0, n*n, "z");
IntVar z = solver.MakeIntVar(0, n * n, "z");
//
// Constraints
@@ -96,18 +90,16 @@ public class PhotoProblem
solver.Add(positions.AllDifferent());
// calculate all the successful preferences
solver.Add( ( from i in RANGE
from j in RANGE
where preferences[i,j] == 1
select (positions[i] - positions[j]).Abs() == 1
).ToArray().Sum() == z);
solver.Add((from i in RANGE from j in RANGE where preferences[i, j] ==
1 select(positions[i] - positions[j]).Abs() == 1)
.ToArray()
.Sum() == z);
//
// Symmetry breaking (from the Oz page):
// Fred is somewhere left of Betty
solver.Add(positions[3] < positions[0]);
//
// Objective
//
@@ -118,13 +110,11 @@ public class PhotoProblem
solver.Add(z == 6);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(positions,
Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MAX_VALUE);
DecisionBuilder db = solver.MakePhase(
positions, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE);
solver.NewSearch(db, obj);
@@ -132,13 +122,14 @@ public class PhotoProblem
Console.WriteLine("z: {0}", z.Value());
int[] p = new int[n];
Console.Write("p: ");
for(int i = 0; i < n; i++) {
p[i] = (int)positions[i].Value();
for (int i = 0; i < n; i++) {
p[i] = (int) positions [i]
.Value();
Console.Write(p[i] + " ");
}
Console.WriteLine();
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (p[j] == i) {
Console.Write(persons[j] + " ");
}
@@ -146,10 +137,9 @@ public class PhotoProblem
}
Console.WriteLine();
Console.WriteLine("Successful preferences:");
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if (preferences[i,j] == 1 &&
Math.Abs(p[i]-p[j])==1) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (preferences[i, j] == 1 && Math.Abs(p[i] - p[j]) == 1) {
Console.WriteLine("\t{0} {1}", persons[i], persons[j]);
}
}
@@ -163,11 +153,9 @@ public class PhotoProblem
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int show_all_max = 0;
if (args.Length > 0) {
show_all_max = Convert.ToInt32(args[0]);

View File

@@ -19,13 +19,12 @@ using System.Collections;
using System.Collections.Generic;
using Google.OrTools.ConstraintSolver;
public class PlaceNumberPuzzle
{
public class PlaceNumberPuzzle {
/**
*
* Place number puzzle.
*
* From
*
* From
* http://ai.uwaterloo.ca/~vanbeek/Courses/Slides/introduction.pdf
* """
* Place numbers 1 through 8 on nodes
@@ -42,8 +41,7 @@ public class PlaceNumberPuzzle
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("PlaceNumberPuzzle");
//
@@ -53,74 +51,43 @@ public class PlaceNumberPuzzle
int n = 8;
// Note: this is 1-based for compatibility (and lazyness)
int[,] graph = {
{1,2},
{1,3},
{1,4},
{2,1},
{2,3},
{2,5},
{2,6},
{3,2},
{3,4},
{3,6},
{3,7},
{4,1},
{4,3},
{4,6},
{4,7},
{5,2},
{5,3},
{5,6},
{5,8},
{6,2},
{6,3},
{6,4},
{6,5},
{6,7},
{6,8},
{7,3},
{7,4},
{7,6},
{7,8},
{8,5},
{8,6},
{8,7}
};
int[, ] graph = {{1, 2}, {1, 3}, {1, 4}, {2, 1}, {2, 3}, {2, 5}, {2, 6},
{3, 2}, {3, 4}, {3, 6}, {3, 7}, {4, 1}, {4, 3}, {4, 6},
{4, 7}, {5, 2}, {5, 3}, {5, 6}, {5, 8}, {6, 2}, {6, 3},
{6, 4}, {6, 5}, {6, 7}, {6, 8}, {7, 3}, {7, 4}, {7, 6},
{7, 8}, {8, 5}, {8, 6}, {8, 7}};
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x");
//
// Constraints
//
solver.Add(x.AllDifferent());
for(int i = 0; i < m; i++) {
for (int i = 0; i < m; i++) {
// (also base 0-base)
solver.Add( (x[graph[i,0]-1]-x[graph[i,1]-1]).Abs() > 1);
solver.Add((x[graph[i, 0] - 1] - x[graph[i, 1] - 1]).Abs() > 1);
}
// symmetry breaking
solver.Add(x[0] < x[n-1]);
solver.Add(x[0] < x[n - 1]);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x: ");
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -131,11 +98,7 @@ public class PlaceNumberPuzzle
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,10 +19,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class PostOfficeProblem2
{
public class PostOfficeProblem2 {
/**
*
* Post office problem.
@@ -58,9 +55,7 @@ public class PostOfficeProblem2
* Also see http://www.hakank.org/or-tools/post_office_problem2.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("PostOfficeProblem2");
//
@@ -77,7 +72,6 @@ public class PostOfficeProblem2
// Working sunday is 200 extra.
int[] cost = {500, 600, 800, 800, 800, 800, 700};
//
// Decision variables
//
@@ -91,10 +85,12 @@ public class PostOfficeProblem2
//
// Constraints
//
for(int i = 0; i < n; i++) {
IntVar s = (from j in Enumerable.Range(0, n)
where j != (i+5) % n && j != (i+6) % n
select x[j]).ToArray().Sum().Var();
for (int i = 0; i < n; i++) {
IntVar s = (from j in Enumerable.Range(0, n) where j != (i + 5) % n &&
j != (i + 6) % n select x[j])
.ToArray()
.Sum()
.Var();
solver.Add(s >= need[i]);
}
@@ -108,24 +104,22 @@ public class PostOfficeProblem2
//
OptimizeVar obj = total_cost.Minimize(100);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("num_workers: {0}", num_workers.Value());
Console.WriteLine("total_cost: {0}", total_cost.Value());
Console.Write("x: ");
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine("\n");
}
@@ -136,13 +130,7 @@ public class PostOfficeProblem2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,10 +19,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class QuasigroupCompletion
{
public class QuasigroupCompletion {
static int X = 0;
/*
@@ -37,19 +34,17 @@ public class QuasigroupCompletion
* 4 1 3 2 5
* 5 4 1 3 2
* 3 2 5 4 1
*/
*/
static int default_n = 5;
static int[,] default_problem = {{1, X, X, X, 4},
{X, 5, X, X, X},
{4, X, X, 2, X},
{X, 4, X, X, X},
{X, X, 5, X, 1}};
static int[, ] default_problem = {{1, X, X, X, 4},
{X, 5, X, X, X},
{4, X, X, 2, X},
{X, 4, X, X, X},
{X, X, 5, X, 1}};
// for the actual problem
static int n;
static int[,] problem;
static int[, ] problem;
/**
*
@@ -57,36 +52,34 @@ public class QuasigroupCompletion
* See http://www.hakank.org/or-tools/quasigroup_completion.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("QuasigroupCompletion");
//
// data
//
Console.WriteLine("Problem:");
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
Console.Write(problem[i,j] + " ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write(problem[i, j] + " ");
}
Console.WriteLine();
}
Console.WriteLine();
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
IntVar[] x_flat = x.Flatten();
//
// Constraints
//
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if (problem[i,j] > X) {
solver.Add(x[i,j] == problem[i,j]);
//
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (problem[i, j] > X) {
solver.Add(x[i, j] == problem[i, j]);
}
}
}
@@ -96,29 +89,27 @@ public class QuasigroupCompletion
//
// rows
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
IntVar[] row = new IntVar[n];
for(int j = 0; j < n; j++) {
row[j] = x[i,j];
for (int j = 0; j < n; j++) {
row[j] = x[i, j];
}
solver.Add(row.AllDifferent());
}
// columns
for(int j = 0; j < n; j++) {
for (int j = 0; j < n; j++) {
IntVar[] col = new IntVar[n];
for(int i = 0; i < n; i++) {
col[i] = x[i,j];
for (int i = 0; i < n; i++) {
col[i] = x[i, j];
}
solver.Add(col.AllDifferent());
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.INT_VAR_SIMPLE,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_SIMPLE,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
@@ -127,13 +118,14 @@ public class QuasigroupCompletion
while (solver.NextSolution()) {
sol++;
Console.WriteLine("Solution #{0} ", sol + " ");
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++){
Console.Write("{0} ", x[i,j].Value());
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write("{0} ", x [i, j]
.Value());
}
Console.WriteLine();
}
Console.WriteLine();
}
@@ -143,10 +135,8 @@ public class QuasigroupCompletion
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
/**
*
* Reads a Quasigroup completion file.
@@ -157,9 +147,9 @@ public class QuasigroupCompletion
* <
* row number of space separated entries
* >
*
*
* "." or "0" means unknown, integer 1..n means known value
*
*
* Example
* 5
* 1 . . . 4
@@ -170,29 +160,27 @@ public class QuasigroupCompletion
*
*/
private static void readFile(String file) {
Console.WriteLine("readFile(" + file + ")");
int lineCount = 0;
TextReader inr = new StreamReader(file);
String str;
while ((str = inr.ReadLine()) != null && str.Length > 0) {
str = str.Trim();
// ignore comments
if(str.StartsWith("#") || str.StartsWith("%")) {
if (str.StartsWith("#") || str.StartsWith("%")) {
continue;
}
Console.WriteLine(str);
if (lineCount == 0) {
n = Convert.ToInt32(str); // number of rows
problem = new int[n,n];
n = Convert.ToInt32(str); // number of rows
problem = new int[n, n];
} else {
// the problem matrix
String[] row = Regex.Split(str, " ");
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
String s = row[i];
if (s.Equals(".")) {
problem[lineCount - 1, i] = 0;
@@ -201,20 +189,16 @@ public class QuasigroupCompletion
}
}
}
lineCount++;
} // end while
} // end while
inr.Close();
} // end readFile
} // end readFile
public static void Main(String[] args)
{
public static void Main(String[] args) {
String file = "";
if (args.Length > 0) {
file = args[0];

View File

@@ -18,9 +18,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class RegexGeneration
{
public class RegexGeneration {
/*
* Global constraint regular
*
@@ -43,36 +41,31 @@ public class RegexGeneration
* F : accepting states
*
*/
static void MyRegular(Solver solver,
IntVar[] x,
int Q,
int S,
int[,] d,
int q0,
int[] F) {
static void MyRegular(Solver solver, IntVar[] x, int Q, int S, int[, ] d,
int q0, int[] F) {
// d2 is the same as d, except we add one extra transition for
// each possible input; each extra transition is from state zero
// to state zero. This allows us to continue even if we hit a
// non-accepted input.
int[][] d2 = new int[Q+1][];
for(int i = 0; i <= Q; i++) {
int[][] d2 = new int [Q + 1]
[];
for (int i = 0; i <= Q; i++) {
int[] row = new int[S];
for(int j = 0; j < S; j++) {
for (int j = 0; j < S; j++) {
if (i == 0) {
row[j] = 0;
} else {
row[j] = d[i-1,j];
row[j] = d[i - 1, j];
}
}
d2[i] = row;
}
int[] d2_flatten = (from i in Enumerable.Range(0, Q+1)
from j in Enumerable.Range(0, S)
select d2[i][j]).ToArray();
int[] d2_flatten =
(from i in Enumerable.Range(0, Q + 1) from j in Enumerable.Range(0, S)
select d2 [i]
[j])
.ToArray();
// If x has index set m..n, then a[m-1] holds the initial state
// (q0), and a[i+1] holds the state we're in after processing
@@ -81,23 +74,21 @@ public class RegexGeneration
int m = 0;
int n = x.Length;
IntVar[] a = solver.MakeIntVarArray(n+1-m, 0,Q+1, "a");
IntVar[] a = solver.MakeIntVarArray(n + 1 - m, 0, Q + 1, "a");
// Check that the final state is in F
solver.Add(a[a.Length-1].Member(F));
solver.Add(a [a.Length - 1]
.Member(F));
// First state is q0
solver.Add(a[m] == q0);
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
solver.Add(x[i] >= 1);
solver.Add(x[i] <= S);
// Determine a[i+1]: a[i+1] == d2[a[i], x[i]]
solver.Add(a[i+1] == d2_flatten.Element(((a[i]*S)+(x[i]-1))));
solver.Add(a[i + 1] == d2_flatten.Element(((a[i] * S) + (x[i] - 1))));
}
}
/**
*
* Simple regular expression.
@@ -113,8 +104,7 @@ public class RegexGeneration
* Also see http://www.hakank.org/or-tools/regex.py
*
*/
private static void Solve(int n, List<String> res)
{
private static void Solve(int n, List<String> res) {
Solver solver = new Solver("RegexGeneration");
Console.WriteLine("\nn: {0}", n);
@@ -122,29 +112,29 @@ public class RegexGeneration
// The DFS (for regular)
int n_states = 11;
int input_max = 12;
int initial_state = 1; // 0 is for the failing state
int initial_state = 1; // 0 is for the failing state
int[] accepting_states = {12};
// The DFA
int [,] transition_fn = {
// 1 2 3 4 5 6 7 8 9 0 1 2 //
{0,2,3,0,0,0,0,0,0,0,0,0}, // 1 k
{0,0,0,4,0,0,0,0,0,0,0,0}, // 2 je
{0,0,0,4,0,0,0,0,0,0,0,0}, // 3 ä
{0,0,0,0,5,6,7,8,0,0,0,0}, // 4 ll
{0,0,0,0,0,0,7,8,0,0,0,0}, // 5 er
{0,0,0,0,0,0,7,8,0,0,0,0}, // 6 ar
{0,0,0,0,0,0,0,0,9,10,0,0}, // 7 st
{0,0,0,0,0,0,0,0,9,10,0,0}, // 8 b
{0,0,0,0,0,0,0,0,0,10,0,0}, // 9 r
{0,0,0,0,0,0,0,0,0,0,11,12}, // 10 a
{0,0,0,0,0,0,0,0,0,0,0,12}, // 11 n
// 12 d
int[, ] transition_fn = {
// 1 2 3 4 5 6 7 8 9 0 1 2 //
{0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // 1 k
{0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, // 2 je
{0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0}, // 3 ä
{0, 0, 0, 0, 5, 6, 7, 8, 0, 0, 0, 0}, // 4 ll
{0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0}, // 5 er
{0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0}, // 6 ar
{0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0}, // 7 st
{0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 0, 0}, // 8 b
{0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0}, // 9 r
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12}, // 10 a
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12}, // 11 n
// 12 d
};
// Name of the states
String[] s = {"k","je","ä","ll","er","ar","st","b","r","a","n","d"};
String[] s = {"k", "je", "ä", "ll", "er", "ar",
"st", "b", "r", "a", "n", "d"};
//
// Decision variables
@@ -154,15 +144,13 @@ public class RegexGeneration
//
// Constraints
//
MyRegular(solver, x, n_states, input_max, transition_fn,
initial_state, accepting_states);
MyRegular(solver, x, n_states, input_max, transition_fn, initial_state,
accepting_states);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
@@ -172,8 +160,11 @@ public class RegexGeneration
// State 1 (the start state) is not included in the
// state array (x) so we add it first.
res2.Add(s[0]);
for(int i = 0; i < n; i++) {
res2.Add(s[x[i].Value()-1]);
for (int i = 0; i < n; i++) {
res2.Add(s [x [i]
.Value() -
1]
);
}
res.Add(String.Join("", res2.ToArray()));
}
@@ -183,19 +174,16 @@ public class RegexGeneration
Console.WriteLine("Failures: {0}", solver.Failures());
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
List<String> res = new List<String>();
for(int n = 4; n <= 9; n++) {
for (int n = 4; n <= 9; n++) {
Solve(n, res);
}
Console.WriteLine("\nThe following {0} words where generated", res.Count);
foreach(string r in res) {
foreach (string r in res) {
Console.WriteLine(r);
}
}

View File

@@ -21,9 +21,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class Rogo2
{
public class Rogo2 {
static int W = 0;
static int B = -1;
@@ -39,58 +37,45 @@ public class Rogo2
static int default_cols = 9;
static int default_max_steps = 12;
static int default_best = 8;
static int[,] default_problem = {
{2,W,W,W,W,W,W,W,W},
{W,3,W,W,1,W,W,2,W},
{W,W,W,W,W,W,B,W,2},
{W,W,2,B,W,W,W,W,W},
{W,W,W,W,2,W,W,1,W}
};
static int[, ] default_problem = {{2, W, W, W, W, W, W, W, W},
{W, 3, W, W, 1, W, W, 2, W},
{W, W, W, W, W, W, B, W, 2},
{W, W, 2, B, W, W, W, W, W},
{W, W, W, W, 2, W, W, 1, W}};
static String default_problem_name = "Problem Mike Trick";
// The actual problem
static int rows;
static int cols;
static int max_steps;
static int best;
static int[,] problem;
static int[, ] problem;
static string problem_name;
/**
*
* Build the table of valid connections of the grid.
*
*/
public static IntTupleSet ValidConnections(int rows, int cols)
{
public static IntTupleSet ValidConnections(int rows, int cols) {
IEnumerable<int> ROWS = Enumerable.Range(0, rows);
IEnumerable<int> COLS = Enumerable.Range(0, cols);
var result_tmp = (
from i1 in ROWS
from j1 in COLS
from i2 in ROWS
from j2 in COLS
where
(Math.Abs(j1-j2) == 1 && i1 == i2) ||
(Math.Abs(i1-i2) == 1 && j1 % cols == j2 % cols)
select new int[] {i1*cols+j1, i2*cols+j2}
).ToArray();
var result_tmp =
(from i1 in ROWS from j1 in COLS from i2 in ROWS from j2 in COLS where(
Math.Abs(j1 - j2) == 1 && i1 == i2) ||
(Math.Abs(i1 - i2) == 1 && j1 % cols == j2 % cols)
select new int[]{i1 * cols + j1, i2 * cols + j2})
.ToArray();
// Convert to len x 2 matrix
int len = result_tmp.Length;
IntTupleSet result = new IntTupleSet(2);
foreach(int[] r in result_tmp) {
foreach (int[] r in result_tmp) {
result.Insert(r);
}
return result;
}
/**
*
* Rogo puzzle solver.
@@ -118,12 +103,9 @@ AllowedAssignments) with the valid connections
* - instead of two coordinates arrays, it use a single path array
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Rogo2");
Console.WriteLine("\n");
Console.WriteLine("**********************************************");
Console.WriteLine(" {0}", problem_name);
@@ -134,33 +116,34 @@ AllowedAssignments) with the valid connections
//
int B = -1;
Console.WriteLine("Rows: {0} Cols: {1} Max Steps: {2}", rows, cols, max_steps);
Console.WriteLine("Rows: {0} Cols: {1} Max Steps: {2}", rows, cols,
max_steps);
int[] problem_flatten = problem.Cast<int>().ToArray();
int max_point = problem_flatten.Max();
int max_sum = problem_flatten.Sum();
Console.WriteLine("max_point: {0} max_sum: {1} best: {2}", max_point, max_sum, best);
Console.WriteLine("max_point: {0} max_sum: {1} best: {2}", max_point,
max_sum, best);
IEnumerable<int> STEPS = Enumerable.Range(0, max_steps);
IEnumerable<int> STEPS1 = Enumerable.Range(0, max_steps-1);
IEnumerable<int> STEPS1 = Enumerable.Range(0, max_steps - 1);
// the valid connections, to be used with AllowedAssignments
IntTupleSet valid_connections = ValidConnections(rows, cols);
//
// Decision variables
//
IntVar[] path = solver.MakeIntVarArray(max_steps, 0, rows*cols-1, "path");
IntVar[] path =
solver.MakeIntVarArray(max_steps, 0, rows * cols - 1, "path");
IntVar[] points = solver.MakeIntVarArray(max_steps, 0, best, "points");
IntVar sum_points = points.Sum().VarWithName("sum_points");
//
// Constraints
//
foreach(int s in STEPS) {
foreach (int s in STEPS) {
// calculate the points (to maximize)
solver.Add(points[s] == problem_flatten.Element(path[s]));
@@ -171,34 +154,29 @@ AllowedAssignments) with the valid connections
solver.Add(path.AllDifferent());
// valid connections
foreach(int s in STEPS1) {
solver.Add(new IntVar[] {path[s], path[s+1]}.
AllowedAssignments(valid_connections));
foreach (int s in STEPS1) {
solver.Add(new IntVar[]{path[s], path[s + 1]}.AllowedAssignments(
valid_connections));
}
// around the corner
solver.Add(new IntVar[] {path[max_steps-1], path[0]}.
AllowedAssignments(valid_connections));
solver.Add(new IntVar[]{path[max_steps - 1], path[0]}.AllowedAssignments(
valid_connections));
// Symmetry breaking
for(int s = 1; s < max_steps; s++) {
for (int s = 1; s < max_steps; s++) {
solver.Add(path[0] < path[s]);
}
//
// Objective
//
OptimizeVar obj = sum_points.Maximize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(path,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(path, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, obj);
@@ -206,31 +184,36 @@ AllowedAssignments) with the valid connections
while (solver.NextSolution()) {
Console.WriteLine("sum_points: {0}", sum_points.Value());
Console.Write("path: ");
foreach(int s in STEPS) {
Console.Write("{0} ", path[s].Value());
foreach (int s in STEPS) {
Console.Write("{0} ", path [s]
.Value());
}
Console.WriteLine();
Console.WriteLine("(Adding 1 to coords...)");
int[,] sol = new int[rows, cols];
foreach(int s in STEPS) {
int p = (int) path[s].Value();
int x = (int) (p / cols);
int y = (int) (p % cols);
Console.WriteLine("{0,2},{1,2} ({2} points)", x+1, y+1, points[s].Value());
int[, ] sol = new int[rows, cols];
foreach (int s in STEPS) {
int p = (int) path [s]
.Value();
int x = (int)(p / cols);
int y = (int)(p % cols);
Console.WriteLine("{0,2},{1,2} ({2} points)", x + 1, y + 1,
points [s]
.Value());
sol[x, y] = 1;
}
Console.WriteLine("\nThe path is marked by 'X's:");
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
String p = sol[i,j] == 1 ? "X" : " ";
String q = problem[i,j] == B ? "B" :
problem[i,j] == 0 ? "." : problem[i,j].ToString();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
String p = sol[i, j] == 1 ? "X" : " ";
String q = problem[i, j] == B ? "B" : problem[i, j] == 0
? "."
: problem [i, j]
.ToString();
Console.Write("{0,2}{1} ", q, p);
}
Console.WriteLine();
}
Console.WriteLine();
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -239,10 +222,8 @@ AllowedAssignments) with the valid connections
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
/**
*
* Reads a Rogo problem instance file.
@@ -276,7 +257,6 @@ AllowedAssignments) with the valid connections
*/
private static void ReadFile(String file) {
Console.WriteLine("readFile(" + file + ")");
TextReader inr = new StreamReader(file);
@@ -288,7 +268,7 @@ AllowedAssignments) with the valid connections
Console.WriteLine(str);
// ignore comments
if(str.StartsWith("#") || str.StartsWith("%")) {
if (str.StartsWith("#") || str.StartsWith("%")) {
continue;
}
@@ -306,9 +286,8 @@ AllowedAssignments) with the valid connections
best = Convert.ToInt32(str);
} else {
String[] tmp = Regex.Split(str, "[,\\s]+");
for(int j = 0; j < cols; j++) {
for (int j = 0; j < cols; j++) {
int val = 0;
if (tmp[j] == "B") {
val = B;
@@ -317,29 +296,24 @@ AllowedAssignments) with the valid connections
} else {
val = Convert.ToInt32(tmp[j]);
}
problem[lineCount-4, j] = val;
problem[lineCount - 4, j] = val;
}
}
lineCount++;
} // end while
} // end while
inr.Close();
} // end readFile
} // end readFile
public static void Main(String[] args)
{
rows = default_rows;
cols = default_cols;
max_steps = default_max_steps;
best = default_best;
problem = default_problem;
public static void Main(String[] args) {
rows = default_rows;
cols = default_cols;
max_steps = default_max_steps;
best = default_best;
problem = default_problem;
problem_name = default_problem_name;
String file = "";
@@ -351,6 +325,5 @@ AllowedAssignments) with the valid connections
}
Solve();
}
}

View File

@@ -20,10 +20,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class SchedulingSpeakers
{
public class SchedulingSpeakers {
/**
*
* Scheduling speakers problem
@@ -34,46 +31,42 @@ public class SchedulingSpeakers
* See http://www.hakank.org/google_or_tools/scheduling_speakers.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SchedulingSpeakers");
// number of speakers
int n = 6;
// slots available to speak
int[][] available = {
// Reasoning:
new int[] {3,4,5,6}, // 2) the only one with 6 after speaker F -> 1
new int[] {3,4}, // 5) 3 or 4
new int[] {2,3,4,5}, // 3) only with 5 after F -> 1 and A -> 6
new int[] {2,3,4}, // 4) only with 2 after C -> 5 and F -> 1
new int[] {3,4}, // 5) 3 or 4
new int[] {1,2,3,4,5,6} // 1) the only with 1
// Reasoning:
new int[]{3, 4, 5, 6}, // 2) the only one with 6 after speaker F -> 1
new int[]{3, 4}, // 5) 3 or 4
new int[]{2, 3, 4, 5}, // 3) only with 5 after F -> 1 and A -> 6
new int[]{2, 3, 4}, // 4) only with 2 after C -> 5 and F -> 1
new int[]{3, 4}, // 5) 3 or 4
new int[]{1, 2, 3, 4, 5, 6} // 1) the only with 1
};
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x");
IntVar[] x = solver.MakeIntVarArray(n, 1, n, "x");
//
// Constraints
//
solver.Add(x.AllDifferent());
for(int i = 0; i < n; i++) {
solver.Add(x[i].Member(available[i]));
for (int i = 0; i < n; i++) {
solver.Add(x [i]
.Member(available[i]));
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
@@ -88,12 +81,7 @@ public class SchedulingSpeakers
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,10 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class SecretSanta
{
public class SecretSanta {
/**
*
* Secret Santa problem in Google CP Solver.
@@ -48,25 +45,23 @@ public class SecretSanta
* * Your script will be fed a list of names on STDIN.
* ...
* Your script should then choose a Secret Santa for every name in the list.
* Obviously, a person cannot be their own Secret Santa. In addition, my friends
* no longer allow people in the same family to be Santas for each other and your
* script should take this into account.
* Obviously, a person cannot be their own Secret Santa. In addition, my
* friends no longer allow people in the same family to be Santas for each
* other and your script should take this into account.
* """
*
* Comment: This model skips the file input and mail parts. We
* assume that the friends are identified with a number from 1..n,
* and the families is identified with a number 1..num_families.
*
* Also see http://www.hakank.org/or-tools/secret_santa.py
* Also see http://www.hakank.org/or-tools/secret_santa2.cs
* Also see http://www.hakank.org/or-tools/secret_santa.py
* Also see http://www.hakank.org/or-tools/secret_santa2.cs
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SecretSanta");
int[] family = {1,1,1,1, 2, 3,3,3,3,3, 4,4};
int[] family = {1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 4, 4};
int n = family.Length;
Console.WriteLine("n = {0}", n);
@@ -76,8 +71,7 @@ public class SecretSanta
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 0, n-1, "x");
IntVar[] x = solver.MakeIntVarArray(n, 0, n - 1, "x");
//
// Constraints
@@ -86,29 +80,29 @@ public class SecretSanta
// Can't be one own"s Secret Santa
// (i.e. ensure that there are no fix-point in the array.)
foreach(int i in RANGE) {
foreach (int i in RANGE) {
solver.Add(x[i] != i);
}
// No Secret Santa to a person in the same family
foreach(int i in RANGE) {
foreach (int i in RANGE) {
solver.Add(solver.MakeIntConst(family[i]) != family.Element(x[i]));
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_SIMPLE,
Solver.INT_VALUE_SIMPLE);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x: ");
foreach(int i in RANGE) {
Console.Write(x[i].Value() + " ");
foreach (int i in RANGE) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -119,11 +113,7 @@ public class SecretSanta
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,10 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class SecretSanta2
{
public class SecretSanta2 {
/**
*
* Secret Santa problem II in Google CP Solver.
@@ -64,12 +61,10 @@ public class SecretSanta2
* problem don't mention.
*
*
* Also see http://www.hakank.org/or-tools/secret_santa2.py
* Also see http://www.hakank.org/or-tools/secret_santa2.py
*
*/
private static void Solve(int single=0)
{
private static void Solve(int single = 0) {
Solver solver = new Solver("SecretSanta2");
Console.WriteLine("\nSingle: {0}", single);
@@ -85,15 +80,15 @@ public class SecretSanta2
int n_no_single = 8;
int M = n_no_single + 1;
int[][] rounds_no_single = {
// N A R M El J L Ev
new int[] {0, M, 3, M, 1, 4, M, 2}, // Noah
new int[] {M, 0, 4, 2, M, 3, M, 1}, // Ava
new int[] {M, 2, 0, M, 1, M, 3, 4}, // Ryan
new int[] {M, 1, M, 0, 2, M, 3, 4}, // Mia
new int[] {M, 4, M, 3, 0, M, 1, 2}, // Ella
new int[] {1, 4, 3, M, M, 0, 2, M}, // John
new int[] {M, 3, M, 2, 4, 1, 0, M}, // Lily
new int[] {4, M, 3, 1, M, 2, M, 0} // Evan
// N A R M El J L Ev
new int[]{0, M, 3, M, 1, 4, M, 2}, // Noah
new int[]{M, 0, 4, 2, M, 3, M, 1}, // Ava
new int[]{M, 2, 0, M, 1, M, 3, 4}, // Ryan
new int[]{M, 1, M, 0, 2, M, 3, 4}, // Mia
new int[]{M, 4, M, 3, 0, M, 1, 2}, // Ella
new int[]{1, 4, 3, M, M, 0, 2, M}, // John
new int[]{M, 3, M, 2, 4, 1, 0, M}, // Lily
new int[]{4, M, 3, 1, M, 2, M, 0} // Evan
};
//
@@ -103,26 +98,25 @@ public class SecretSanta2
M = n_with_single + 1;
int[][] rounds_single = {
// N A R M El J L Ev S
new int[] {0, M, 3, M, 1, 4, M, 2, 2}, // Noah
new int[] {M, 0, 4, 2, M, 3, M, 1, 1}, // Ava
new int[] {M, 2, 0, M, 1, M, 3, 4, 4}, // Ryan
new int[] {M, 1, M, 0, 2, M, 3, 4, 3}, // Mia
new int[] {M, 4, M, 3, 0, M, 1, 2, M}, // Ella
new int[] {1, 4, 3, M, M, 0, 2, M, M}, // John
new int[] {M, 3, M, 2, 4, 1, 0, M, M}, // Lily
new int[] {4, M, 3, 1, M, 2, M, 0, M}, // Evan
new int[] {1, 2, 3, 4, M, 2, M, M, 0} // Single
new int[]{0, M, 3, M, 1, 4, M, 2, 2}, // Noah
new int[]{M, 0, 4, 2, M, 3, M, 1, 1}, // Ava
new int[]{M, 2, 0, M, 1, M, 3, 4, 4}, // Ryan
new int[]{M, 1, M, 0, 2, M, 3, 4, 3}, // Mia
new int[]{M, 4, M, 3, 0, M, 1, 2, M}, // Ella
new int[]{1, 4, 3, M, M, 0, 2, M, M}, // John
new int[]{M, 3, M, 2, 4, 1, 0, M, M}, // Lily
new int[]{4, M, 3, 1, M, 2, M, 0, M}, // Evan
new int[]{1, 2, 3, 4, M, 2, M, M, 0} // Single
};
int Noah = 0;
int Ava = 1;
int Ryan = 2;
int Mia = 3;
int Ella = 4;
int John = 5;
int Lily = 6;
int Evan = 7;
int Noah = 0;
int Ava = 1;
int Ryan = 2;
int Mia = 3;
int Ella = 4;
int John = 5;
int Lily = 6;
int Evan = 7;
int n = n_no_single;
@@ -135,34 +129,30 @@ public class SecretSanta2
IEnumerable<int> RANGE = Enumerable.Range(0, n);
String[] persons = {"Noah", "Ava", "Ryan", "Mia", "Ella",
"John", "Lily", "Evan", "Single"};
String[] persons = {"Noah", "Ava", "Ryan", "Mia", "Ella",
"John", "Lily", "Evan", "Single"};
int[] spouses = {
Ava, // Noah
Noah, // Ava
Mia, // Rya
Ryan, // Mia
John, // Ella
Ella, // John
Evan, // Lily
Lily, // Evan
-1 // Single has no spouse
Ava, // Noah
Noah, // Ava
Mia, // Rya
Ryan, // Mia
John, // Ella
Ella, // John
Evan, // Lily
Lily, // Evan
-1 // Single has no spouse
};
//
// Decision variables
//
IntVar[] santas = solver.MakeIntVarArray(n, 0, n-1, "santas");
IntVar[] santas = solver.MakeIntVarArray(n, 0, n - 1, "santas");
IntVar[] santa_distance = solver.MakeIntVarArray(n, 0, M, "santa_distance");
// total of "distance", to maximize
IntVar z = santa_distance.Sum().VarWithName("z");
//
// Constraints
//
@@ -170,62 +160,63 @@ public class SecretSanta2
// Can't be one own"s Secret Santa
// (i.e. ensure that there are no fix-point in the array.)
foreach(int i in RANGE) {
foreach (int i in RANGE) {
solver.Add(santas[i] != i);
}
// no Santa for a spouses
foreach(int i in RANGE) {
foreach (int i in RANGE) {
if (spouses[i] > -1) {
solver.Add(santas[i] != spouses[i]);
}
}
// optimize "distance" to earlier rounds:
foreach(int i in RANGE) {
solver.Add(santa_distance[i] == rounds[i].Element(santas[i]));
foreach (int i in RANGE) {
solver.Add(santa_distance[i] == rounds [i]
.Element(santas[i]));
}
// cannot be a Secret Santa for the same person
// two years in a row.
foreach(int i in RANGE) {
foreach(int j in RANGE) {
if (rounds[i][j] == 1) {
foreach (int i in RANGE) {
foreach (int j in RANGE) {
if (rounds [i]
[j] == 1) {
solver.Add(santas[i] != j);
}
}
}
//
// Objective (minimize the distances)
//
OptimizeVar obj = z.Maximize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(santas,
Solver.CHOOSE_MIN_SIZE_LOWEST_MIN,
Solver.ASSIGN_CENTER_VALUE);
DecisionBuilder db = solver.MakePhase(
santas, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_CENTER_VALUE);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("\ntotal distances: {0}", z.Value());
Console.Write("santas: ");
for(int i = 0; i < n; i++) {
Console.Write(santas[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(santas [i]
.Value() +
" ");
}
Console.WriteLine();
foreach(int i in RANGE) {
Console.WriteLine("{0}\tis a Santa to {1} (distance {2})",
persons[i],
persons[santas[i].Value()],
santa_distance[i].Value());
foreach (int i in RANGE) {
Console.WriteLine("{0}\tis a Santa to {1} (distance {2})", persons[i],
persons [santas [i]
.Value()]
,
santa_distance [i]
.Value());
}
}
@@ -235,11 +226,9 @@ public class SecretSanta2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int single = 0;
Solve(single);
single = 1;

View File

@@ -16,15 +16,13 @@
using System;
using Google.OrTools.ConstraintSolver;
public class SendMoreMoney
{
public class SendMoreMoney {
/**
*
* Solve the SEND+MORE=MONEY problem
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SendMoreMoney");
//
@@ -40,14 +38,15 @@ public class SendMoreMoney
IntVar Y = solver.MakeIntVar(0, 9, "Y");
// for AllDifferent()
IntVar[] x = new IntVar[] {S,E,N,D,M,O,R,Y};
IntVar[] x = new IntVar[]{S, E, N, D, M, O, R, Y};
//
// Constraints
//
solver.Add(x.AllDifferent());
solver.Add(S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E ==
M*10000 + O*1000 + N*100 + E*10 + Y);
solver.Add(S * 1000 + E * 100 + N * 10 + D + M * 1000 + O * 100 + R * 10 +
E ==
M * 10000 + O * 1000 + N * 100 + E * 10 + Y);
solver.Add(S > 0);
solver.Add(M > 0);
@@ -55,14 +54,15 @@ public class SendMoreMoney
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < 8; i++) {
Console.Write(x[i].ToString() + " ");
for (int i = 0; i < 8; i++) {
Console.Write(x [i]
.ToString() +
" ");
}
Console.WriteLine();
}
@@ -72,11 +72,7 @@ public class SendMoreMoney
Console.WriteLine("Branches: " + solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,16 +16,14 @@
using System;
using Google.OrTools.ConstraintSolver;
public class SendMoreMoney
{
public class SendMoreMoney {
/**
*
* Solve the SEND+MORE=MONEY problem
* using scalar product.
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SendMoreMoney");
//
@@ -41,7 +39,7 @@ public class SendMoreMoney
IntVar Y = solver.MakeIntVar(0, 9, "Y");
// for AllDifferent()
IntVar[] x = new IntVar[] {S,E,N,D,M,O,R,Y};
IntVar[] x = new IntVar[]{S, E, N, D, M, O, R, Y};
//
// Constraints
@@ -54,11 +52,11 @@ public class SendMoreMoney
*/
// Here we use scalar product instead.
int[] s1 = new int[] {1000,100,10,1};
int[] s2 = new int[] {10000,1000,100,10,1};
solver.Add(new IntVar[] {S,E,N,D}.ScalProd(s1) +
new IntVar[] {M,O,R,E}.ScalProd(s1) ==
new IntVar[] {M,O,N,E,Y}.ScalProd(s2));
int[] s1 = new int[]{1000, 100, 10, 1};
int[] s2 = new int[]{10000, 1000, 100, 10, 1};
solver.Add(new IntVar[]{S, E, N, D}.ScalProd(s1) +
new IntVar[]{M, O, R, E}.ScalProd(s1) ==
new IntVar[]{M, O, N, E, Y}.ScalProd(s2));
solver.Add(S > 0);
solver.Add(M > 0);
@@ -66,14 +64,15 @@ public class SendMoreMoney
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < 8; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < 8; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -84,11 +83,7 @@ public class SendMoreMoney
Console.WriteLine("Branches: {0}", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -16,8 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class SendMostMoney
{
public class SendMostMoney {
/**
*
* Solve the SEND+MOST=MONEY problem
@@ -25,9 +24,7 @@ public class SendMostMoney
* See http://www.hakank.org/google_or_tools/send_most_money.py
*
*/
private static long Solve(long MONEY)
{
private static long Solve(long MONEY) {
Solver solver = new Solver("SendMostMoney");
//
@@ -43,19 +40,22 @@ public class SendMostMoney
IntVar Y = solver.MakeIntVar(0, 9, "Y");
// for AllDifferent()
IntVar[] x = new IntVar[] {S,E,N,D,M,O,T,Y};
IntVar[] x = new IntVar[]{S, E, N, D, M, O, T, Y};
IntVar[] eq = {S,E,N,D, M,O,S,T, M,O,N,E,Y};
int[] coeffs = { 1000, 100, 10, 1, // S E N D +
1000, 100, 10, 1, // M O S T
-10000,-1000, -100,-10,-1 // == M O N E Y
};
IntVar[] eq = {S, E, N, D, M, O, S, T, M, O, N, E, Y};
int[] coeffs = {
1000, 100, 10, 1, // S E N D +
1000, 100, 10, 1, // M O S T
-10000, -1000, -100, -10, -1 // == M O N E Y
};
solver.Add(eq.ScalProd(coeffs) == 0);
// IntVar money = solver.MakeScalProd(new IntVar[] {M, O, N, E, Y},
// new int[] {10000, 1000, 100, 10, 1}).Var();
IntVar money = (new IntVar[] {M, O, N, E, Y}).
ScalProd(new int[] {10000, 1000, 100, 10, 1}).Var();
// new int[] {10000, 1000, 100, 10,
// 1}).Var();
IntVar money = (new IntVar[]{M, O, N, E, Y})
.ScalProd(new int[]{10000, 1000, 100, 10, 1})
.Var();
//
// Constraints
@@ -71,8 +71,7 @@ public class SendMostMoney
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
if (MONEY == 0) {
@@ -85,9 +84,11 @@ public class SendMostMoney
long money_ret = 0;
while (solver.NextSolution()) {
money_ret = money.Value();
Console.WriteLine("money: {0}", money.Value() );
for(int i = 0; i < x.Length; i++) {
Console.Write(x[i].Value() + " ");
Console.WriteLine("money: {0}", money.Value());
for (int i = 0; i < x.Length; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -100,14 +101,13 @@ public class SendMostMoney
solver.EndSearch();
return money_ret;
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
Console.WriteLine("First get the max value of money:");
long this_money = Solve(0);
Console.WriteLine("\nThen we find all solutions for MONEY = {0}:", this_money);
Console.WriteLine("\nThen we find all solutions for MONEY = {0}:",
this_money);
long tmp = Solve(this_money);
}
}

View File

@@ -16,18 +16,14 @@
using System;
using Google.OrTools.ConstraintSolver;
public class Seseman
{
public class Seseman {
/**
*
* Solves the Seseman convent problem.
* See http://www.hakank.org/google_or_tools/seseman.py
*
*/
private static void Solve(int n = 3)
{
private static void Solve(int n = 3) {
Solver solver = new Solver("Seseman");
//
@@ -38,27 +34,26 @@ public class Seseman
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 0, n*n, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 0, n * n, "x");
IntVar[] x_flat = x.Flatten();
IntVar total_sum = x_flat.Sum().Var();
//
// Constraints
//
//
// zero in all middle cells
for(int i = 1; i < n-1; i++) {
for(int j = 1; j < n-1; j++) {
solver.Add(x[i,j] == 0);
for (int i = 1; i < n - 1; i++) {
for (int j = 1; j < n - 1; j++) {
solver.Add(x[i, j] == 0);
}
}
// all borders must be >= 1
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == 0 || j == 0 || i == n - 1 || j == n - 1) {
solver.Add(x[i,j] >= 1);
solver.Add(x[i, j] >= 1);
}
}
}
@@ -68,35 +63,34 @@ public class Seseman
IntVar[] border2 = new IntVar[n];
IntVar[] border3 = new IntVar[n];
IntVar[] border4 = new IntVar[n];
for(int i = 0; i < n; i++) {
border1[i] = x[i,0];
border2[i] = x[i,n-1];
border3[i] = x[0,i];
border4[i] = x[n-1,i];
for (int i = 0; i < n; i++) {
border1[i] = x[i, 0];
border2[i] = x[i, n - 1];
border3[i] = x[0, i];
border4[i] = x[n - 1, i];
}
solver.Add(border1.Sum() == border_sum);
solver.Add(border2.Sum() == border_sum);
solver.Add(border3.Sum() == border_sum);
solver.Add(border4.Sum() == border_sum);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.CHOOSE_PATH,
Solver.ASSIGN_MIN_VALUE);
DecisionBuilder db =
solver.MakePhase(x_flat, Solver.CHOOSE_PATH, Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.WriteLine("total_sum: {0} ", total_sum.Value());
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++){
Console.Write("{0} ", x[i,j].Value());
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write("{0} ", x [i, j]
.Value());
}
Console.WriteLine();
}
Console.WriteLine();
}
@@ -106,11 +100,9 @@ public class Seseman
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 3;
if (args.Length > 0) {

View File

@@ -20,18 +20,14 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class SetCovering
{
public class SetCovering {
/**
*
* Solves a set covering problem.
* See See http://www.hakank.org/or-tools/set_covering.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SetCovering");
//
@@ -43,12 +39,9 @@ public class SetCovering
int min_distance = 15;
int num_cities = 6;
int[,] distance = {{ 0,10,20,30,30,20},
{10, 0,25,35,20,10},
{20,25, 0,15,30,20},
{30,35,15, 0,15,25},
{30,20,30,15, 0,14},
{20,10,20,25,14, 0}};
int[, ] distance = {{0, 10, 20, 30, 30, 20}, {10, 0, 25, 35, 20, 10},
{20, 25, 0, 15, 30, 20}, {30, 35, 15, 0, 15, 25},
{30, 20, 30, 15, 0, 14}, {20, 10, 20, 25, 14, 0}};
//
// Decision variables
@@ -61,34 +54,33 @@ public class SetCovering
//
// ensure that all cities are covered
for(int i = 0; i < num_cities; i++) {
for (int i = 0; i < num_cities; i++) {
IntVar[] b = (from j in Enumerable.Range(0, num_cities)
where distance[i,j] <= min_distance
select x[j]).ToArray();
where distance[i, j] <= min_distance select x[j])
.ToArray();
solver.Add(b.Sum() >= 1);
}
//
//
// objective
//
OptimizeVar objective = z.Minimize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, objective);
while (solver.NextSolution()) {
Console.WriteLine("z: {0}", z.Value());
Console.Write("x: ");
for(int i = 0; i < num_cities; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < num_cities; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -99,11 +91,7 @@ public class SetCovering
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,18 +19,14 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class SetCovering2
{
public class SetCovering2 {
/**
*
* Solves a set covering problem.
* See See http://www.hakank.org/or-tools/set_covering2.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SetCovering2");
//
@@ -43,22 +39,13 @@ public class SetCovering2
// Minimize the number of security telephones in street
// corners on a campus.
int n = 8; // maximum number of corners
int num_streets = 11; // number of connected streets
int n = 8; // maximum number of corners
int num_streets = 11; // number of connected streets
// corners of each street
// Note: 1-based (handled below)
int[,] corner = {{1,2},
{2,3},
{4,5},
{7,8},
{6,7},
{2,6},
{1,6},
{4,7},
{2,4},
{5,8},
{3,5}};
int[, ] corner = {{1, 2}, {2, 3}, {4, 5}, {7, 8}, {6, 7}, {2, 6},
{1, 6}, {4, 7}, {2, 4}, {5, 8}, {3, 5}};
//
// Decision variables
@@ -72,8 +59,8 @@ public class SetCovering2
//
// ensure that all streets are covered
for(int i = 0; i < num_streets; i++) {
solver.Add(x[corner[i,0] - 1] + x[corner[i,1] - 1] >= 1);
for (int i = 0; i < num_streets; i++) {
solver.Add(x[corner[i, 0] - 1] + x[corner[i, 1] - 1] >= 1);
}
//
@@ -84,17 +71,18 @@ public class SetCovering2
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, objective);
while (solver.NextSolution()) {
Console.WriteLine("z: {0}", z.Value());
Console.Write("x: ");
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -105,11 +93,7 @@ public class SetCovering2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,18 +19,14 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class SetCovering3
{
public class SetCovering3 {
/**
*
* Solves a set covering problem.
* See See http://www.hakank.org/or-tools/set_covering3.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SetCovering3");
//
@@ -45,14 +41,13 @@ public class SetCovering3
int num_senators = 10;
// which group does a senator belong to?
int[,] belongs = {{1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 1 southern
int[, ] belongs = {{1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 1 southern
{0, 0, 0, 0, 0, 1, 1, 1, 1, 1}, // 2 northern
{0, 1, 1, 0, 0, 0, 0, 1, 1, 1}, // 3 liberals
{1, 0, 0, 0, 1, 1, 1, 0, 0, 0}, // 4 conservative
{0, 0, 1, 1, 1, 1, 1, 0, 1, 0}, // 5 democrats
{1, 1, 0, 0, 0, 0, 0, 1, 0, 1}}; // 6 republicans
//
// Decision variables
//
@@ -66,53 +61,50 @@ public class SetCovering3
// ensure that each group is covered by at least
// one senator
for(int i = 0; i < num_groups; i++) {
for (int i = 0; i < num_groups; i++) {
IntVar[] b = new IntVar[num_senators];
for(int j = 0; j < num_senators; j++) {
b[j] = (x[j]*belongs[i,j]).Var();
for (int j = 0; j < num_senators; j++) {
b[j] = (x[j] * belongs[i, j]).Var();
}
solver.Add(b.Sum() >= 1);
}
//
// objective
//
OptimizeVar objective = z.Minimize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, objective);
while (solver.NextSolution()) {
Console.WriteLine("z: " + z.Value());
Console.Write("x: ");
for(int j = 0; j < num_senators; j++) {
Console.Write(x[j].Value() + " ");
for (int j = 0; j < num_senators; j++) {
Console.Write(x [j]
.Value() +
" ");
}
Console.WriteLine();
// More details
for(int j = 0; j < num_senators; j++) {
if (x[j].Value() == 1) {
Console.Write("Senator " + (1 + j) +
" belongs to these groups: ");
for(int i = 0; i < num_groups; i++) {
if (belongs[i,j] == 1) {
for (int j = 0; j < num_senators; j++) {
if (x [j]
.Value() == 1) {
Console.Write("Senator " + (1 + j) + " belongs to these groups: ");
for (int i = 0; i < num_groups; i++) {
if (belongs[i, j] == 1) {
Console.Write((1 + i) + " ");
}
}
Console.WriteLine();
}
}
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -121,11 +113,7 @@ public class SetCovering3
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,18 +19,14 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class SetCovering4
{
public class SetCovering4 {
/**
*
* Solves a set covering problem.
* See See http://www.hakank.org/or-tools/set_covering4.py
*
*/
private static void Solve(int set_partition)
{
private static void Solve(int set_partition) {
Solver solver = new Solver("SetCovering4");
//
@@ -49,18 +45,17 @@ public class SetCovering4
int[] costs = {19, 16, 18, 13, 15, 19, 15, 17, 16, 15};
// the alternatives, and their objects
int[,] a = {
// 1 2 3 4 5 6 7 8 the objects
{1,0,0,0,0,1,0,0}, // alternative 1
{0,1,0,0,0,1,0,1}, // alternative 2
{1,0,0,1,0,0,1,0}, // alternative 3
{0,1,1,0,1,0,0,0}, // alternative 4
{0,1,0,0,1,0,0,0}, // alternative 5
{0,1,1,0,0,0,0,0}, // alternative 6
{0,1,1,1,0,0,0,0}, // alternative 7
{0,0,0,1,1,0,0,1}, // alternative 8
{0,0,1,0,0,1,0,1}, // alternative 9
{1,0,0,0,0,1,1,0}}; // alternative 10
int[, ] a = { // 1 2 3 4 5 6 7 8 the objects
{1, 0, 0, 0, 0, 1, 0, 0}, // alternative 1
{0, 1, 0, 0, 0, 1, 0, 1}, // alternative 2
{1, 0, 0, 1, 0, 0, 1, 0}, // alternative 3
{0, 1, 1, 0, 1, 0, 0, 0}, // alternative 4
{0, 1, 0, 0, 1, 0, 0, 0}, // alternative 5
{0, 1, 1, 0, 0, 0, 0, 0}, // alternative 6
{0, 1, 1, 1, 0, 0, 0, 0}, // alternative 7
{0, 0, 0, 1, 1, 0, 0, 1}, // alternative 8
{0, 0, 1, 0, 0, 1, 0, 1}, // alternative 9
{1, 0, 0, 0, 0, 1, 1, 0}}; // alternative 10
//
// Decision variables
@@ -73,11 +68,10 @@ public class SetCovering4
// Constraints
//
for(int j = 0; j < num_objects; j++) {
for (int j = 0; j < num_objects; j++) {
IntVar[] b = new IntVar[num_alternatives];
for(int i = 0; i < num_alternatives; i++) {
b[i] = (x[i] * a[i,j]).Var();
for (int i = 0; i < num_alternatives; i++) {
b[i] = (x[i] * a[i, j]).Var();
}
if (set_partition == 1) {
@@ -87,32 +81,29 @@ public class SetCovering4
}
}
//
// objective
//
OptimizeVar objective = z.Minimize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, objective);
while (solver.NextSolution()) {
Console.WriteLine("z: " + z.Value());
Console.Write("Selected alternatives: ");
for(int i = 0; i < num_alternatives; i++) {
if (x[i].Value() == 1) {
Console.Write((i+1) + " ");
for (int i = 0; i < num_alternatives; i++) {
if (x [i]
.Value() == 1) {
Console.Write((i + 1) + " ");
}
}
Console.WriteLine("\n");
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -121,11 +112,9 @@ public class SetCovering4
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
Console.WriteLine("Set partition:");
Solve(1);
Console.WriteLine("\nSet covering:");

View File

@@ -20,18 +20,14 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class SetCoveringDeployment
{
public class SetCoveringDeployment {
/**
*
* Solves a set covering deployment problem.
* See See http://www.hakank.org/or-tools/set_covering_deployment.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SetCoveringDeployment");
//
@@ -39,26 +35,16 @@ public class SetCoveringDeployment
//
// From http://mathworld.wolfram.com/SetCoveringDeployment.html
string[] countries = {"Alexandria",
"Asia Minor",
"Britain",
"Byzantium",
"Gaul",
"Iberia",
"Rome",
"Tunis"};
string[] countries = {"Alexandria", "Asia Minor", "Britain", "Byzantium",
"Gaul", "Iberia", "Rome", "Tunis"};
int n = countries.Length;
// the incidence matrix (neighbours)
int[,] mat = {{0, 1, 0, 1, 0, 0, 1, 1},
{1, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 0, 0},
{1, 1, 0, 0, 0, 0, 1, 0},
{0, 0, 1, 0, 0, 1, 1, 0},
{0, 0, 1, 0, 1, 0, 1, 1},
{1, 0, 0, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 1, 1, 0}};
int[, ] mat = {{0, 1, 0, 1, 0, 0, 1, 1}, {1, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 0, 0}, {1, 1, 0, 0, 0, 0, 1, 0},
{0, 0, 1, 0, 0, 1, 1, 0}, {0, 0, 1, 0, 1, 0, 1, 1},
{1, 0, 0, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 1, 1, 0}};
//
// Decision variables
@@ -73,7 +59,6 @@ public class SetCoveringDeployment
// total number of armies
IntVar num_armies = (x.Sum() + y.Sum()).Var();
//
// Constraints
//
@@ -84,7 +69,7 @@ public class SetCoveringDeployment
// Or rather: Is there a backup, there
// must be an an army
//
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
solver.Add(x[i] >= y[i]);
}
@@ -92,45 +77,41 @@ public class SetCoveringDeployment
// Constraint 2: There should always be an backup
// army near every city
//
for(int i = 0; i < n; i++) {
IntVar[] count_neighbours = (
from j in Enumerable.Range(0, n)
where mat[i,j] == 1
select(y[j])).ToArray();
for (int i = 0; i < n; i++) {
IntVar[] count_neighbours =
(from j in Enumerable.Range(0, n) where mat[i, j] == 1 select(y[j]))
.ToArray();
solver.Add((x[i] + count_neighbours.Sum()) >= 1);
}
//
// objective
//
OptimizeVar objective = num_armies.Minimize(1);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, objective);
while (solver.NextSolution()) {
Console.WriteLine("num_armies: " + num_armies.Value());
for(int i = 0; i < n; i++) {
if (x[i].Value() == 1) {
for (int i = 0; i < n; i++) {
if (x [i]
.Value() == 1) {
Console.Write("Army: " + countries[i] + " ");
}
if (y[i].Value() == 1) {
if (y [i]
.Value() == 1) {
Console.WriteLine(" Reverse army: " + countries[i]);
}
}
Console.WriteLine("\n");
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -139,11 +120,7 @@ public class SetCoveringDeployment
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -18,8 +18,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class SetCoveringSkiena
{
public class SetCoveringSkiena {
/**
*
* Set covering.
@@ -39,9 +38,7 @@ public class SetCoveringSkiena
* Also see http://www.hakank.org/or-tools/set_covering_skiena.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SetCoveringSkiena");
int num_sets = 7;
@@ -50,18 +47,16 @@ public class SetCoveringSkiena
IEnumerable<int> Elements = Enumerable.Range(0, num_elements);
// Which element belongs to which set
int[,] belongs =
{
int[, ] belongs = {
// 1 2 3 4 5 6 7 8 9 0 1 2 elements
{1,1,0,0,0,0,0,0,0,0,0,0}, // Set 1
{0,1,0,0,0,0,0,1,0,0,0,0}, // 2
{0,0,0,0,1,1,0,0,0,0,0,0}, // 3
{0,0,0,0,0,1,1,0,0,1,1,0}, // 4
{0,0,0,0,0,0,0,0,1,1,0,0}, // 5
{1,1,1,0,1,0,0,0,1,1,1,0}, // 6
{0,0,1,1,0,0,1,1,0,0,1,1} // 7
};
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Set 1
{0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // 2
{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, // 3
{0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0}, // 4
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}, // 5
{1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0}, // 6
{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1} // 7
};
//
// Decision variables
@@ -69,22 +64,23 @@ public class SetCoveringSkiena
IntVar[] x = solver.MakeIntVarArray(num_sets, 0, 1, "x");
IntVar z = x.Sum().VarWithName("z");
// total number of elements in the choosen sets
IntVar tot_elements = solver.MakeIntVar(0, num_sets*num_elements, "tot_elements");
IntVar tot_elements =
solver.MakeIntVar(0, num_sets * num_elements, "tot_elements");
//
// Constraints
//
// all sets must be used
foreach(int j in Elements) {
solver.Add( (from i in Sets select belongs[i,j] * x[i])
.ToArray().Sum() >= 1);
foreach (int j in Elements) {
solver.Add((from i in Sets select belongs[i, j] * x[i]).ToArray().Sum() >=
1);
}
// number of used elements
solver.Add((from i in Sets from j in Elements select x[i] * belongs[i,j])
.ToArray().Sum() == tot_elements);
solver.Add((from i in Sets from j in Elements select x[i] * belongs[i, j])
.ToArray()
.Sum() == tot_elements);
//
// Objective
@@ -94,20 +90,20 @@ public class SetCoveringSkiena
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x, Solver.INT_VAR_DEFAULT, Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.WriteLine("z: {0}", z.Value());
Console.WriteLine("tot_elements: {0}", tot_elements.Value());
Console.WriteLine(
"x: {0}",
String.Join(" ", (from i in Enumerable.Range(0, num_sets)
select x[i].Value().ToString()).ToArray()));
Console.WriteLine("x: {0}",
String.Join(" ", (from i in Enumerable
.Range(0, num_sets) select x [i]
.Value()
.ToString())
.ToArray()));
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -116,11 +112,7 @@ public class SetCoveringSkiena
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,36 +19,32 @@ using System.Linq;
using System.Diagnostics;
using Google.OrTools.ConstraintSolver;
public class SetPartition
{
//
// Partition the sets (binary matrix representation).
//
public static void partition_sets(Solver solver,
IntVar[,] x, int num_sets, int n)
{
for(int i = 0; i <num_sets; i++) {
for(int j = 0; j <num_sets; j++) {
if (i != j) {
// b = solver.Sum([x[i,k]*x[j,k] for k in range(n)]);
// solver.Add(b == 0);
solver.Add( (from k in Enumerable.Range(0, n)
select (x[i,k]*x[j,k])).
ToArray().Sum() == 0);
}
public class SetPartition {
//
// Partition the sets (binary matrix representation).
//
public static void partition_sets(Solver solver, IntVar[, ] x, int num_sets,
int n) {
for (int i = 0; i < num_sets; i++) {
for (int j = 0; j < num_sets; j++) {
if (i != j) {
// b = solver.Sum([x[i,k]*x[j,k] for k in range(n)]);
// solver.Add(b == 0);
solver.Add(
(from k in Enumerable.Range(0, n) select(x[i, k] * x[j, k]))
.ToArray()
.Sum() == 0);
}
}
// ensure that all integers is in
// (exactly) one partition
solver.Add( (from i in Enumerable.Range(0, num_sets)
from j in Enumerable.Range(0, n)
select x[i,j]).ToArray().Sum() == n);
}
// ensure that all integers is in
// (exactly) one partition
solver.Add((from i in Enumerable.Range(0, num_sets)
from j in Enumerable.Range(0, n) select x[i, j])
.ToArray()
.Sum() == n);
}
/**
*
@@ -74,9 +70,7 @@ public class SetPartition
* Also see http://www.hakank.org/or-tools/set_partition.py
*
*/
private static void Solve(int n=16, int num_sets=2)
{
private static void Solve(int n = 16, int num_sets = 2) {
Solver solver = new Solver("SetPartition");
Console.WriteLine("n: {0}", n);
@@ -85,14 +79,12 @@ public class SetPartition
IEnumerable<int> Sets = Enumerable.Range(0, num_sets);
IEnumerable<int> NRange = Enumerable.Range(0, n);
//
// Decision variables
//
IntVar[,] a = solver.MakeIntVarMatrix(num_sets, n, 0, 1, "a");
IntVar[, ] a = solver.MakeIntVarMatrix(num_sets, n, 0, 1, "a");
IntVar[] a_flat = a.Flatten();
//
// Constraints
//
@@ -100,75 +92,70 @@ public class SetPartition
// partition set
partition_sets(solver, a, num_sets, n);
foreach(int i in Sets) {
foreach(int j in Sets) {
foreach (int i in Sets) {
foreach (int j in Sets) {
// same cardinality
solver.Add(
(from k in NRange select a[i,k]).ToArray().Sum()
==
(from k in NRange select a[j,k]).ToArray().Sum());
solver.Add((from k in NRange select a[i, k]).ToArray().Sum() ==
(from k in NRange select a[j, k]).ToArray().Sum());
// same sum
solver.Add(
(from k in NRange select (k*a[i,k])).ToArray().Sum()
==
(from k in NRange select (k*a[j,k])).ToArray().Sum());
solver.Add((from k in NRange select(k * a[i, k])).ToArray().Sum() ==
(from k in NRange select(k * a[j, k])).ToArray().Sum());
// same sum squared
solver.Add(
(from k in NRange select (k*a[i,k]*k*a[i,k])).ToArray().Sum()
==
(from k in NRange select (k*a[j,k]*k*a[j,k])).ToArray().Sum());
solver.Add((from k in NRange select(k * a[i, k] * k * a[i, k]))
.ToArray()
.Sum() ==
(from k in NRange select(k * a[j, k] * k * a[j, k]))
.ToArray()
.Sum());
}
}
// symmetry breaking for num_sets == 2
if (num_sets == 2) {
solver.Add(a[0,0] == 1);
solver.Add(a[0, 0] == 1);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(a_flat,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(a_flat, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
int[,] a_val = new int[num_sets, n];
foreach(int i in Sets) {
foreach(int j in NRange) {
a_val[i,j] = (int)a[i,j].Value();
int[, ] a_val = new int[num_sets, n];
foreach (int i in Sets) {
foreach (int j in NRange) {
a_val[i, j] = (int) a [i, j]
.Value();
}
}
Console.WriteLine("sums: {0}",
(from j in NRange
select (j+1)*a_val[0,j]).ToArray().Sum());
Console.WriteLine(
"sums: {0}",
(from j in NRange select(j + 1) * a_val[0, j]).ToArray().Sum());
Console.WriteLine("sums squared: {0}",
(from j in NRange
select (int)Math.Pow((j+1)*a_val[0,j],2)).ToArray().Sum());
Console.WriteLine(
"sums squared: {0}",
(from j in NRange select(int) Math.Pow((j + 1) * a_val[0, j], 2))
.ToArray()
.Sum());
// Show the numbers in each set
foreach(int i in Sets) {
if ( (from j in NRange select a_val[i,j]).ToArray().Sum() > 0 ) {
Console.Write(i+1 + ": ");
foreach(int j in NRange) {
if (a_val[i,j] == 1) {
Console.Write((j+1) + " ");
foreach (int i in Sets) {
if ((from j in NRange select a_val[i, j]).ToArray().Sum() > 0) {
Console.Write(i + 1 + ": ");
foreach (int j in NRange) {
if (a_val[i, j] == 1) {
Console.Write((j + 1) + " ");
}
}
Console.WriteLine();
}
}
Console.WriteLine();
}
Console.WriteLine("\nSolutions: {0}", solver.Solutions());
@@ -177,11 +164,9 @@ public class SetPartition
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int n = 16;
int num_sets = 2;
@@ -194,11 +179,10 @@ public class SetPartition
}
if (n % num_sets == 0) {
Solve(n, num_sets);
} else {
Console.WriteLine("n {0} num_sets {1}: Equal sets is not possible!",
n, num_sets);
Console.WriteLine("n {0} num_sets {1}: Equal sets is not possible!", n,
num_sets);
}
}
}

View File

@@ -19,8 +19,7 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class SichermanDice
{
public class SichermanDice {
/**
*
* Sicherman Dice.
@@ -64,8 +63,7 @@ public class SichermanDice
* Also see http://www.hakank.org/or-tools/sicherman_dice.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SichermanDice");
//
@@ -76,12 +74,10 @@ public class SichermanDice
int lowest_value = 0;
// standard distribution
int[] standard_dist = {1,2,3,4,5,6,5,4,3,2,1};
int[] standard_dist = {1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1};
IEnumerable<int> RANGE = Enumerable.Range(0, n);
IEnumerable<int> RANGE1 = Enumerable.Range(0, n-1);
IEnumerable<int> RANGE1 = Enumerable.Range(0, n - 1);
//
// Decision variables
@@ -93,38 +89,40 @@ public class SichermanDice
//
// Constraints
//
for(int k = 0; k < standard_dist.Length; k++) {
solver.Add((from i in RANGE
from j in RANGE
select x1[i] + x2[j] == k + 2
).ToArray().Sum() == standard_dist[k]);
for (int k = 0; k < standard_dist.Length; k++) {
solver.Add((from i in RANGE from j in RANGE select x1[i] + x2[j] == k + 2)
.ToArray()
.Sum() == standard_dist[k]);
}
// symmetry breaking
foreach(int i in RANGE1) {
solver.Add(x1[i] <= x1[i+1]);
solver.Add(x2[i] <= x2[i+1]);
foreach (int i in RANGE1) {
solver.Add(x1[i] <= x1[i + 1]);
solver.Add(x2[i] <= x2[i + 1]);
solver.Add(x1[i] <= x2[i]);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x1.Concat(x2).ToArray(),
Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
DecisionBuilder db =
solver.MakePhase(x1.Concat(x2).ToArray(), Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x1: ");
foreach(int i in RANGE) {
Console.Write(x1[i].Value() + " ");
foreach (int i in RANGE) {
Console.Write(x1 [i]
.Value() +
" ");
}
Console.Write("\nx2: ");
foreach(int i in RANGE) {
Console.Write(x2[i].Value() + " ");
foreach (int i in RANGE) {
Console.Write(x2 [i]
.Value() +
" ");
}
Console.WriteLine("\n");
}
@@ -135,11 +133,7 @@ public class SichermanDice
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,8 +19,7 @@ using System.Collections;
using System.Collections.Generic;
using Google.OrTools.ConstraintSolver;
public class SkiAssignment
{
public class SkiAssignment {
/**
*
* Ski assignment in Google CP Solver.
@@ -50,8 +49,7 @@ public class SkiAssignment
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SkiAssignment");
//
@@ -65,8 +63,7 @@ public class SkiAssignment
//
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(num_skiers, 0, num_skis-1, "x");
IntVar[] x = solver.MakeIntVarArray(num_skiers, 0, num_skis - 1, "x");
//
// Constraints
@@ -74,7 +71,7 @@ public class SkiAssignment
solver.Add(x.AllDifferent());
IntVar[] z_tmp = new IntVar[num_skiers];
for(int i = 0; i < num_skiers; i++) {
for (int i = 0; i < num_skiers; i++) {
z_tmp[i] = (ski_heights.Element(x[i]) - skier_heights[i]).Abs().Var();
}
@@ -92,16 +89,17 @@ public class SkiAssignment
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db, obj);
while (solver.NextSolution()) {
Console.Write("z: {0} x: ", z.Value());
for(int i = 0; i < num_skiers; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < num_skiers; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -112,11 +110,7 @@ public class SkiAssignment
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,18 +19,14 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class StableMarriage
{
public class StableMarriage {
/**
*
* Solves some stable marriage problems.
* See http://www.hakank.org/or-tools/stable_marriage.py
*
*/
private static void Solve(int[][][] ranks, String problem_name)
{
private static void Solve(int[][][] ranks, String problem_name) {
Solver solver = new Solver("StableMarriage");
//
@@ -42,7 +38,7 @@ public class StableMarriage
Console.WriteLine("Problem: " + problem_name);
int[][] rankWomen = ranks[0];
int[][] rankMen = ranks[1];
int[][] rankMen = ranks[1];
//
// Decision variables
@@ -58,57 +54,66 @@ public class StableMarriage
//
// forall(m in Men)
// cp.post(husband[wife[m]] == m);
for(int m = 0; m < n; m++) {
for (int m = 0; m < n; m++) {
solver.Add(husband.Element(wife[m]) == m);
}
// forall(w in Women)
// cp.post(wife[husband[w]] == w);
for(int w = 0; w < n; w++) {
for (int w = 0; w < n; w++) {
solver.Add(wife.Element(husband[w]) == w);
}
// forall(m in Men, o in Women)
// cp.post(rankMen[m,o] < rankMen[m, wife[m]] =>
// rankWomen[o,husband[o]] < rankWomen[o,m]);
for(int m = 0; m < n; m++) {
for(int o = 0; o < n; o++) {
IntVar b1 = rankMen[m].Element(wife[m]) > rankMen[m][o];
IntVar b2 = rankWomen[o].Element(husband[o]) < rankWomen[o][m];
for (int m = 0; m < n; m++) {
for (int o = 0; o < n; o++) {
IntVar b1 = rankMen [m]
.Element(wife[m]) > rankMen [m]
[o];
IntVar b2 = rankWomen [o]
.Element(husband[o]) < rankWomen [o]
[m];
solver.Add(b1 <= b2);
}
}
// forall(w in Women, o in Men)
// cp.post(rankWomen[w,o] < rankWomen[w,husband[w]] =>
// rankMen[o,wife[o]] < rankMen[o,w]);
for(int w = 0; w < n; w++) {
for(int o = 0; o < n; o++) {
IntVar b1 = rankWomen[w].Element(husband[w]) > rankWomen[w][o];
IntVar b2 = rankMen[o].Element(wife[o]) < rankMen[o][w];
for (int w = 0; w < n; w++) {
for (int o = 0; o < n; o++) {
IntVar b1 = rankWomen [w]
.Element(husband[w]) > rankWomen [w]
[o];
IntVar b2 = rankMen [o]
.Element(wife[o]) < rankMen [o]
[w];
solver.Add(b1 <= b2);
}
}
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(wife,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(wife, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("wife : ");
for(int i = 0; i < n; i++) {
Console.Write(wife[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(wife [i]
.Value() +
" ");
}
Console.Write("\nhusband: ");
for(int i = 0; i < n; i++) {
Console.Write(husband[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(husband [i]
.Value() +
" ");
}
Console.WriteLine("\n");
}
@@ -119,84 +124,61 @@ public class StableMarriage
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
//
// From Pascal Van Hentenryck's OPL book
//
int[][][] van_hentenryck = {
// rankWomen
new int[][] {
new int[] {1, 2, 4, 3, 5},
new int[] {3, 5, 1, 2, 4},
new int[] {5, 4, 2, 1, 3},
new int[] {1, 3, 5, 4, 2},
new int[] {4, 2, 3, 5, 1}},
// rankWomen
new int[][]{new int[]{1, 2, 4, 3, 5}, new int[]{3, 5, 1, 2, 4},
new int[]{5, 4, 2, 1, 3}, new int[]{1, 3, 5, 4, 2},
new int[]{4, 2, 3, 5, 1}},
// rankMen
new int[][] {
new int[] {5, 1, 2, 4, 3},
new int[] {4, 1, 3, 2, 5},
new int[] {5, 3, 2, 4, 1},
new int[] {1, 5, 4, 3, 2},
new int[] {4, 3, 2, 1, 5}}
};
// rankMen
new int[][]{new int[]{5, 1, 2, 4, 3}, new int[]{4, 1, 3, 2, 5},
new int[]{5, 3, 2, 4, 1}, new int[]{1, 5, 4, 3, 2},
new int[]{4, 3, 2, 1, 5}}};
//
// Data from MathWorld
// http://mathworld.wolfram.com/StableMarriageProblem.html
//
int[][][] mathworld = {
// rankWomen
new int[][] {
new int[] {3, 1, 5, 2, 8, 7, 6, 9, 4},
new int[] {9, 4, 8, 1, 7, 6, 3, 2, 5},
new int[] {3, 1, 8, 9, 5, 4, 2, 6, 7},
new int[] {8, 7, 5, 3, 2, 6, 4, 9, 1},
new int[] {6, 9, 2, 5, 1, 4, 7, 3, 8},
new int[] {2, 4, 5, 1, 6, 8, 3, 9, 7},
new int[] {9, 3, 8, 2, 7, 5, 4, 6, 1},
new int[] {6, 3, 2, 1, 8, 4, 5, 9, 7},
new int[] {8, 2, 6, 4, 9, 1, 3, 7, 5}},
int[][][] mathworld = {// rankWomen
new int[][]{new int[]{3, 1, 5, 2, 8, 7, 6, 9, 4},
new int[]{9, 4, 8, 1, 7, 6, 3, 2, 5},
new int[]{3, 1, 8, 9, 5, 4, 2, 6, 7},
new int[]{8, 7, 5, 3, 2, 6, 4, 9, 1},
new int[]{6, 9, 2, 5, 1, 4, 7, 3, 8},
new int[]{2, 4, 5, 1, 6, 8, 3, 9, 7},
new int[]{9, 3, 8, 2, 7, 5, 4, 6, 1},
new int[]{6, 3, 2, 1, 8, 4, 5, 9, 7},
new int[]{8, 2, 6, 4, 9, 1, 3, 7, 5}},
// rankMen
new int[][] {
new int[] {7, 3, 8, 9, 6, 4, 2, 1, 5},
new int[] {5, 4, 8, 3, 1, 2, 6, 7, 9},
new int[] {4, 8, 3, 9, 7, 5, 6, 1, 2},
new int[] {9, 7, 4, 2, 5, 8, 3, 1, 6},
new int[] {2, 6, 4, 9, 8, 7, 5, 1, 3},
new int[] {2, 7, 8, 6, 5, 3, 4, 1, 9},
new int[] {1, 6, 2, 3, 8, 5, 4, 9, 7},
new int[] {5, 6, 9, 1, 2, 8, 4, 3, 7},
new int[] {6, 1, 4, 7, 5, 8, 3, 9, 2}}
};
// rankMen
new int[][]{new int[]{7, 3, 8, 9, 6, 4, 2, 1, 5},
new int[]{5, 4, 8, 3, 1, 2, 6, 7, 9},
new int[]{4, 8, 3, 9, 7, 5, 6, 1, 2},
new int[]{9, 7, 4, 2, 5, 8, 3, 1, 6},
new int[]{2, 6, 4, 9, 8, 7, 5, 1, 3},
new int[]{2, 7, 8, 6, 5, 3, 4, 1, 9},
new int[]{1, 6, 2, 3, 8, 5, 4, 9, 7},
new int[]{5, 6, 9, 1, 2, 8, 4, 3, 7},
new int[]{6, 1, 4, 7, 5, 8, 3, 9, 2}}};
//
// Data from
// http://www.csee.wvu.edu/~ksmani/courses/fa01/random/lecnotes/lecture5.pdf
//
int[][][] problem3 = {
// rankWomen
new int[][] {
new int[] {1,2,3,4},
new int[] {4,3,2,1},
new int[] {1,2,3,4},
new int[] {3,4,1,2}},
// rankMen
new int[][] {
new int[] {1,2,3,4},
new int[] {2,1,3,4},
new int[] {1,4,3,2},
new int[] {4,3,1,2}}
};
// rankWomen
new int[][]{new int[]{1, 2, 3, 4}, new int[]{4, 3, 2, 1},
new int[]{1, 2, 3, 4}, new int[]{3, 4, 1, 2}},
// rankMen
new int[][]{new int[]{1, 2, 3, 4}, new int[]{2, 1, 3, 4},
new int[]{1, 4, 3, 2}, new int[]{4, 3, 1, 2}}};
//
// Data from
@@ -204,29 +186,19 @@ public class StableMarriage
// page 4
//
int[][][] problem4 = {
// rankWomen
new int[][] {
new int[] {1,5,4,6,2,3},
new int[] {4,1,5,2,6,3},
new int[] {6,4,2,1,5,3},
new int[] {1,5,2,4,3,6},
new int[] {4,2,1,5,6,3},
new int[] {2,6,3,5,1,4}},
// rankMen
new int[][] {
new int[] {1,4,2,5,6,3},
new int[] {3,4,6,1,5,2},
new int[] {1,6,4,2,3,5},
new int[] {6,5,3,4,2,1},
new int[] {3,1,2,4,5,6},
new int[] {2,3,1,6,5,4}}};
// rankWomen
new int[][]{new int[]{1, 5, 4, 6, 2, 3}, new int[]{4, 1, 5, 2, 6, 3},
new int[]{6, 4, 2, 1, 5, 3}, new int[]{1, 5, 2, 4, 3, 6},
new int[]{4, 2, 1, 5, 6, 3}, new int[]{2, 6, 3, 5, 1, 4}},
// rankMen
new int[][]{new int[]{1, 4, 2, 5, 6, 3}, new int[]{3, 4, 6, 1, 5, 2},
new int[]{1, 6, 4, 2, 3, 5}, new int[]{6, 5, 3, 4, 2, 1},
new int[]{3, 1, 2, 4, 5, 6}, new int[]{2, 3, 1, 6, 5, 4}}};
Solve(van_hentenryck, "Van Hentenryck");
Solve(mathworld, "MathWorld");
Solve(problem3, "Problem 3");
Solve(problem4, "Problem 4");
}
}

View File

@@ -20,42 +20,27 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class Strimko2
{
public class Strimko2 {
/**
*
* Solves a Strimko problem.
* See http://www.hakank.org/google_or_tools/strimko2.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Strimko2");
//
// data
//
int[,] streams = {{1,1,2,2,2,2,2},
{1,1,2,3,3,3,2},
{1,4,1,3,3,5,5},
{4,4,3,1,3,5,5},
{4,6,6,6,7,7,5},
{6,4,6,4,5,5,7},
{6,6,4,7,7,7,7}};
int[, ] streams = {{1, 1, 2, 2, 2, 2, 2}, {1, 1, 2, 3, 3, 3, 2},
{1, 4, 1, 3, 3, 5, 5}, {4, 4, 3, 1, 3, 5, 5},
{4, 6, 6, 6, 7, 7, 5}, {6, 4, 6, 4, 5, 5, 7},
{6, 6, 4, 7, 7, 7, 7}};
// Note: This is 1-based
int[,] placed = {{2,1,1},
{2,3,7},
{2,5,6},
{2,7,4},
{3,2,7},
{3,6,1},
{4,1,4},
{4,7,5},
{5,2,2},
{5,6,6}};
int[, ] placed = {{2, 1, 1}, {2, 3, 7}, {2, 5, 6}, {2, 7, 4}, {3, 2, 7},
{3, 6, 1}, {4, 1, 4}, {4, 7, 5}, {5, 2, 2}, {5, 6, 6}};
int n = streams.GetLength(0);
int num_placed = placed.GetLength(0);
@@ -63,19 +48,19 @@ public class Strimko2
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(n, n, 1, n, "x");
IntVar[] x_flat = x.Flatten();
//
// Constraints
//
// all rows and columns must be unique, i.e. a Latin Square
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
IntVar[] row = new IntVar[n];
IntVar[] col = new IntVar[n];
for(int j = 0; j < n; j++) {
row[j] = x[i,j];
col[j] = x[j,i];
for (int j = 0; j < n; j++) {
row[j] = x[i, j];
col[j] = x[j, i];
}
solver.Add(row.AllDifferent());
@@ -83,34 +68,34 @@ public class Strimko2
}
// streams
for(int s = 1; s <= n; s++) {
IntVar[] tmp = (from i in Enumerable.Range(0, n)
from j in Enumerable.Range(0, n)
where streams[i,j] == s
select x[i,j]).ToArray();
for (int s = 1; s <= n; s++) {
IntVar[] tmp =
(from i in Enumerable.Range(0, n) from j in Enumerable.Range(0, n)
where streams[i, j] == s select x[i, j])
.ToArray();
solver.Add(tmp.AllDifferent());
}
// placed
for(int i = 0; i < num_placed; i++) {
for (int i = 0; i < num_placed; i++) {
// note: also adjust to 0-based
solver.Add(x[placed[i,0] - 1,placed[i,1] - 1] == placed[i,2]);
solver.Add(x[placed[i, 0] - 1, placed[i, 1] - 1] == placed[i, 2]);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.INT_VAR_DEFAULT,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_DEFAULT,
Solver.INT_VALUE_DEFAULT);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
Console.Write(x[i,j].Value() + " ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write(x [i, j]
.Value() +
" ");
}
Console.WriteLine();
}
@@ -123,11 +108,7 @@ public class Strimko2
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,12 +19,8 @@ using System.Collections.Generic;
using System.Linq;
using Google.OrTools.ConstraintSolver;
public class SubsetSum
{
public static IntVar[] subset_sum(Solver solver,
int[] values,
int total) {
public class SubsetSum {
public static IntVar[] subset_sum(Solver solver, int[] values, int total) {
int n = values.Length;
IntVar[] x = solver.MakeIntVarArray(n, 0, n, "x");
solver.Add(x.ScalProd(values) == total);
@@ -32,7 +28,6 @@ public class SubsetSum
return x;
}
/**
*
* Subset sum problem.
@@ -41,7 +36,7 @@ public class SubsetSum
* http://ioe.engin.umich.edu/people/fac/books/murty/opti_model/junior-7.pdf
* """
* Example 7.8.1
*
*
* A bank van had several bags of coins, each containing either
* 16, 17, 23, 24, 39, or 40 coins. While the van was parked on the
* street, thieves stole some bags. A total of 100 coins were lost.
@@ -51,14 +46,12 @@ public class SubsetSum
* Also see http://www.hakank.org/or-tools/subset_sum.py
*
*/
private static void Solve(int[] coins, int total)
{
private static void Solve(int[] coins, int total) {
Solver solver = new Solver("SubsetSum");
int n = coins.Length;
Console.Write("Coins: ");
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
Console.Write(coins[i] + " ");
}
Console.WriteLine("\nTotal: {0}", total);
@@ -69,27 +62,26 @@ public class SubsetSum
// number of coins
IntVar s = solver.MakeIntVar(0, coins.Sum(), "s");
//
// Constraints
//
//
IntVar[] x = subset_sum(solver, coins, total);
solver.Add(x.Sum() == s);
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("x: ");
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
Console.WriteLine(" s: {0}", s.Value());
}
@@ -100,12 +92,9 @@ public class SubsetSum
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
public static void Main(String[] args) {
int[] coins = {16, 17, 23, 24, 39, 40};
int total = 100;

View File

@@ -20,17 +20,13 @@ using System.Linq;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class Sudoku
{
public class Sudoku {
/**
*
* Solves a Sudoku problem.
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("Sudoku");
//
@@ -42,21 +38,17 @@ public class Sudoku
IEnumerable<int> RANGE = Enumerable.Range(0, n);
// 0 marks an unknown value
int[,] initial_grid = {{0, 6, 0, 0, 5, 0, 0, 2, 0},
{0, 0, 0, 3, 0, 0, 0, 9, 0},
{7, 0, 0, 6, 0, 0, 0, 1, 0},
{0, 0, 6, 0, 3, 0, 4, 0, 0},
{0, 0, 4, 0, 7, 0, 1, 0, 0},
{0, 0, 5, 0, 9, 0, 8, 0, 0},
{0, 4, 0, 0, 0, 1, 0, 0, 6},
{0, 3, 0, 0, 0, 8, 0, 0, 0},
{0, 2, 0, 0, 4, 0, 0, 5, 0}};
int[, ] initial_grid = {
{0, 6, 0, 0, 5, 0, 0, 2, 0}, {0, 0, 0, 3, 0, 0, 0, 9, 0},
{7, 0, 0, 6, 0, 0, 0, 1, 0}, {0, 0, 6, 0, 3, 0, 4, 0, 0},
{0, 0, 4, 0, 7, 0, 1, 0, 0}, {0, 0, 5, 0, 9, 0, 8, 0, 0},
{0, 4, 0, 0, 0, 1, 0, 0, 6}, {0, 3, 0, 0, 0, 8, 0, 0, 0},
{0, 2, 0, 0, 4, 0, 0, 5, 0}};
//
// Decision variables
//
IntVar[,] grid = solver.MakeIntVarMatrix(n, n, 1, 9, "grid");
IntVar[, ] grid = solver.MakeIntVarMatrix(n, n, 1, 9, "grid");
IntVar[] grid_flat = grid.Flatten();
//
@@ -64,51 +56,45 @@ public class Sudoku
//
// init
foreach(int i in RANGE) {
foreach(int j in RANGE) {
if (initial_grid[i,j] > 0) {
solver.Add(grid[i,j] == initial_grid[i,j]);
foreach (int i in RANGE) {
foreach (int j in RANGE) {
if (initial_grid[i, j] > 0) {
solver.Add(grid[i, j] == initial_grid[i, j]);
}
}
}
foreach(int i in RANGE) {
foreach (int i in RANGE) {
// rows
solver.Add( (from j in RANGE
select grid[i,j]).ToArray().AllDifferent());
solver.Add((from j in RANGE select grid[i, j]).ToArray().AllDifferent());
// cols
solver.Add( (from j in RANGE
select grid[j,i]).ToArray().AllDifferent());
solver.Add((from j in RANGE select grid[j, i]).ToArray().AllDifferent());
}
// cells
foreach(int i in CELL) {
foreach(int j in CELL) {
solver.Add( (from di in CELL
from dj in CELL
select grid[i*cell_size+di, j*cell_size+dj]
).ToArray().AllDifferent());
foreach (int i in CELL) {
foreach (int j in CELL) {
solver.Add((from di in CELL from dj in CELL select
grid[i * cell_size + di, j * cell_size + dj])
.ToArray()
.AllDifferent());
}
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(grid_flat,
Solver.INT_VAR_SIMPLE,
DecisionBuilder db = solver.MakePhase(grid_flat, Solver.INT_VAR_SIMPLE,
Solver.INT_VALUE_SIMPLE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++){
Console.Write("{0} ", grid[i,j].Value());
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Console.Write("{0} ", grid [i, j]
.Value());
}
Console.WriteLine();
}
@@ -122,12 +108,7 @@ public class Sudoku
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,30 +19,22 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class SurvoPuzzle
{
public class SurvoPuzzle {
//
// default problem
//
//
static int default_r = 3;
static int default_c = 4;
static int[] default_rowsums = {30, 18, 30};
static int[] default_colsums = {27, 16, 10, 25};
static int[,] default_game = {{0, 6, 0, 0},
{8, 0, 0, 0},
{0, 0, 3, 0}};
static int[, ] default_game = {{0, 6, 0, 0}, {8, 0, 0, 0}, {0, 0, 3, 0}};
// for the actual problem
static int r;
static int c;
static int[] rowsums;
static int[] colsums;
static int[,] game;
static int[, ] game;
/**
*
@@ -50,70 +42,63 @@ public class SurvoPuzzle
* See http://www.hakank.org/or-tools/survo_puzzle.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("SurvoPuzzle");
//
// data
//
Console.WriteLine("Problem:");
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
Console.Write(game[i,j] + " ");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
Console.Write(game[i, j] + " ");
}
Console.WriteLine();
}
Console.WriteLine();
//
// Decision variables
//
IntVar[,] x = solver.MakeIntVarMatrix(r, c, 1, r*c, "x");
IntVar[, ] x = solver.MakeIntVarMatrix(r, c, 1, r * c, "x");
IntVar[] x_flat = x.Flatten();
//
// Constraints
//
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
if (game[i,j] > 0) {
solver.Add(x[i,j] == game[i,j]);
//
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (game[i, j] > 0) {
solver.Add(x[i, j] == game[i, j]);
}
}
}
solver.Add(x_flat.AllDifferent());
//
// calculate rowsums and colsums
//
for(int i = 0; i < r; i++) {
for (int i = 0; i < r; i++) {
IntVar[] row = new IntVar[c];
for(int j = 0; j < c; j++) {
row[j] = x[i,j];
for (int j = 0; j < c; j++) {
row[j] = x[i, j];
}
solver.Add(row.Sum() == rowsums[i]);
}
for(int j = 0; j < c; j++) {
for (int j = 0; j < c; j++) {
IntVar[] col = new IntVar[r];
for(int i = 0; i < r; i++) {
col[i] = x[i,j];
for (int i = 0; i < r; i++) {
col[i] = x[i, j];
}
solver.Add(col.Sum() == colsums[j]);
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(x_flat,
Solver.INT_VAR_SIMPLE,
DecisionBuilder db = solver.MakePhase(x_flat, Solver.INT_VAR_SIMPLE,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
@@ -122,9 +107,10 @@ public class SurvoPuzzle
while (solver.NextSolution()) {
sol++;
Console.WriteLine("Solution #{0} ", sol + " ");
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++){
Console.Write("{0} ", x[i,j].Value());
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
Console.Write("{0} ", x [i, j]
.Value());
}
Console.WriteLine();
}
@@ -137,11 +123,9 @@ public class SurvoPuzzle
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
/**
/**
*
* readFile()
*
@@ -164,63 +148,57 @@ public class SurvoPuzzle
*
*/
private static void readFile(String file) {
Console.WriteLine("readFile(" + file + ")");
TextReader inr = new StreamReader(file);
r = Convert.ToInt32(inr.ReadLine());
c = Convert.ToInt32(inr.ReadLine());
rowsums = new int[r];
colsums = new int[c];
Console.WriteLine("r: " + r + " c: " + c);
String[] rowsums_str = Regex.Split(inr.ReadLine(),",\\s*");
String[] colsums_str = Regex.Split(inr.ReadLine(),",\\s*");
String[] rowsums_str = Regex.Split(inr.ReadLine(), ",\\s*");
String[] colsums_str = Regex.Split(inr.ReadLine(), ",\\s*");
Console.WriteLine("rowsums:");
for(int i = 0; i < r; i++) {
for (int i = 0; i < r; i++) {
Console.Write(rowsums_str[i] + " ");
rowsums[i] = Convert.ToInt32(rowsums_str[i]);
}
Console.WriteLine("\ncolsums:");
for(int j = 0; j < c; j++) {
for (int j = 0; j < c; j++) {
Console.Write(colsums_str[j] + " ");
colsums[j] = Convert.ToInt32(colsums_str[j]);
}
Console.WriteLine();
// init the game matrix and read data from file
game = new int[r,c];
game = new int[r, c];
String str;
int line_count = 0;
while ((str = inr.ReadLine()) != null && str.Length > 0) {
str = str.Trim();
// ignore comments
// starting with either # or %
if(str.StartsWith("#") || str.StartsWith("%")) {
if (str.StartsWith("#") || str.StartsWith("%")) {
continue;
}
String[] this_row = Regex.Split(str, ",\\s*");
for(int j = 0; j < this_row.Length; j++) {
game[line_count,j] = Convert.ToInt32(this_row[j]);
for (int j = 0; j < this_row.Length; j++) {
game[line_count, j] = Convert.ToInt32(this_row[j]);
}
line_count++;
} // end while
inr.Close();
} // end readFile
} // end while
inr.Close();
public static void Main(String[] args)
{
} // end readFile
public static void Main(String[] args) {
String file = "";
if (args.Length > 0) {
file = args[0];

View File

@@ -16,10 +16,7 @@
using System;
using Google.OrTools.ConstraintSolver;
public class ToNumTest
{
public class ToNumTest {
/**
*
* toNum(solver, a, num, base)
@@ -31,22 +28,19 @@ public class ToNumTest
int len = a.Length;
IntVar[] tmp = new IntVar[len];
for(int i = 0; i < len; i++) {
tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var();
for (int i = 0; i < len; i++) {
tmp[i] = (a[i] * (int) Math.Pow(bbase, (len - i - 1))).Var();
}
return tmp.Sum() == num;
return tmp.Sum() == num;
}
/**
*
* Implements toNum: channeling between a number and an array.
* See http://www.hakank.org/or-tools/toNum.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("ToNum");
int n = 5;
@@ -56,7 +50,7 @@ public class ToNumTest
// Decision variables
//
IntVar[] x = solver.MakeIntVarArray(n, 0, bbase - 1, "x");
IntVar num = solver.MakeIntVar(0, (int)Math.Pow(bbase, n) - 1, "num");
IntVar num = solver.MakeIntVar(0, (int) Math.Pow(bbase, n) - 1, "num");
//
// Constraints
@@ -72,16 +66,17 @@ public class ToNumTest
//
// Search
//
DecisionBuilder db = solver.MakePhase(x,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
Console.Write("\n" + num.Value() + ": ");
for(int i = 0; i < n; i++) {
Console.Write(x[i].Value() + " ");
for (int i = 0; i < n; i++) {
Console.Write(x [i]
.Value() +
" ");
}
}
@@ -91,11 +86,7 @@ public class ToNumTest
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -19,9 +19,7 @@ using System.IO;
using System.Text.RegularExpressions;
using Google.OrTools.ConstraintSolver;
public class TrafficLights
{
public class TrafficLights {
/**
*
* Traffic lights problem.
@@ -30,28 +28,31 @@ public class TrafficLights
* http://www.cs.st-andrews.ac.uk/~ianm/CSPLib/prob/prob016/index.html
* """
* Specification:
* Consider a four way traffic junction with eight traffic lights. Four of the traffic
* lights are for the vehicles and can be represented by the variables V1 to V4 with domains
* {r,ry,g,y} (for red, red-yellow, green and yellow). The other four traffic lights are
* for the pedestrians and can be represented by the variables P1 to P4 with domains {r,g}.
* Consider a four way traffic junction with eight traffic lights. Four of the
* traffic lights are for the vehicles and can be represented by the variables
* V1 to V4 with domains {r,ry,g,y} (for red, red-yellow, green and yellow).
* The other four traffic lights are for the pedestrians and can be
* represented by the variables P1 to P4 with domains {r,g}.
*
* The constraints on these variables can be modelled by quaternary constraints on
* (Vi, Pi, Vj, Pj ) for 1<=i<=4, j=(1+i)mod 4 which allow just the tuples
* The constraints on these variables can be modelled by quaternary
* constraints on (Vi, Pi, Vj, Pj ) for 1<=i<=4, j=(1+i)mod 4 which allow just
* the tuples
* {(r,r,g,g), (ry,r,y,r), (g,g,r,r), (y,r,ry,r)}.
*
* It would be interesting to consider other types of junction (e.g. five roads
* intersecting) as well as modelling the evolution over time of the traffic light sequence.
* It would be interesting to consider other types of junction (e.g. five
* roads intersecting) as well as modelling the evolution over time of the
* traffic light sequence.
* ...
*
* Results
* Only 2^2 out of the 2^12 possible assignments are solutions.
*
* (V1,P1,V2,P2,V3,P3,V4,P4) =
* {(r,r,g,g,r,r,g,g), (ry,r,y,r,ry,r,y,r), (g,g,r,r,g,g,r,r), (y,r,ry,r,y,r,ry,r)}
* [(1,1,3,3,1,1,3,3), ( 2,1,4,1, 2,1,4,1), (3,3,1,1,3,3,1,1), (4,1, 2,1,4,1, 2,1)}
* The problem has relative few constraints, but each is very
* tight. Local propagation appears to be rather ineffective on this
* problem.
* {(r,r,g,g,r,r,g,g), (ry,r,y,r,ry,r,y,r), (g,g,r,r,g,g,r,r),
* (y,r,ry,r,y,r,ry,r)}
* [(1,1,3,3,1,1,3,3), ( 2,1,4,1, 2,1,4,1), (3,3,1,1,3,3,1,1), (4,1, 2,1,4,1,
* 2,1)} The problem has relative few constraints, but each is very tight.
* Local propagation appears to be rather ineffective on this problem.
*
* """
* Note: In this model we use only the constraint
@@ -61,9 +62,7 @@ public class TrafficLights
* See http://www.hakank.org/or-tools/traffic_lights.py
*
*/
private static void Solve()
{
private static void Solve() {
Solver solver = new Solver("TrafficLights");
//
@@ -80,48 +79,48 @@ public class TrafficLights
// The allowed combinations
IntTupleSet allowed = new IntTupleSet(4);
allowed.InsertAll(new long[][] {
new long[] {r,r,g,g},
new long[] {ry,r,y,r},
new long[] {g,g,r,r},
new long[] {y,r,ry,r}});
allowed.InsertAll(
new long[][]{new long[]{r, r, g, g}, new long[]{ry, r, y, r},
new long[]{g, g, r, r}, new long[]{y, r, ry, r}});
//
// Decision variables
//
IntVar[] V = solver.MakeIntVarArray(n, 0, n-1, "V");
IntVar[] P = solver.MakeIntVarArray(n, 0, n-1, "P");
IntVar[] V = solver.MakeIntVarArray(n, 0, n - 1, "V");
IntVar[] P = solver.MakeIntVarArray(n, 0, n - 1, "P");
// for search
IntVar[] VP = new IntVar[2 * n];
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
VP[i] = V[i];
VP[i+n] = P[i];
VP[i + n] = P[i];
}
//
// Constraints
//
for(int i = 0; i < n; i++) {
int j = (1+i) % n;
IntVar[] tmp = new IntVar[] {V[i],P[i],V[j],P[j]};
for (int i = 0; i < n; i++) {
int j = (1 + i) % n;
IntVar[] tmp = new IntVar[]{V[i], P[i], V[j], P[j]};
solver.Add(tmp.AllowedAssignments(allowed));
}
//
// Search
//
DecisionBuilder db = solver.MakePhase(VP,
Solver.CHOOSE_FIRST_UNBOUND,
DecisionBuilder db = solver.MakePhase(VP, Solver.CHOOSE_FIRST_UNBOUND,
Solver.ASSIGN_MIN_VALUE);
solver.NewSearch(db);
while (solver.NextSolution()) {
for(int i = 0; i < n; i++) {
for (int i = 0; i < n; i++) {
Console.Write("{0,2} {1,2} ",
lights[V[i].Value()],
lights[P[i].Value()]);
lights [V [i]
.Value()]
,
lights [P [i]
.Value()]
);
}
Console.WriteLine();
}
@@ -132,12 +131,7 @@ public class TrafficLights
Console.WriteLine("Branches: {0} ", solver.Branches());
solver.EndSearch();
}
public static void Main(String[] args)
{
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -28,7 +28,7 @@ public class Volsay {
*/
private static void Solve() {
Solver solver = new Solver(
"Volsay", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
"Volsay", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
//
// Variables
@@ -50,28 +50,22 @@ public class Volsay {
Console.WriteLine("Objective: {0}", solver.Objective().Value());
Console.WriteLine("Gas : {0} ReducedCost: {1}",
Gas.SolutionValue(),
Console.WriteLine("Gas : {0} ReducedCost: {1}", Gas.SolutionValue(),
Gas.ReducedCost());
Console.WriteLine("Chloride : {0} ReducedCost: {1}",
Chloride.SolutionValue(),
Chloride.ReducedCost());
Chloride.SolutionValue(), Chloride.ReducedCost());
double[] activities = solver.ComputeConstraintActivities();
Console.WriteLine("c1 : DualValue: {0} Activity: {1}",
c1.DualValue(),
Console.WriteLine("c1 : DualValue: {0} Activity: {1}", c1.DualValue(),
activities[c1.Index()]);
Console.WriteLine("c2 : DualValue: {0} Activity: {1}",
c2.DualValue(),
Console.WriteLine("c2 : DualValue: {0} Activity: {1}", c2.DualValue(),
activities[c2.Index()]);
Console.WriteLine("\nWallTime: " + solver.WallTime());
Console.WriteLine("Iterations: " + solver.Iterations());
}
public static void Main(String[] args) {
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -30,7 +30,7 @@ public class Volsay2 {
*/
private static void Solve() {
Solver solver = new Solver(
"Volsay2", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
"Volsay2", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
int num_products = 2;
IEnumerable<int> PRODUCTS = Enumerable.Range(0, num_products);
@@ -42,7 +42,7 @@ public class Volsay2 {
// Variables
//
Variable[] production = new Variable[num_products];
foreach(int p in PRODUCTS) {
foreach (int p in PRODUCTS) {
production[p] = solver.MakeNumVar(0, 100000, products[p]);
}
@@ -63,30 +63,33 @@ public class Volsay2 {
return;
}
foreach(int p in PRODUCTS) {
Console.WriteLine("{0,-10}: {1} ReducedCost: {2}",
products[p],
production[p].SolutionValue(),
production[p].ReducedCost());
foreach (int p in PRODUCTS) {
Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", products[p],
production [p]
.SolutionValue(),
production [p]
.ReducedCost());
}
double[] activities = solver.ComputeConstraintActivities();
foreach(int c in CONSTRAINTS) {
foreach (int c in CONSTRAINTS) {
Console.WriteLine(
"Constraint {0} DualValue {1} Activity: {2} lb: {3} ub: {4}",
c.ToString(),
cons[c].DualValue(),
activities[cons[c].Index()],
cons[c].Lb(),
cons[c].Ub());
cons [c]
.DualValue(),
activities [cons [c]
.Index()]
,
cons [c]
.Lb(),
cons [c]
.Ub());
}
Console.WriteLine("\nWallTime: " + solver.WallTime());
Console.WriteLine("Iterations: " + solver.Iterations());
}
public static void Main(String[] args) {
Solve();
}
public static void Main(String[] args) { Solve(); }
}

View File

@@ -31,22 +31,22 @@ public class Volsay3 {
*/
private static void Solve() {
Solver solver = new Solver(
"Volsay3", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
"Volsay3", Solver.OptimizationProblemType.CLP_LINEAR_PROGRAMMING);
int num_products = 2;
IEnumerable<int> PRODUCTS = Enumerable.Range(0, num_products);
String[] products = {"Gas", "Chloride"};
String[] components = {"nitrogen", "hydrogen", "chlorine"};
int[,] demand = { {1,3,0}, {1,4,1}};
int[] profit = {30,40};
int[] stock = {50,180,40};
int[, ] demand = {{1, 3, 0}, {1, 4, 1}};
int[] profit = {30, 40};
int[] stock = {50, 180, 40};
//
// Variables
//
Variable[] production = new Variable[num_products];
foreach(int p in PRODUCTS) {
foreach (int p in PRODUCTS) {
production[p] = solver.MakeNumVar(0, 100000, products[p]);
}
@@ -55,19 +55,18 @@ public class Volsay3 {
//
int c_len = components.Length;
Constraint[] cons = new Constraint[c_len];
for(int c = 0; c < c_len; c++) {
cons[c] = solver.Add( (from p in PRODUCTS
select (demand[p,c]*production[p])).
ToArray().Sum() <= stock[c]);
for (int c = 0; c < c_len; c++) {
cons[c] =
solver.Add((from p in PRODUCTS select(demand[p, c] * production[p]))
.ToArray()
.Sum() <= stock[c]);
}
//
// Objective
//
solver.Maximize( (from p in PRODUCTS
select (profit[p]*production[p])).
ToArray().Sum()
);
solver.Maximize(
(from p in PRODUCTS select(profit[p] * production[p])).ToArray().Sum());
if (solver.Solve() != Solver.ResultStatus.OPTIMAL) {
Console.WriteLine("The problem don't have an optimal solution.");
@@ -75,28 +74,32 @@ public class Volsay3 {
}
Console.WriteLine("Objective: {0}", solver.Objective().Value());
foreach(int p in PRODUCTS) {
Console.WriteLine("{0,-10}: {1} ReducedCost: {2}",
products[p],
production[p].SolutionValue(),
production[p].ReducedCost());
foreach (int p in PRODUCTS) {
Console.WriteLine("{0,-10}: {1} ReducedCost: {2}", products[p],
production [p]
.SolutionValue(),
production [p]
.ReducedCost());
}
double[] activities = solver.ComputeConstraintActivities();
for(int c = 0; c < c_len; c++) {
Console.WriteLine("Constraint {0} DualValue {1} Activity: {2} lb: {3} ub: {4}",
c,
cons[c].DualValue(),
activities[cons[c].Index()],
cons[c].Lb(),
cons[c].Ub());
for (int c = 0; c < c_len; c++) {
Console.WriteLine(
"Constraint {0} DualValue {1} Activity: {2} lb: {3} ub: {4}", c,
cons [c]
.DualValue(),
activities [cons [c]
.Index()]
,
cons [c]
.Lb(),
cons [c]
.Ub());
}
Console.WriteLine("\nWallTime: " + solver.WallTime());
Console.WriteLine("Iterations: " + solver.Iterations());
}
public static void Main(String[] args) {
Solve();
}
public static void Main(String[] args) { Solve(); }
}

Some files were not shown because too many files have changed in this diff Show More