DotNet Reference

.Net Reference

SatSolverTests.cs
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 using System;
15 using System.Collections.Generic;
16 using Xunit;
17 using Google.OrTools.Sat;
18 
19 namespace Google.OrTools.Tests
20 {
21 public class SatSolverTest
22 {
23  static IntegerVariableProto NewIntegerVariable(long lb, long ub)
24  {
25  IntegerVariableProto var = new IntegerVariableProto();
26  var.Domain.Add(lb);
27  var.Domain.Add(ub);
28  return var;
29  }
30 
31  static ConstraintProto NewLinear2(int v1, int v2, long c1, long c2, long lb, long ub)
32  {
33  LinearConstraintProto linear = new LinearConstraintProto();
34  linear.Vars.Add(v1);
35  linear.Vars.Add(v2);
36  linear.Coeffs.Add(c1);
37  linear.Coeffs.Add(c2);
38  linear.Domain.Add(lb);
39  linear.Domain.Add(ub);
40  ConstraintProto ct = new ConstraintProto();
41  ct.Linear = linear;
42  return ct;
43  }
44 
45  static ConstraintProto NewLinear3(int v1, int v2, int v3, long c1, long c2, long c3, long lb, long ub)
46  {
47  LinearConstraintProto linear = new LinearConstraintProto();
48  linear.Vars.Add(v1);
49  linear.Vars.Add(v2);
50  linear.Vars.Add(v3);
51  linear.Coeffs.Add(c1);
52  linear.Coeffs.Add(c2);
53  linear.Coeffs.Add(c3);
54  linear.Domain.Add(lb);
55  linear.Domain.Add(ub);
56  ConstraintProto ct = new ConstraintProto();
57  ct.Linear = linear;
58  return ct;
59  }
60 
61  static CpObjectiveProto NewMinimize1(int v1, long c1)
62  {
63  CpObjectiveProto obj = new CpObjectiveProto();
64  obj.Vars.Add(v1);
65  obj.Coeffs.Add(c1);
66  return obj;
67  }
68 
69  static CpObjectiveProto NewMaximize1(int v1, long c1)
70  {
71  CpObjectiveProto obj = new CpObjectiveProto();
72  obj.Vars.Add(-v1 - 1);
73  obj.Coeffs.Add(c1);
74  obj.ScalingFactor = -1;
75  return obj;
76  }
77 
78  static CpObjectiveProto NewMaximize2(int v1, int v2, long c1, long c2)
79  {
80  CpObjectiveProto obj = new CpObjectiveProto();
81  obj.Vars.Add(-v1 - 1);
82  obj.Vars.Add(-v2 - 1);
83  obj.Coeffs.Add(c1);
84  obj.Coeffs.Add(c2);
85  obj.ScalingFactor = -1;
86  return obj;
87  }
88 
89  // CpModelProto
90  [Fact]
91  public void SimpleLinearModelProto()
92  {
93  CpModelProto model = new CpModelProto();
94  model.Variables.Add(NewIntegerVariable(-10, 10));
95  model.Variables.Add(NewIntegerVariable(-10, 10));
96  model.Variables.Add(NewIntegerVariable(-1000000, 1000000));
97  model.Constraints.Add(NewLinear2(0, 1, 1, 1, -1000000, 100000));
98  model.Constraints.Add(NewLinear3(0, 1, 2, 1, 2, -1, 0, 100000));
99  model.Objective = NewMaximize1(2, 1);
100  // Console.WriteLine("model = " + model.ToString());
101  SolveWrapper solve_wrapper = new SolveWrapper();
102  CpSolverResponse response = solve_wrapper.Solve(model);
103  Assert.Equal(CpSolverStatus.Optimal, response.Status);
104  Assert.Equal(30, response.ObjectiveValue);
105  Assert.Equal(new long[] { 10, 10, 30 }, response.Solution);
106  // Console.WriteLine("response = " + response.ToString());
107  }
108 
109  [Fact]
111  {
112  CpModelProto model = new CpModelProto();
113  model.Variables.Add(NewIntegerVariable(-10, 10));
114  model.Variables.Add(NewIntegerVariable(-10, 10));
115  model.Constraints.Add(NewLinear2(0, 1, 1, 1, -1000000, 100000));
116  model.Objective = NewMaximize2(0, 1, 1, -2);
117  // Console.WriteLine("model = " + model.ToString());
118 
119  SolveWrapper solve_wrapper = new SolveWrapper();
120  CpSolverResponse response = solve_wrapper.Solve(model);
121  Assert.Equal(CpSolverStatus.Optimal, response.Status);
122  Assert.Equal(30, response.ObjectiveValue);
123  Assert.Equal(new long[] { 10, -10 }, response.Solution);
124  // Console.WriteLine("response = " + response.ToString());
125  }
126 
127  // CpModel
128  [Fact]
129  public void SimpleLinearModel()
130  {
131  CpModel model = new CpModel();
132  IntVar v1 = model.NewIntVar(-10, 10, "v1");
133  IntVar v2 = model.NewIntVar(-10, 10, "v2");
134  IntVar v3 = model.NewIntVar(-100000, 100000, "v3");
135  model.AddLinearConstraint(v1 + v2, -1000000, 100000);
136  model.AddLinearConstraint(v1 + 2 * v2 - v3, 0, 100000);
137  model.Maximize(v3);
138  Assert.Equal(v1.Domain.FlattenedIntervals(), new long[] { -10, 10 });
139  // Console.WriteLine("model = " + model.Model.ToString());
140 
141  CpSolver solver = new CpSolver();
142  CpSolverStatus status = solver.Solve(model);
143  Assert.Equal(CpSolverStatus.Optimal, status);
144 
145  CpSolverResponse response = solver.Response;
146  Assert.Equal(30, response.ObjectiveValue);
147  Assert.Equal(new long[] { 10, 10, 30 }, response.Solution);
148  // Console.WriteLine("response = " + response.ToString());
149  }
150 
151  [Fact]
152  public void SimpleLinearModel2()
153  {
154  CpModel model = new CpModel();
155  IntVar v1 = model.NewIntVar(-10, 10, "v1");
156  IntVar v2 = model.NewIntVar(-10, 10, "v2");
157  model.AddLinearConstraint(v1 + v2, -1000000, 100000);
158  model.Maximize(v1 - 2 * v2);
159  // Console.WriteLine("model = " + model.Model.ToString());
160 
161  CpSolver solver = new CpSolver();
162  CpSolverStatus status = solver.Solve(model);
163  Assert.Equal(CpSolverStatus.Optimal, status);
164 
165  CpSolverResponse response = solver.Response;
166  Assert.Equal(30, response.ObjectiveValue);
167  Assert.Equal(new long[] { 10, -10 }, response.Solution);
168  // Console.WriteLine("response = " + response.ToString());
169  }
170 
171  [Fact]
172  public void SimpleLinearModel3()
173  {
174  CpModel model = new CpModel();
175  IntVar v1 = model.NewIntVar(-10, 10, "v1");
176  IntVar v2 = model.NewIntVar(-10, 10, "v2");
177  model.Add(-100000 <= v1 + 2 * v2 <= 100000);
178  model.Minimize(v1 - 2 * v2);
179  // Console.WriteLine("model = " + model.Model.ToString());
180 
181  CpSolver solver = new CpSolver();
182  CpSolverStatus status = solver.Solve(model);
183  Assert.Equal(CpSolverStatus.Optimal, status);
184 
185  CpSolverResponse response = solver.Response;
186  Assert.Equal(-10, solver.Value(v1));
187  Assert.Equal(10, solver.Value(v2));
188  Assert.Equal(new long[] { -10, 10 }, response.Solution);
189  Assert.Equal(-30, solver.Value(v1 - 2 * v2));
190  Assert.Equal(-30, response.ObjectiveValue);
191  // Console.WriteLine("response = " + response.ToString());
192  }
193 
194  [Fact]
195  public void NegativeIntVar()
196  {
197  CpModel model = new CpModel();
198  IntVar boolvar = model.NewBoolVar("boolvar");
199  IntVar x = model.NewIntVar(0, 10, "x");
200  IntVar delta = model.NewIntVar(-5, 5, "delta");
201  IntVar squaredDelta = model.NewIntVar(0, 25, "squaredDelta");
202  model.Add(x == boolvar * 4);
203  model.Add(delta == x - 5);
204  model.AddMultiplicationEquality(squaredDelta, new IntVar[] { delta, delta });
205  model.Minimize(squaredDelta);
206  // Console.WriteLine("model = " + model.Model.ToString());
207 
208  CpSolver solver = new CpSolver();
209  CpSolverStatus status = solver.Solve(model);
210  CpSolverResponse response = solver.Response;
211  Console.WriteLine("response = " + response.ToString());
212 
213  Assert.Equal(CpSolverStatus.Optimal, status);
214 
215  Assert.Equal(1, solver.Value(boolvar));
216  Assert.Equal(4, solver.Value(x));
217  Assert.Equal(-1, solver.Value(delta));
218  Assert.Equal(1, solver.Value(squaredDelta));
219  Assert.Equal(new long[] { 1, 4, -1, 1 }, response.Solution);
220  Assert.Equal(1.0, response.ObjectiveValue, 5);
221  }
222 
223  [Fact]
224  public void NegativeSquareVar()
225  {
226  CpModel model = new CpModel();
227  BoolVar boolvar = model.NewBoolVar("boolvar");
228  IntVar x = model.NewIntVar(0, 10, "x");
229  IntVar delta = model.NewIntVar(-5, 5, "delta");
230  IntVar squaredDelta = model.NewIntVar(0, 25, "squaredDelta");
231  model.Add(x == 4).OnlyEnforceIf(boolvar);
232  model.Add(x == 0).OnlyEnforceIf(boolvar.Not());
233  model.Add(delta == x - 5);
234  long[,] tuples = { { -5, 25 }, { -4, 16 }, { -3, 9 }, { -2, 4 }, { -1, 1 }, { 0, 0 },
235  { 1, 1 }, { 2, 4 }, { 3, 9 }, { 4, 16 }, { 5, 25 } };
236  model.AddAllowedAssignments(new IntVar[] { delta, squaredDelta }).AddTuples(tuples);
237  model.Minimize(squaredDelta);
238 
239  CpSolver solver = new CpSolver();
240  CpSolverStatus status = solver.Solve(model);
241 
242  CpSolverResponse response = solver.Response;
243  Assert.Equal(1, solver.Value(boolvar));
244  Assert.Equal(4, solver.Value(x));
245  Assert.Equal(-1, solver.Value(delta));
246  Assert.Equal(1, solver.Value(squaredDelta));
247  Assert.Equal(new long[] { 1, 4, -1, 1 }, response.Solution);
248  Assert.Equal(1.0, response.ObjectiveValue, 6);
249  }
250 
251  [Fact]
252  public void Division()
253  {
254  CpModel model = new CpModel();
255  IntVar v1 = model.NewIntVar(0, 10, "v1");
256  IntVar v2 = model.NewIntVar(1, 10, "v2");
257  model.AddDivisionEquality(3, v1, v2);
258  // Console.WriteLine(model.Model);
259 
260  CpSolver solver = new CpSolver();
261  CpSolverStatus status = solver.Solve(model);
262  Assert.Equal(CpSolverStatus.Optimal, status);
263 
264  CpSolverResponse response = solver.Response;
265  Assert.Equal(3, solver.Value(v1));
266  Assert.Equal(1, solver.Value(v2));
267  Assert.Equal(new long[] { 3, 1 }, response.Solution);
268  Assert.Equal(0, response.ObjectiveValue);
269  // Console.WriteLine("response = " + response.ToString());
270  }
271 
272  [Fact]
273  public void Modulo()
274  {
275  CpModel model = new CpModel();
276  IntVar v1 = model.NewIntVar(1, 10, "v1");
277  IntVar v2 = model.NewIntVar(1, 10, "v2");
278  model.AddModuloEquality(3, v1, v2);
279  // Console.WriteLine(model.Model);
280 
281  CpSolver solver = new CpSolver();
282  CpSolverStatus status = solver.Solve(model);
283  Assert.Equal(CpSolverStatus.Optimal, status);
284 
285  CpSolverResponse response = solver.Response;
286  Assert.Equal(3, solver.Value(v1));
287  Assert.Equal(4, solver.Value(v2));
288  Assert.Equal(new long[] { 3, 4 }, response.Solution);
289  Assert.Equal(0, response.ObjectiveValue);
290  // Console.WriteLine("response = " + response.ToString());
291  }
292 
293  [Fact]
294  public void LargeWeightedSumLong()
295  {
296  CpModel model = new CpModel();
297  List<IntVar> vars = new List<IntVar>();
298  List<long> coeffs = new List<long>();
299 
300  for (int i = 0; i < 100000; ++i)
301  {
302  vars.Add(model.NewBoolVar(""));
303  coeffs.Add(i + 1);
304  }
305 
306  var watch = System.Diagnostics.Stopwatch.StartNew();
307  model.Minimize(LinearExpr.WeightedSum(vars, coeffs));
308  watch.Stop();
309  var elapsedMs = watch.ElapsedMilliseconds;
310  Console.WriteLine($"Long: Elapsed time {elapsedMs}");
311  }
312 
313  [Fact]
314  public void LargeWeightedSumInt()
315  {
316  CpModel model = new CpModel();
317  List<IntVar> vars = new List<IntVar>();
318  List<int> coeffs = new List<int>();
319 
320  for (int i = 0; i < 100000; ++i)
321  {
322  vars.Add(model.NewBoolVar(""));
323  coeffs.Add(i);
324  }
325 
326  var watch = System.Diagnostics.Stopwatch.StartNew();
327  model.Minimize(LinearExpr.WeightedSum(vars, coeffs));
328  watch.Stop();
329  var elapsedMs = watch.ElapsedMilliseconds;
330  Console.WriteLine($"Int: Elapsed time {elapsedMs}");
331  }
332 
333  [Fact]
334  public void LargeWeightedSumExpr()
335  {
336  CpModel model = new CpModel();
337  List<LinearExpr> exprs = new List<LinearExpr>();
338 
339  for (int i = 0; i < 100000; ++i)
340  {
341  exprs.Add(model.NewBoolVar("") * i);
342  }
343 
344  var watch = System.Diagnostics.Stopwatch.StartNew();
345  model.Minimize(LinearExpr.Sum(exprs));
346  watch.Stop();
347  var elapsedMs = watch.ElapsedMilliseconds;
348  Console.WriteLine($"Exprs: Elapsed time {elapsedMs}");
349  }
350 
351  [Fact]
353  {
354  CpModel model = new CpModel();
355  List<IntVar> vars = new List<IntVar>();
356  List<long> coeffs = new List<long>();
357 
358  for (int i = 0; i < 100000; ++i)
359  {
360  vars.Add(model.NewBoolVar(""));
361  coeffs.Add(i + 1);
362  }
363 
364  var watch = System.Diagnostics.Stopwatch.StartNew();
366  for (int i = 0; i < 100000; ++i)
367  {
368  obj.AddTerm(vars[i], coeffs[i]);
369  }
370  model.Minimize(obj);
371  watch.Stop();
372  var elapsedMs = watch.ElapsedMilliseconds;
373  Console.WriteLine($"Proto: Elapsed time {elapsedMs}");
374  }
375 
376  [Fact]
378  {
379  Console.WriteLine("LinearExprStaticCompileTest");
380  CpModel model = new CpModel();
381  IntVar v1 = model.NewIntVar(-10, 10, "v1");
382  IntVar v2 = model.NewIntVar(-10, 10, "v2");
383  BoolVar b1 = model.NewBoolVar("b1");
384  BoolVar b2 = model.NewBoolVar("b2");
385  long[] c1 = new long[] { 2L, 4L };
386  int[] c2 = new int[] { 2, 4 };
387  LinearExpr e1 = LinearExpr.Sum(new IntVar[] { v1, v2 });
388  Console.WriteLine(e1.ToString());
389  LinearExpr e2 = LinearExpr.Sum(new ILiteral[] { b1, b2 });
390  Console.WriteLine(e2.ToString());
391  LinearExpr e3 = LinearExpr.Sum(new BoolVar[] { b1, b2 });
392  Console.WriteLine(e3.ToString());
393  LinearExpr e4 = LinearExpr.WeightedSum(new IntVar[] { v1, v2 }, c1);
394  Console.WriteLine(e4.ToString());
395  LinearExpr e5 = LinearExpr.WeightedSum(new ILiteral[] { b1, b2 }, c1);
396  Console.WriteLine(e5.ToString());
397  LinearExpr e6 = LinearExpr.WeightedSum(new BoolVar[] { b1, b2 }, c1);
398  Console.WriteLine(e6.ToString());
399  LinearExpr e7 = LinearExpr.WeightedSum(new IntVar[] { v1, v2 }, c2);
400  Console.WriteLine(e7.ToString());
401  LinearExpr e8 = LinearExpr.WeightedSum(new ILiteral[] { b1, b2 }, c2);
402  Console.WriteLine(e8.ToString());
403  LinearExpr e9 = LinearExpr.WeightedSum(new BoolVar[] { b1, b2 }, c2);
404  Console.WriteLine(e9.ToString());
405  }
406 
407  [Fact]
409  {
410  Console.WriteLine("LinearExprBuilderCompileTest");
411  CpModel model = new CpModel();
412  IntVar v1 = model.NewIntVar(-10, 10, "v1");
413  IntVar v2 = model.NewIntVar(-10, 10, "v2");
414  BoolVar b1 = model.NewBoolVar("b1");
415  BoolVar b2 = model.NewBoolVar("b2");
416  long[] c1 = new long[] { 2L, 4L };
417  int[] c2 = new int[] { 2, 4 };
418  LinearExpr e1 = LinearExpr.NewBuilder().AddSum(new IntVar[] { v1, v2 });
419  Console.WriteLine(e1.ToString());
420  LinearExpr e2 = LinearExpr.NewBuilder().AddSum(new ILiteral[] { b1, b2 });
421  Console.WriteLine(e2.ToString());
422  LinearExpr e3 = LinearExpr.NewBuilder().AddSum(new BoolVar[] { b1, b2 });
423  Console.WriteLine(e3.ToString());
424  LinearExpr e4 = LinearExpr.NewBuilder().AddWeightedSum(new IntVar[] { v1, v2 }, c1);
425  Console.WriteLine(e4.ToString());
426  LinearExpr e5 = LinearExpr.NewBuilder().AddWeightedSum(new ILiteral[] { b1, b2 }, c1);
427  Console.WriteLine(e5.ToString());
428  LinearExpr e6 = LinearExpr.NewBuilder().AddWeightedSum(new BoolVar[] { b1, b2 }, c1);
429  Console.WriteLine(e6.ToString());
430  LinearExpr e7 = LinearExpr.NewBuilder().AddWeightedSum(new IntVar[] { v1, v2 }, c2);
431  Console.WriteLine(e7.ToString());
432  LinearExpr e8 = LinearExpr.NewBuilder().AddWeightedSum(new ILiteral[] { b1, b2 }, c2);
433  Console.WriteLine(e8.ToString());
434  LinearExpr e9 = LinearExpr.NewBuilder().AddWeightedSum(new BoolVar[] { b1, b2 }, c2);
435  Console.WriteLine(e9.ToString());
436  LinearExpr e10 = LinearExpr.NewBuilder().Add(v1);
437  Console.WriteLine(e10.ToString());
438  LinearExpr e11 = LinearExpr.NewBuilder().Add(b1);
439  Console.WriteLine(e11.ToString());
440  LinearExpr e12 = LinearExpr.NewBuilder().Add(b1.Not());
441  Console.WriteLine(e12.ToString());
442  LinearExpr e13 = LinearExpr.NewBuilder().AddTerm(v1, -1);
443  Console.WriteLine(e13.ToString());
444  LinearExpr e14 = LinearExpr.NewBuilder().AddTerm(b1, -1);
445  Console.WriteLine(e14.ToString());
446  LinearExpr e15 = LinearExpr.NewBuilder().AddTerm(b1.Not(), -2);
447  Console.WriteLine(e15.ToString());
448  }
449 
450  [Fact]
452  {
453  Console.WriteLine("LinearExprIntVarOperatorTest");
454  CpModel model = new CpModel();
455  IntVar v = model.NewIntVar(-10, 10, "v");
456  LinearExpr e = v * 2;
457  Console.WriteLine(e);
458  e = 2 * v;
459  Console.WriteLine(e);
460  e = v + 2;
461  Console.WriteLine(e);
462  e = 2 + v;
463  Console.WriteLine(e);
464  e = v;
465  Console.WriteLine(e);
466  e = -v;
467  Console.WriteLine(e);
468  e = 1 - v;
469  Console.WriteLine(e);
470  e = v - 1;
471  Console.WriteLine(e);
472  }
473 
474  [Fact]
476  {
477  Console.WriteLine("LinearExprBoolVarOperatorTest");
478  CpModel model = new CpModel();
479  BoolVar v = model.NewBoolVar("v");
480  LinearExpr e = v * 2;
481  Console.WriteLine(e);
482  e = 2 * v;
483  Console.WriteLine(e);
484  e = v + 2;
485  Console.WriteLine(e);
486  e = 2 + v;
487  Console.WriteLine(e);
488  e = v;
489  Console.WriteLine(e);
490  e = -v;
491  Console.WriteLine(e);
492  e = 1 - v;
493  Console.WriteLine(e);
494  e = v - 1;
495  Console.WriteLine(e);
496  }
497 
498  [Fact]
500  {
501  Console.WriteLine("LinearExprBoolVarNotOperatorTest");
502  CpModel model = new CpModel();
503  ILiteral v = model.NewBoolVar("v");
504  LinearExpr e = v.NotAsExpr() * 2;
505  Console.WriteLine(e);
506  e = 2 * v.NotAsExpr();
507  Console.WriteLine(e);
508  e = v.NotAsExpr() + 2;
509  Console.WriteLine(e);
510  e = 2 + v.NotAsExpr();
511  Console.WriteLine(e);
512  e = v.NotAsExpr();
513  Console.WriteLine(e);
514  e = -v.NotAsExpr();
515  Console.WriteLine(e);
516  e = 1 - v.NotAsExpr();
517  Console.WriteLine(e);
518  e = v.NotAsExpr() - 1;
519  Console.WriteLine(e);
520  }
521  [Fact]
522  public void ExportModel()
523  {
524  CpModel model = new CpModel();
525  IntVar v1 = model.NewIntVar(-10, 10, "v1");
526  IntVar v2 = model.NewIntVar(-10, 10, "v2");
527  model.Add(-100000 <= v1 + 2 * v2 <= 100000);
528  model.Minimize(v1 - 2 * v2);
529  Assert.True(model.ExportToFile("test_model_dotnet.pbtxt"));
530  Console.WriteLine("Model written to file");
531  }
532 
533  [Fact]
534  public void SolveFromString()
535  {
536  string model_str = @"
537  {
538  ""variables"": [
539  { ""name"": ""C"", ""domain"": [ ""1"", ""9"" ] },
540  { ""name"": ""P"", ""domain"": [ ""0"", ""9"" ] },
541  { ""name"": ""I"", ""domain"": [ ""1"", ""9"" ] },
542  { ""name"": ""S"", ""domain"": [ ""0"", ""9"" ] },
543  { ""name"": ""F"", ""domain"": [ ""1"", ""9"" ] },
544  { ""name"": ""U"", ""domain"": [ ""0"", ""9"" ] },
545  { ""name"": ""N"", ""domain"": [ ""0"", ""9"" ] },
546  { ""name"": ""T"", ""domain"": [ ""1"", ""9"" ] },
547  { ""name"": ""R"", ""domain"": [ ""0"", ""9"" ] },
548  { ""name"": ""E"", ""domain"": [ ""0"", ""9"" ] }
549  ],
550  ""constraints"": [
551  { ""allDiff"": { ""exprs"": [
552  { ""vars"": [""0""], ""coeffs"": [""1""] },
553  { ""vars"": [""1""], ""coeffs"": [""1""] },
554  { ""vars"": [""2""], ""coeffs"": [""1""] },
555  { ""vars"": [""3""], ""coeffs"": [""1""] },
556  { ""vars"": [""4""], ""coeffs"": [""1""] },
557  { ""vars"": [""5""], ""coeffs"": [""1""] },
558  { ""vars"": [""6""], ""coeffs"": [""1""] },
559  { ""vars"": [""7""], ""coeffs"": [""1""] },
560  { ""vars"": [""8""], ""coeffs"": [""1""] },
561  { ""vars"": [""9""], ""coeffs"": [""1""] } ] } },
562  { ""linear"": { ""vars"": [ 6, 5, 9, 4, 3, 7, 8, 2, 0, 1 ], ""coeffs"": [ ""1"", ""0"", ""-1"", ""100"", ""1"", ""-1000"", ""-100"", ""10"", ""10"", ""1"" ], ""domain"": [ ""0"", ""0"" ] } }
563  ]
564  }";
565  CpModelProto model = Google.Protobuf.JsonParser.Default.Parse<CpModelProto>(model_str);
566  SolveWrapper solve_wrapper = new SolveWrapper();
567  CpSolverResponse response = solve_wrapper.Solve(model);
568  Console.WriteLine(response);
569  }
570 
571  [Fact]
572  public void CaptureLog()
573  {
574  Console.WriteLine("CaptureLog test");
575  CpModel model = new CpModel();
576  IntVar v1 = model.NewIntVar(-10, 10, "v1");
577  IntVar v2 = model.NewIntVar(-10, 10, "v2");
578  IntVar v3 = model.NewIntVar(-100000, 100000, "v3");
579  model.AddLinearConstraint(v1 + v2, -1000000, 100000);
580  model.AddLinearConstraint(v1 + 2 * v2 - v3, 0, 100000);
581  model.Maximize(v3);
582  Assert.Equal(v1.Domain.FlattenedIntervals(), new long[] { -10, 10 });
583  // Console.WriteLine("model = " + model.Model.ToString());
584 
585  CpSolver solver = new CpSolver();
586  solver.StringParameters = "log_search_progress:true log_to_stdout:false";
587  string log = "";
588  solver.SetLogCallback(message => log += message + "\n");
589  solver.Solve(model);
590  Assert.NotEmpty(log);
591  Assert.Contains("OPTIMAL", log);
592  }
593 
594  [Fact]
595  public void TestInterval()
596  {
597  Console.WriteLine("TestInterval test");
598  CpModel model = new CpModel();
599  IntVar v = model.NewIntVar(-10, 10, "v");
600  IntervalVar i = model.NewFixedSizeIntervalVar(v, 3, "i");
601  Assert.Equal("v", i.StartExpr().ToString());
602  Assert.Equal("3", i.SizeExpr().ToString());
603  Assert.Equal("v + 3", i.EndExpr().ToString());
604  }
605 }
606 } // namespace Google.OrTools.Tests
Holds a Boolean variable.
ILiteral Not()
Returns the Boolean negation of that variable.
void OnlyEnforceIf(ILiteral lit)
Adds a literal to the constraint.
Definition: Constraints.cs:38
Wrapper class around the cp_model proto.
Definition: CpModel.cs:24
TableConstraint AddAllowedAssignments(IEnumerable< IntVar > vars)
Adds AllowedAssignments(variables).
Definition: CpModel.cs:347
void Minimize(LinearExpr obj)
Adds a minimization objective of a linear expression.
Definition: CpModel.cs:995
Boolean ExportToFile(String file)
Write the model as a protocol buffer to file.
Definition: CpModel.cs:1143
BoolVar NewBoolVar(string name)
Creates an Boolean variable with given domain.
Definition: CpModel.cs:98
Constraint AddMultiplicationEquality(LinearExpr target, IEnumerable< LinearExpr > exprs)
Adds target == ∏(exprs).
Definition: CpModel.cs:765
void Maximize(LinearExpr obj)
Adds a maximization objective of a linear expression.
Definition: CpModel.cs:1001
IntVar NewIntVar(long lb, long ub, string name)
Creates an integer variable with domain [lb, ub].
Definition: CpModel.cs:64
Constraint Add(BoundedLinearExpression lin)
Adds a linear constraint to the model.
Definition: CpModel.cs:192
Constraint AddLinearConstraint(LinearExpr expr, long lb, long ub)
Adds lb ≤ expr ≤ ub.
Definition: CpModel.cs:141
Wrapper around the SAT solver.
Definition: CpSolver.cs:30
void SetLogCallback(StringToVoidDelegate del)
Definition: CpSolver.cs:139
CpSolverResponse Response
Definition: CpSolver.cs:145
CpSolverStatus Solve(CpModel model, SolutionCallback cb=null)
Solves the given model, and returns the solve status.
Definition: CpSolver.cs:32
long Value(IntVar intVar)
Returns the value of an integer variable in the last solution found.
Definition: CpSolver.cs:156
string StringParameters
The parameters of the search, stored as a string.
Definition: CpSolver.cs:130
Holds a integer variable with a discrete domain.
Domain Domain
Returns the domain of the variable.
LinearExpr SizeExpr()
The size expression of the interval
LinearExpr StartExpr()
The start expression of the interval
LinearExpr EndExpr()
The end expression of the interval
A builder class for linear expressions.
LinearExprBuilder Add(LinearExpr expr)
Adds expr to the builder.
LinearExprBuilder AddSum(IEnumerable< LinearExpr > exprs)
Adds sum(exprs) to the builder.
LinearExprBuilder AddWeightedSum(IEnumerable< LinearExpr > exprs, IEnumerable< long > coefficients)
Adds sum(exprs[i] * coeffs[i]) to the builder.
LinearExprBuilder AddTerm(LinearExpr expr, long coefficient)
Adds expr * coefficient to the builder.
Holds a linear expression: sum (ai * xi) + b.
static LinearExpr Sum(IEnumerable< LinearExpr > exprs)
Creates Sum(exprs).
static LinearExpr WeightedSum(IEnumerable< LinearExpr > exprs, IEnumerable< int > coeffs)
Creates Sum(exprs[i] * coeffs[i]).
static LinearExprBuilder NewBuilder(int sizeHint=2)
Creates a builder class for linear expression.
Holds a Boolean variable or its negation.
LinearExpr NotAsExpr()
Returns the Boolean negation of the literal as a linear expression.