add operator== and operator!= on C#
This commit is contained in:
@@ -42,4 +42,45 @@ namespace Google.OrTools.ConstraintSolver
|
||||
return valCstPair.Cst;
|
||||
}
|
||||
}
|
||||
|
||||
public class ConstraintAndEquality
|
||||
{
|
||||
public ConstraintAndEquality(IntExpr a, IntExpr b, bool equality)
|
||||
{
|
||||
this.left_ = a;
|
||||
this.right_ = b;
|
||||
this.equality_ = equality;
|
||||
}
|
||||
|
||||
bool IsTrue()
|
||||
{
|
||||
return (object)left_ == (object)right_ ? equality_ : !equality_;
|
||||
}
|
||||
|
||||
Constraint ToConstraint()
|
||||
{
|
||||
return equality_ ?
|
||||
left_.solver().MakeEquality(left_.Var(), right_.Var()) :
|
||||
left_.solver().MakeNonEquality(left_.Var(), right_.Var());
|
||||
}
|
||||
|
||||
public static bool operator true(ConstraintAndEquality eq)
|
||||
{
|
||||
return eq.IsTrue();
|
||||
}
|
||||
|
||||
public static bool operator false(ConstraintAndEquality eq)
|
||||
{
|
||||
return !eq.IsTrue();
|
||||
}
|
||||
|
||||
public static implicit operator Constraint(ConstraintAndEquality eq)
|
||||
{
|
||||
return eq.ToConstraint();
|
||||
}
|
||||
|
||||
private IntExpr left_;
|
||||
private IntExpr right_;
|
||||
private bool equality_;
|
||||
}
|
||||
} // namespace Google.OrTools.ConstraintSolver
|
||||
|
||||
@@ -1563,11 +1563,11 @@ namespace operations_research {
|
||||
public static ValCstPair operator !=(IntExpr a, long v) {
|
||||
return new ValCstPair(a.solver().MakeNonEquality(a.Var(), v));
|
||||
}
|
||||
public Constraint Equality(IntExpr b) {
|
||||
return this.solver().MakeEquality(this.Var(), b.Var());
|
||||
public static ConstraintAndEquality operator ==(IntExpr a, IntExpr b) {
|
||||
return new ConstraintAndEquality(a, b, true);
|
||||
}
|
||||
public Constraint NonEquality(IntExpr b) {
|
||||
return this.solver().MakeNonEquality(this.Var(), b.Var());
|
||||
public static ConstraintAndEquality operator !=(IntExpr a, IntExpr b) {
|
||||
return new ConstraintAndEquality(a, b, false);
|
||||
}
|
||||
public static ValCstPair operator >=(IntExpr a, long v) {
|
||||
return new ValCstPair(a.solver().MakeGreaterOrEqual(a, v));
|
||||
|
||||
@@ -117,13 +117,13 @@ public class ARoundOfGolf
|
||||
// 2. Mr. Clubb, who isn't Paul, hit several balls into the woods and
|
||||
// scored ten strokes more than the pro-shop clerk.
|
||||
solver.Add(Clubb != Paul);
|
||||
solver.Add(score.Element(Clubb).Equality(score.Element(clerk) + 10));
|
||||
solver.Add(score.Element(Clubb) == score.Element(clerk) + 10);
|
||||
|
||||
// 3. In some order, Frank and the caddy scored four and seven more
|
||||
// strokes than Mr. Sands.
|
||||
solver.Add(caddy != Frank);
|
||||
solver.Add(Sands != Frank);
|
||||
solver.Add(caddy.NonEquality(Sands));
|
||||
solver.Add(caddy != Sands);
|
||||
|
||||
IntVar b3_a_1 = (score.Element(Sands) + 4).IsEqual(score[Frank]);
|
||||
IntVar b3_a_2 = score.Element(caddy).IsEqual(score.Element(Sands) + 7);
|
||||
|
||||
@@ -47,10 +47,8 @@ public class AllInterval
|
||||
solver.Add(diffs.AllDifferent());
|
||||
|
||||
for(int k = 0; k < n - 1; k++) {
|
||||
// solver.Add(
|
||||
// solver.MakeEquality(diffs[k],
|
||||
// solver.MakeAbs(x[k + 1] - x[k]).Var()));
|
||||
solver.Add(diffs[k].Equality((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()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,9 +42,9 @@ public class CircuitTest
|
||||
solver.Add(z.AllDifferent());
|
||||
|
||||
// put the orbit of x[0] in z[0..n-1]
|
||||
solver.Add(z[0].Equality(x[0]));
|
||||
solver.Add(z[0] == x[0]);
|
||||
for(int i = 1; i < n-1; i++) {
|
||||
solver.Add(z[i].Equality(x.Element(z[i-1]).Var()));
|
||||
solver.Add(z[i] == x.Element(z[i-1].Var()));
|
||||
}
|
||||
|
||||
// z may not be 0 for i < n-1
|
||||
|
||||
@@ -43,9 +43,9 @@ public class CircuitTest2
|
||||
solver.Add(z.AllDifferent());
|
||||
|
||||
// put the orbit of x[0] in z[0..n-1]
|
||||
solver.Add(z[0].Equality(x[0]));
|
||||
solver.Add(z[0] == x[0]);
|
||||
for(int i = 1; i < n-1; i++) {
|
||||
solver.Add(z[i].Equality(x.Element(z[i-1]).Var()));
|
||||
solver.Add(z[i] == x.Element(z[i-1].Var()));
|
||||
}
|
||||
|
||||
// z may not be 0 for i < n-1
|
||||
|
||||
@@ -26,7 +26,7 @@ public class ContiguityRegular
|
||||
/*
|
||||
* Global constraint regular
|
||||
*
|
||||
* This is a translation of MiniZinc's regular constraint (defined in
|
||||
* This is a translation of MiniZinc's regular constraint (defined in
|
||||
* lib/zinc/globals.mzn), via the Comet code refered above.
|
||||
* All comments are from the MiniZinc code.
|
||||
* """
|
||||
@@ -52,9 +52,9 @@ public class ContiguityRegular
|
||||
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");
|
||||
|
||||
@@ -85,8 +85,8 @@ public class ContiguityRegular
|
||||
// string).
|
||||
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));
|
||||
// First state is q0
|
||||
@@ -96,10 +96,10 @@ public class ContiguityRegular
|
||||
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].Equality(d2_flatten.Element(((a[i])*S)+(x[i]-1))));
|
||||
solver.Add(a[i+1] == d2_flatten.Element(((a[i]*S)+(x[i]-1))));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -115,13 +115,13 @@ public class ContiguityRegular
|
||||
int[] accepting_states = {1,2,3};
|
||||
|
||||
// The regular expression 0*1*0*
|
||||
int[,] transition_fn =
|
||||
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*
|
||||
{3,2}, // state 2: 1*
|
||||
{3,0}, // state 3: 0*
|
||||
};
|
||||
|
||||
|
||||
MyRegular(solver, x, n_states, input_max, transition_fn,
|
||||
initial_state, accepting_states);
|
||||
|
||||
@@ -139,13 +139,13 @@ public class ContiguityRegular
|
||||
* From Global Constraint Catalogue
|
||||
* http://www.emn.fr/x-info/sdemasse/gccat/Cglobal_contiguity.html
|
||||
* """
|
||||
* Enforce all variables of the VARIABLES collection to be assigned to 0 or 1.
|
||||
* Enforce all variables of the VARIABLES collection to be assigned to 0 or 1.
|
||||
* In addition, all variables assigned to value 1 appear contiguously.
|
||||
*
|
||||
* Example:
|
||||
* (<0, 1, 1, 0>)
|
||||
*
|
||||
* The global_contiguity constraint holds since the sequence 0 1 1 0 contains
|
||||
* The global_contiguity constraint holds since the sequence 0 1 1 0 contains
|
||||
* no more than one group of contiguous 1.
|
||||
* """
|
||||
*
|
||||
@@ -165,7 +165,7 @@ public class ContiguityRegular
|
||||
//
|
||||
// Decision variables
|
||||
//
|
||||
|
||||
|
||||
// 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");
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public class Crew
|
||||
* number of cabin crew, and they have to speak certain languages.
|
||||
* Every cabin crew member has two flights off after an attended flight.
|
||||
* """
|
||||
*
|
||||
*
|
||||
* Also see http://www.hakank.org/or-tools/crew.pl
|
||||
*
|
||||
*/
|
||||
@@ -68,7 +68,7 @@ public class Crew
|
||||
"Jean",
|
||||
"Heather",
|
||||
"Juliet"};
|
||||
|
||||
|
||||
int num_persons = names.Length;
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ public class Crew
|
||||
{0,1,0,1,1}, // Heather = 18
|
||||
{0,1,1,0,0} // Juliet = 19
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Required number of crew members.
|
||||
@@ -155,7 +155,7 @@ public class Crew
|
||||
}
|
||||
nw[p] = tmp.Sum().IsGreater(0);
|
||||
}
|
||||
solver.Add(nw.Sum().Equality(num_working));
|
||||
solver.Add(nw.Sum() == num_working);
|
||||
|
||||
for(int f = 0; f < num_flights; f++) {
|
||||
// size of crew
|
||||
@@ -164,7 +164,7 @@ public class Crew
|
||||
tmp[p] = crew[f,p];
|
||||
}
|
||||
solver.Add(tmp.Sum() == required_crew[f,0]);
|
||||
|
||||
|
||||
// attributes and requirements
|
||||
for(int a = 0; a < 5; a++) {
|
||||
IntVar[] tmp2 = new IntVar[num_persons];
|
||||
@@ -181,7 +181,7 @@ public class Crew
|
||||
solver.Add(crew[f,i] + crew[f+1,i] + crew[f+2,i] <= 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// extra contraint: all must work at least two of the flights
|
||||
/*
|
||||
for(int p = 0; p < num_persons; p++) {
|
||||
@@ -269,7 +269,7 @@ public class Crew
|
||||
}
|
||||
|
||||
if (args.Length > 1) {
|
||||
min = Convert.ToInt32(args[0]);
|
||||
min = Convert.ToInt32(args[1]);
|
||||
}
|
||||
|
||||
Solve(n, min);
|
||||
|
||||
@@ -141,11 +141,8 @@ public class Crossword
|
||||
//
|
||||
for(int I = 0; I < num_overlapping; I++) {
|
||||
solver.Add(
|
||||
solver.MakeEquality(
|
||||
A_flat.Element(E[overlapping[I,0]] * word_len +
|
||||
overlapping[I,1]).Var(),
|
||||
A_flat.Element(E[overlapping[I,2]] * word_len +
|
||||
overlapping[I,3]).Var()));
|
||||
A_flat.Element(E[overlapping[I,0]] * word_len + overlapping[I,1]) ==
|
||||
A_flat.Element(E[overlapping[I,2]] * word_len + overlapping[I,3]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class DeBruijn
|
||||
for(int i = 0; i < len; i++) {
|
||||
tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var();
|
||||
}
|
||||
return tmp.Sum().Equality(num);
|
||||
return tmp.Sum() == num;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,18 +105,18 @@ public class DeBruijn
|
||||
// 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].Equality(binary[i,j - 1]));
|
||||
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].Equality(binary[0,j - 1]));
|
||||
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].Equality(binary[i,0]));
|
||||
solver.Add(bin_code[i] == binary[i,0]);
|
||||
|
||||
}
|
||||
|
||||
@@ -127,13 +127,13 @@ public class DeBruijn
|
||||
solver.Add(bin_code.Distribute(gcc));
|
||||
if (check_same_gcc && m % bbase == 0) {
|
||||
for(int i = 1; i < bbase; i++) {
|
||||
solver.Add(gcc[i].Equality(gcc[i - 1]));
|
||||
solver.Add(gcc[i] == gcc[i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
// symmetry breaking:
|
||||
// the minimum value of x should be first
|
||||
// solver.Add(x[0].Equality(x.Min()));
|
||||
// solver.Add(x[0] == x.Min());
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -35,7 +35,7 @@ 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;
|
||||
@@ -44,7 +44,7 @@ public class DivisibleBy9Through1
|
||||
int max_x = (int)Math.Max(ubx, lbx_neg);
|
||||
|
||||
IntVar d = solver.MakeIntVar(min_x, max_x, "d");
|
||||
|
||||
|
||||
// r >= 0
|
||||
solver.Add(r >= 0);
|
||||
|
||||
@@ -65,7 +65,7 @@ public class DivisibleBy9Through1
|
||||
|
||||
// x == y*d+r
|
||||
solver.Add(x - (y*d + r) == 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public class DivisibleBy9Through1
|
||||
for(int i = 0; i < len; i++) {
|
||||
tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var();
|
||||
}
|
||||
return tmp.Sum().Equality(num);
|
||||
return tmp.Sum() == num;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +153,7 @@ public class DivisibleBy9Through1
|
||||
Console.Write(t[i].Value() + " ");
|
||||
}
|
||||
Console.WriteLine("\n");
|
||||
|
||||
|
||||
if (bbase != 10) {
|
||||
Console.Write("Number base 10: " + t[0].Value());
|
||||
Console.Write(" Base " + bbase + ": ");
|
||||
@@ -161,7 +161,7 @@ public class DivisibleBy9Through1
|
||||
Console.Write(digits_str[(int)x[i].Value() + 1]);
|
||||
}
|
||||
Console.WriteLine("\n");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ using Google.OrTools.ConstraintSolver;
|
||||
|
||||
public class DudeneyNumbers
|
||||
{
|
||||
|
||||
|
||||
|
||||
private static Constraint ToNum(IntVar[] a, IntVar num, int bbase) {
|
||||
int len = a.Length;
|
||||
@@ -31,7 +31,7 @@ public class DudeneyNumbers
|
||||
for(int i = 0; i < len; i++) {
|
||||
tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var();
|
||||
}
|
||||
return tmp.Sum().Equality(num);
|
||||
return tmp.Sum() == num;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,17 +43,17 @@ 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
|
||||
* 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)
|
||||
* 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:
|
||||
* 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
|
||||
* It is difficult to argue that it is very far from dedicated
|
||||
* optimization languages!
|
||||
* """
|
||||
*
|
||||
*
|
||||
* Also see: http://en.wikipedia.org/wiki/Dudeney_number
|
||||
*
|
||||
*/
|
||||
@@ -77,15 +77,15 @@ public class DudeneyNumbers
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
solver.Add(nb.Equality(s*s*s));
|
||||
solver.Add(x.Sum().Equality(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().Equality(nb));
|
||||
ToArray().Sum() == nb);
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -44,11 +44,11 @@ public class FurnitureMoving
|
||||
*
|
||||
*/
|
||||
static void MyCumulative(Solver solver,
|
||||
IntVar[] s,
|
||||
int[] d,
|
||||
int[] r,
|
||||
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();
|
||||
@@ -64,7 +64,7 @@ public class FurnitureMoving
|
||||
}
|
||||
solver.Add((bb.ToArray(typeof(IntVar)) as IntVar[]).Sum() <= b);
|
||||
}
|
||||
|
||||
|
||||
// Somewhat experimental:
|
||||
// This constraint is needed to constrain the upper limit of b.
|
||||
if (b is IntVar) {
|
||||
@@ -80,7 +80,7 @@ public class FurnitureMoving
|
||||
*
|
||||
* Marriott & Stukey: 'Programming with constraints', page 112f
|
||||
*
|
||||
* The model implements an decomposition of the global constraint
|
||||
* The model implements an decomposition of the global constraint
|
||||
* cumulative (see above).
|
||||
*
|
||||
* Also see http://www.hakank.org/or-tools/furniture_moving.py
|
||||
@@ -111,10 +111,10 @@ public class FurnitureMoving
|
||||
// Constraints
|
||||
//
|
||||
for(int i = 0; i < n; i++) {
|
||||
solver.Add(end_times[i].Equality(start_times[i] + duration[i]));
|
||||
solver.Add(end_times[i] == start_times[i] + duration[i]);
|
||||
}
|
||||
|
||||
solver.Add(end_time.Equality(end_times.Max()));
|
||||
solver.Add(end_time == end_times.Max());
|
||||
MyCumulative(solver, start_times, duration, demand, num_resources);
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ public class FurnitureMoving
|
||||
Console.WriteLine("num_resources: {0} end_time: {1}",
|
||||
num_resources.Value(), end_time.Value());
|
||||
for(int i = 0; i < n; i++) {
|
||||
Console.WriteLine("Task {0,1}: {1,2} -> {2,2} -> {3,2} (demand: {4})",
|
||||
Console.WriteLine("Task {0,1}: {1,2} -> {2,2} -> {3,2} (demand: {4})",
|
||||
i,
|
||||
start_times[i].Value(),
|
||||
duration[i],
|
||||
|
||||
@@ -61,7 +61,7 @@ public class Grocery
|
||||
solver.Add(item.Sum() == c);
|
||||
solver.Add(item[0] * item[1] * item[2] * item[3] - (c * 100*100*100) == 0);
|
||||
// solver.Add(item.Prod() - (c * 100*100*100) == 0);
|
||||
// solver.Add(item.Prod().Equality(c * 100*100*100));
|
||||
// solver.Add(item.Prod() == c * 100*100*100);
|
||||
|
||||
// Symmetry breaking
|
||||
Decreasing(solver, item);
|
||||
|
||||
@@ -50,15 +50,15 @@ public class Map
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
solver.Add(color[France].NonEquality(color[Belgium]));
|
||||
solver.Add(color[France].NonEquality(color[Luxembourg]));
|
||||
solver.Add(color[France].NonEquality(color[Germany]));
|
||||
solver.Add(color[Luxembourg].NonEquality(color[Germany]));
|
||||
solver.Add(color[Luxembourg].NonEquality(color[Belgium]));
|
||||
solver.Add(color[Belgium].NonEquality(color[Netherlands]));
|
||||
solver.Add(color[Belgium].NonEquality(color[Germany]));
|
||||
solver.Add(color[Germany].NonEquality(color[Netherlands]));
|
||||
solver.Add(color[Germany].NonEquality(color[Denmark]));
|
||||
solver.Add(color[France] != color[Belgium]);
|
||||
solver.Add(color[France] != color[Luxembourg]);
|
||||
solver.Add(color[France] != color[Germany]);
|
||||
solver.Add(color[Luxembourg] != color[Germany]);
|
||||
solver.Add(color[Luxembourg] != color[Belgium]);
|
||||
solver.Add(color[Belgium] != color[Netherlands]);
|
||||
solver.Add(color[Belgium] != color[Germany]);
|
||||
solver.Add(color[Germany] != color[Netherlands]);
|
||||
solver.Add(color[Germany] != color[Denmark]);
|
||||
|
||||
// Symmetry breaking
|
||||
solver.Add(color[Belgium] == 1);
|
||||
|
||||
@@ -67,7 +67,7 @@ public class Map2
|
||||
// Constraints
|
||||
//
|
||||
for(int i = 0; i < neighbours.GetLength(0); i++) {
|
||||
solver.Add(color[neighbours[i,0]].NonEquality(color[neighbours[i,1]]));
|
||||
solver.Add(color[neighbours[i,0]] != color[neighbours[i,1]]);
|
||||
}
|
||||
|
||||
// Symmetry breaking
|
||||
|
||||
@@ -27,7 +27,7 @@ public class NurseRostering
|
||||
/*
|
||||
* Global constraint regular
|
||||
*
|
||||
* This is a translation of MiniZinc's regular constraint (defined in
|
||||
* This is a translation of MiniZinc's regular constraint (defined in
|
||||
* lib/zinc/globals.mzn), via the Comet code refered above.
|
||||
* All comments are from the MiniZinc code.
|
||||
* """
|
||||
@@ -53,9 +53,9 @@ public class NurseRostering
|
||||
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");
|
||||
|
||||
@@ -86,8 +86,8 @@ public class NurseRostering
|
||||
// string).
|
||||
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));
|
||||
// First state is q0
|
||||
@@ -97,10 +97,10 @@ public class NurseRostering
|
||||
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].Equality(d2_flatten.Element(((a[i])*S)+(x[i]-1))));
|
||||
solver.Add(a[i+1] == d2_flatten.Element(((a[i])*S)+(x[i]-1)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ public class NurseRostering
|
||||
{6,0,1}, // state 5
|
||||
{0,0,1} // state 6
|
||||
};
|
||||
|
||||
|
||||
string[] days = {"d","n","o"}; // for presentation
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ public class NurseRostering
|
||||
//
|
||||
// Decision variables
|
||||
//
|
||||
|
||||
|
||||
// For regular
|
||||
IntVar[,] x = new IntVar[num_nurses, num_days];
|
||||
IntVar[] x_flat = new IntVar[num_nurses*num_days];
|
||||
@@ -198,11 +198,11 @@ public class NurseRostering
|
||||
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++) {
|
||||
@@ -212,7 +212,7 @@ public class NurseRostering
|
||||
for(int j = 0; j < num_days; j++) {
|
||||
b[j] = (x[i,j].IsEqual(day_shift) + x[i,j].IsEqual(night_shift)).Var();
|
||||
}
|
||||
solver.Add(b.Sum().Equality(nurse_stat[i]));
|
||||
solver.Add(b.Sum() == nurse_stat[i]);
|
||||
|
||||
// Each nurse must work between 7 and 10
|
||||
// days/nights during this period
|
||||
@@ -222,7 +222,7 @@ public class NurseRostering
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Statistics and constraints for each day
|
||||
//
|
||||
for(int j = 0; j < num_days; j++) {
|
||||
@@ -231,7 +231,7 @@ public class NurseRostering
|
||||
for(int i = 0; i < num_nurses; i++) {
|
||||
b[i] = (x[i,j].IsEqual(t)).Var();
|
||||
}
|
||||
solver.Add(b.Sum().Equality(day_stat[j,t]));
|
||||
solver.Add(b.Sum() == day_stat[j,t]);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -283,7 +283,7 @@ public class NurseRostering
|
||||
occ[v]++;
|
||||
Console.Write(days[v] + " ");
|
||||
}
|
||||
|
||||
|
||||
Console.Write(" #workdays: {0,2}", nurse_stat[i].Value());
|
||||
foreach(int s in valid_shifts) {
|
||||
int v = 0;
|
||||
@@ -293,7 +293,7 @@ public class NurseRostering
|
||||
Console.Write(" {0}:{1}", days[s-1], v);
|
||||
}
|
||||
Console.WriteLine();
|
||||
|
||||
|
||||
}
|
||||
Console.WriteLine();
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public class NurseRostering
|
||||
//
|
||||
// Decision variables
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// For TransitionConstraint
|
||||
//
|
||||
@@ -153,7 +153,7 @@ public class NurseRostering
|
||||
accepting_states));
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Statistics and constraints for each nurse
|
||||
//
|
||||
for(int i = 0; i < num_nurses; i++) {
|
||||
@@ -163,7 +163,7 @@ public class NurseRostering
|
||||
for(int j = 0; j < num_days; j++) {
|
||||
b[j] = (x[i,j].IsEqual(day_shift) + x[i,j].IsEqual(night_shift)).Var();
|
||||
}
|
||||
solver.Add(b.Sum().Equality(nurse_stat[i]));
|
||||
solver.Add(b.Sum() == nurse_stat[i]);
|
||||
|
||||
// Each nurse must work between 7 and 10
|
||||
// days/nights during this period
|
||||
@@ -173,7 +173,7 @@ public class NurseRostering
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Statistics and constraints for each day
|
||||
//
|
||||
for(int j = 0; j < num_days; j++) {
|
||||
@@ -182,7 +182,7 @@ public class NurseRostering
|
||||
for(int i = 0; i < num_nurses; i++) {
|
||||
b[i] = (x[i,j].IsEqual(t)).Var();
|
||||
}
|
||||
solver.Add(b.Sum().Equality(day_stat[j,t]));
|
||||
solver.Add(b.Sum() == day_stat[j,t]);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -234,7 +234,7 @@ public class NurseRostering
|
||||
occ[v]++;
|
||||
Console.Write(days[v] + " ");
|
||||
}
|
||||
|
||||
|
||||
Console.Write(" #workdays: {0,2}", nurse_stat[i].Value());
|
||||
foreach(int s in valid_shifts) {
|
||||
int v = 0;
|
||||
@@ -244,7 +244,7 @@ public class NurseRostering
|
||||
Console.Write(" {0}:{1}", days[s-1], v);
|
||||
}
|
||||
Console.WriteLine();
|
||||
|
||||
|
||||
}
|
||||
Console.WriteLine();
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ public class SendMoreMoney
|
||||
// Constraints
|
||||
//
|
||||
solver.Add(x.AllDifferent());
|
||||
solver.Add((S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E).Equality(
|
||||
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);
|
||||
|
||||
@@ -49,8 +49,8 @@ public class SendMoreMoney
|
||||
solver.Add(x.AllDifferent());
|
||||
|
||||
/*
|
||||
solver.Add((S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E).Equality(
|
||||
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);
|
||||
*/
|
||||
|
||||
// Here we use scalar product instead.
|
||||
@@ -61,20 +61,18 @@ public class SendMoreMoney
|
||||
new int[] {1000,100,10,1}),
|
||||
solver.MakeScalProd(new IntVar[] {M, O, R, E},
|
||||
new int[] {1000,100,10,1}))
|
||||
.Equality(
|
||||
==
|
||||
solver.MakeScalProd(new IntVar[] {M,O,N,E,Y},
|
||||
new int[] {10000, 1000, 100, 10, 1}
|
||||
))
|
||||
)
|
||||
);
|
||||
*/
|
||||
// Alternative
|
||||
// Alternative
|
||||
int[] s1 = new int[] {1000,100,10,1};
|
||||
int[] s2 = new int[] {10000,1000,100,10,1};
|
||||
solver.Add(solver.MakeSum(new IntVar[] {S,E,N,D}.ScalProd(s1),
|
||||
new IntVar[] {M,O,R,E}.ScalProd(s1))
|
||||
.Equality(
|
||||
new IntVar[] {M,O,N,E,Y}.ScalProd(s2))
|
||||
);
|
||||
== new IntVar[] {M,O,N,E,Y}.ScalProd(s2));
|
||||
|
||||
|
||||
solver.Add(S > 0);
|
||||
|
||||
@@ -79,7 +79,7 @@ public class SkiAssignment
|
||||
}
|
||||
|
||||
// IntVar z = solver.MakeIntVar(0, ski_heights.Sum(), "z");
|
||||
// solver.Add(z_tmp.Sum().Equality(z));
|
||||
// solver.Add(z_tmp.Sum() == z);
|
||||
// The direct cast from IntExpr to IntVar is potentially faster than
|
||||
// the above code.
|
||||
IntVar z = z_tmp.Sum().VarWithName("z");
|
||||
|
||||
@@ -44,7 +44,7 @@ public class Strimko2
|
||||
{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},
|
||||
@@ -59,7 +59,7 @@ public class Strimko2
|
||||
|
||||
int n = streams.GetLength(0);
|
||||
int num_placed = placed.GetLength(0);
|
||||
|
||||
|
||||
//
|
||||
// Decision variables
|
||||
//
|
||||
@@ -74,7 +74,7 @@ public class Strimko2
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
//
|
||||
// all rows and columns must be unique, i.e. a Latin Square
|
||||
for(int i = 0; i < n; i++) {
|
||||
IntVar[] row = new IntVar[n];
|
||||
@@ -87,10 +87,10 @@ public class Strimko2
|
||||
solver.Add(row.AllDifferent());
|
||||
solver.Add(col.AllDifferent());
|
||||
}
|
||||
|
||||
|
||||
// streams
|
||||
for(int s = 1; s <= n; s++) {
|
||||
IntVar[] tmp = (from i in Enumerable.Range(0, n)
|
||||
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();
|
||||
@@ -101,8 +101,7 @@ public class Strimko2
|
||||
// placed
|
||||
for(int i = 0; i < num_placed; i++) {
|
||||
// note: also adjust to 0-based
|
||||
solver.Add(solver.MakeEquality(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]);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -34,7 +34,7 @@ public class ToNumTest
|
||||
for(int i = 0; i < len; i++) {
|
||||
tmp[i] = (a[i]*(int)Math.Pow(bbase,(len-i-1))).Var();
|
||||
}
|
||||
return tmp.Sum().Equality(num);
|
||||
return tmp.Sum() == num;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public class YoungTableaux
|
||||
for(int j = 0; j < n; j++) {
|
||||
b[j] = x[i, j].IsLessOrEqual(n);
|
||||
}
|
||||
solver.Add(p[i].Equality(b.Sum()));
|
||||
solver.Add(p[i] == b.Sum());
|
||||
}
|
||||
|
||||
solver.Add(p.Sum() == n);
|
||||
|
||||
@@ -25,7 +25,7 @@ public class NQueens
|
||||
*
|
||||
* This is a port of the or-tools/Python model zebra.py
|
||||
*
|
||||
*
|
||||
*
|
||||
* """
|
||||
* This is the zebra problem as invented by Lewis Caroll.
|
||||
*
|
||||
@@ -45,7 +45,7 @@ public class NQueens
|
||||
* The Lucky Strike smoker drinks orange juice.
|
||||
* The Japanese smokes Parliaments.
|
||||
* The Norwegian lives next to the blue house.
|
||||
*
|
||||
*
|
||||
* Who owns a zebra and who drinks water?
|
||||
* """
|
||||
*
|
||||
@@ -80,14 +80,14 @@ public class NQueens
|
||||
IntVar fox = solver.MakeIntVar(1, n, "fox");
|
||||
IntVar zebra = solver.MakeIntVar(1, n, "zebra");
|
||||
IntVar horse = solver.MakeIntVar(1, n, "horse");
|
||||
|
||||
|
||||
// Drink
|
||||
IntVar tea = solver.MakeIntVar(1, n, "tea");
|
||||
IntVar coffee = solver.MakeIntVar(1, n, "coffee");
|
||||
IntVar water = solver.MakeIntVar(1, n, "water");
|
||||
IntVar milk = solver.MakeIntVar(1, n, "milk");
|
||||
IntVar fruit_juice = solver.MakeIntVar(1, n, "fruit juice");
|
||||
|
||||
|
||||
// Smoke
|
||||
IntVar old_gold = solver.MakeIntVar(1, n, "old gold");
|
||||
IntVar kools = solver.MakeIntVar(1, n, "kools");
|
||||
@@ -97,7 +97,7 @@ public class NQueens
|
||||
|
||||
|
||||
// for search
|
||||
IntVar[] all_vars =
|
||||
IntVar[] all_vars =
|
||||
{parliaments, kools, chesterfields, lucky_strike, old_gold,
|
||||
englishman, spaniard, japanese, ukrainian, norwegian,
|
||||
dog, snails, fox, zebra, horse,
|
||||
@@ -106,38 +106,38 @@ public class NQueens
|
||||
|
||||
//
|
||||
// Constraints
|
||||
//
|
||||
//
|
||||
|
||||
// Alldifferents
|
||||
solver.Add(new IntVar[]
|
||||
solver.Add(new IntVar[]
|
||||
{red, green, yellow, blue, ivory}.AllDifferent());
|
||||
solver.Add(new IntVar[]
|
||||
solver.Add(new IntVar[]
|
||||
{englishman, spaniard, japanese, ukrainian, norwegian}.AllDifferent());
|
||||
solver.Add(new IntVar[]
|
||||
solver.Add(new IntVar[]
|
||||
{dog, snails, fox, zebra, horse}.AllDifferent());
|
||||
solver.Add(new IntVar[]
|
||||
solver.Add(new IntVar[]
|
||||
{tea, coffee, water, milk, fruit_juice}.AllDifferent());
|
||||
solver.Add(new IntVar[]
|
||||
solver.Add(new IntVar[]
|
||||
{parliaments, kools, chesterfields, lucky_strike, old_gold}.AllDifferent());
|
||||
|
||||
//
|
||||
// The clues
|
||||
//
|
||||
solver.Add(englishman.Equality(red));
|
||||
solver.Add(spaniard.Equality(dog));
|
||||
solver.Add(coffee.Equality(green));
|
||||
solver.Add(ukrainian.Equality(tea));
|
||||
solver.Add(green.Equality(ivory + 1));
|
||||
solver.Add(old_gold.Equality(snails));
|
||||
solver.Add(kools.Equality(yellow));
|
||||
solver.Add(englishman == red);
|
||||
solver.Add(spaniard == dog);
|
||||
solver.Add(coffee == green);
|
||||
solver.Add(ukrainian == tea);
|
||||
solver.Add(green == ivory + 1);
|
||||
solver.Add(old_gold == snails);
|
||||
solver.Add(kools == yellow);
|
||||
solver.Add(milk == 3);
|
||||
solver.Add(norwegian == 1);
|
||||
solver.Add((fox - chesterfields).Abs() == 1);
|
||||
solver.Add((horse - kools).Abs() == 1);
|
||||
solver.Add(lucky_strike.Equality(fruit_juice));
|
||||
solver.Add(japanese.Equality(parliaments));
|
||||
solver.Add(lucky_strike == fruit_juice);
|
||||
solver.Add(japanese == parliaments);
|
||||
solver.Add((norwegian - blue).Abs() == 1);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Search
|
||||
@@ -151,11 +151,11 @@ public class NQueens
|
||||
IntVar[] p = {englishman, spaniard, japanese, ukrainian, norwegian};
|
||||
int[] ix = {0,1,2,3,4};
|
||||
while (solver.NextSolution()) {
|
||||
int water_drinker = (from i in ix
|
||||
where p[i].Value() == water.Value()
|
||||
int water_drinker = (from i in ix
|
||||
where p[i].Value() == water.Value()
|
||||
select i).First();
|
||||
int zebra_owner = (from i in ix
|
||||
where p[i].Value() == zebra.Value()
|
||||
int zebra_owner = (from i in ix
|
||||
where p[i].Value() == zebra.Value()
|
||||
select i).First();
|
||||
Console.WriteLine("The {0} drinks water.", p[water_drinker].ToString());
|
||||
Console.WriteLine("The {0} owns the zebra", p[zebra_owner].ToString());
|
||||
|
||||
Reference in New Issue
Block a user