C# CP-SAT: test new expression; reformat examples/tests/*cs
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -18,36 +18,36 @@ using static Google.OrTools.Init.operations_research_init;
|
||||
|
||||
namespace Google.OrTools.Tests
|
||||
{
|
||||
public class InitTest
|
||||
public class InitTest
|
||||
{
|
||||
[Fact]
|
||||
public void CheckLogging()
|
||||
{
|
||||
[Fact]
|
||||
public void CheckLogging()
|
||||
{
|
||||
Init.CppBridge.InitLogging("init");
|
||||
Init.CppBridge.ShutdownLogging();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckFlags()
|
||||
{
|
||||
Init.CppFlags cpp_flags = new Init.CppFlags();
|
||||
cpp_flags.logtostderr = true;
|
||||
cpp_flags.log_prefix = true;
|
||||
cpp_flags.cp_model_dump_prefix = "init";
|
||||
cpp_flags.cp_model_dump_models = true;
|
||||
cpp_flags.cp_model_dump_lns = true;
|
||||
cpp_flags.cp_model_dump_response = true;
|
||||
Init.CppBridge.SetFlags(cpp_flags);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckOrToolsVersion()
|
||||
{
|
||||
int major = OrToolsVersion.MajorNumber();
|
||||
int minor = OrToolsVersion.MinorNumber();
|
||||
int patch = OrToolsVersion.PatchNumber();
|
||||
string version = OrToolsVersion.VersionString();
|
||||
Assert.Equal($"{major}.{minor}.{patch}", version);
|
||||
}
|
||||
Init.CppBridge.InitLogging("init");
|
||||
Init.CppBridge.ShutdownLogging();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckFlags()
|
||||
{
|
||||
Init.CppFlags cpp_flags = new Init.CppFlags();
|
||||
cpp_flags.logtostderr = true;
|
||||
cpp_flags.log_prefix = true;
|
||||
cpp_flags.cp_model_dump_prefix = "init";
|
||||
cpp_flags.cp_model_dump_models = true;
|
||||
cpp_flags.cp_model_dump_lns = true;
|
||||
cpp_flags.cp_model_dump_response = true;
|
||||
Init.CppBridge.SetFlags(cpp_flags);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckOrToolsVersion()
|
||||
{
|
||||
int major = OrToolsVersion.MajorNumber();
|
||||
int minor = OrToolsVersion.MinorNumber();
|
||||
int patch = OrToolsVersion.PatchNumber();
|
||||
string version = OrToolsVersion.VersionString();
|
||||
Assert.Equal($"{major}.{minor}.{patch}", version);
|
||||
}
|
||||
}
|
||||
} // namespace Google.OrTools.Tests
|
||||
|
||||
@@ -17,402 +17,402 @@ using Google.OrTools.LinearSolver;
|
||||
|
||||
namespace Google.OrTools.Tests
|
||||
{
|
||||
public class LinearSolverTest
|
||||
public class LinearSolverTest
|
||||
{
|
||||
[Fact]
|
||||
public void VarOperator()
|
||||
{
|
||||
[Fact]
|
||||
public void VarOperator()
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(x >= 1);
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct1.Lb());
|
||||
Assert.Equal(double.PositiveInfinity, ct1.Ub());
|
||||
|
||||
Constraint ct2 = solver.Add(x <= 1);
|
||||
Assert.Equal(1.0, ct2.GetCoefficient(x));
|
||||
Assert.Equal(double.NegativeInfinity, ct2.Lb());
|
||||
Assert.Equal(1.0, ct2.Ub());
|
||||
|
||||
Constraint ct3 = solver.Add(x == 1);
|
||||
Assert.Equal(1.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct3.Lb());
|
||||
Assert.Equal(1.0, ct3.Ub());
|
||||
|
||||
Constraint ct4 = solver.Add(1 >= x);
|
||||
Assert.Equal(1.0, ct4.GetCoefficient(x));
|
||||
Assert.Equal(double.NegativeInfinity, ct4.Lb());
|
||||
Assert.Equal(1.0, ct4.Ub());
|
||||
|
||||
Constraint ct5 = solver.Add(1 <= x);
|
||||
Assert.Equal(1.0, ct5.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct5.Lb());
|
||||
Assert.Equal(double.PositiveInfinity, ct5.Ub());
|
||||
|
||||
Constraint ct6 = solver.Add(1 == x);
|
||||
Assert.Equal(1.0, ct6.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct6.Lb());
|
||||
Assert.Equal(1.0, ct6.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VarAddition()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(x + y == 1);
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(y));
|
||||
|
||||
Constraint ct2 = solver.Add(x + x == 1);
|
||||
Assert.Equal(2.0, ct2.GetCoefficient(x));
|
||||
|
||||
Constraint ct3 = solver.Add(x + (y + x) == 1);
|
||||
Assert.Equal(2.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct3.GetCoefficient(y));
|
||||
|
||||
Constraint ct4 = solver.Add(x + (y + x + 3) == 1);
|
||||
Assert.Equal(2.0, ct4.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct4.GetCoefficient(y));
|
||||
Assert.Equal(-2.0, ct4.Lb());
|
||||
Assert.Equal(-2.0, ct4.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VarMultiplication()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(3 * x == 1);
|
||||
Assert.Equal(3.0, ct1.GetCoefficient(x));
|
||||
|
||||
Constraint ct2 = solver.Add(x * 3 == 1);
|
||||
Assert.Equal(3.0, ct2.GetCoefficient(x));
|
||||
|
||||
Constraint ct3 = solver.Add(x + (2 * y + 3 * x) == 1);
|
||||
Assert.Equal(4.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(2.0, ct3.GetCoefficient(y));
|
||||
|
||||
Constraint ct4 = solver.Add(x + 5 * (y + x + 3) == 1);
|
||||
Assert.Equal(6.0, ct4.GetCoefficient(x));
|
||||
Assert.Equal(5.0, ct4.GetCoefficient(y));
|
||||
Assert.Equal(-14.0, ct4.Lb());
|
||||
Assert.Equal(-14.0, ct4.Ub());
|
||||
|
||||
Constraint ct5 = solver.Add(x + (2 * y + x + 3) * 3 == 1);
|
||||
Assert.Equal(4.0, ct5.GetCoefficient(x));
|
||||
Assert.Equal(6.0, ct5.GetCoefficient(y));
|
||||
Assert.Equal(-8.0, ct5.Lb());
|
||||
Assert.Equal(-8.0, ct5.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BinaryOperator()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(x == y);
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(x));
|
||||
Assert.Equal(-1.0, ct1.GetCoefficient(y));
|
||||
|
||||
Constraint ct2 = solver.Add(x == 3 * y + 5);
|
||||
Assert.Equal(1.0, ct2.GetCoefficient(x));
|
||||
Assert.Equal(-3.0, ct2.GetCoefficient(y));
|
||||
Assert.Equal(5.0, ct2.Lb());
|
||||
Assert.Equal(5.0, ct2.Ub());
|
||||
|
||||
Constraint ct3 = solver.Add(2 * x - 9 == y);
|
||||
Assert.Equal(2.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(-1.0, ct3.GetCoefficient(y));
|
||||
Assert.Equal(9.0, ct3.Lb());
|
||||
Assert.Equal(9.0, ct3.Ub());
|
||||
|
||||
Assert.True(x == x);
|
||||
Assert.True(!(x != x));
|
||||
Assert.True((x != y));
|
||||
Assert.True(!(x == y));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Inequalities()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(2 * (x + 3) + 5 * (y + x - 1) >= 3);
|
||||
Assert.Equal(7.0, ct1.GetCoefficient(x));
|
||||
Assert.Equal(5.0, ct1.GetCoefficient(y));
|
||||
Assert.Equal(2.0, ct1.Lb());
|
||||
Assert.Equal(double.PositiveInfinity, ct1.Ub());
|
||||
|
||||
Constraint ct2 = solver.Add(2 * (x + 3) + 5 * (y + x - 1) <= 3);
|
||||
Assert.Equal(7.0, ct2.GetCoefficient(x));
|
||||
Assert.Equal(5.0, ct2.GetCoefficient(y));
|
||||
Assert.Equal(double.NegativeInfinity, ct2.Lb());
|
||||
Assert.Equal(2.0, ct2.Ub());
|
||||
|
||||
Constraint ct3 = solver.Add(2 * (x + 3) + 5 * (y + x - 1) >= 3 - x - y);
|
||||
Assert.Equal(8.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(6.0, ct3.GetCoefficient(y));
|
||||
Assert.Equal(2.0, ct3.Lb());
|
||||
Assert.Equal(double.PositiveInfinity, ct3.Ub());
|
||||
|
||||
Constraint ct4 = solver.Add(2 * (x + 3) + 5 * (y + x - 1) <= -x - y + 3);
|
||||
Assert.Equal(8.0, ct4.GetCoefficient(x));
|
||||
Assert.Equal(6.0, ct4.GetCoefficient(y));
|
||||
Assert.Equal(double.NegativeInfinity, ct4.Lb());
|
||||
Assert.Equal(2.0, ct4.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SumArray()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
|
||||
Variable[] x = solver.MakeBoolVarArray(10, "x");
|
||||
Constraint ct1 = solver.Add(x.Sum() == 3);
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(x[0]));
|
||||
|
||||
Constraint ct2 = solver.Add(-2 * x.Sum() == 3);
|
||||
Assert.Equal(-2.0, ct2.GetCoefficient(x[0]));
|
||||
|
||||
LinearExpr[] array = new LinearExpr[] { x[0] + 2.0, x[0] + 3, x[0] + 4 };
|
||||
Constraint ct3 = solver.Add(array.Sum() == 1);
|
||||
Assert.Equal(3.0, ct3.GetCoefficient(x[0]));
|
||||
Assert.Equal(-8.0, ct3.Lb());
|
||||
Assert.Equal(-8.0, ct3.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Objective()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
solver.Maximize(x);
|
||||
Assert.Equal(0.0, solver.Objective().Offset());
|
||||
Assert.Equal(1.0, solver.Objective().GetCoefficient(x));
|
||||
Assert.True(solver.Objective().Maximization());
|
||||
|
||||
solver.Minimize(-x - 2 * y + 3);
|
||||
Assert.Equal(3.0, solver.Objective().Offset());
|
||||
Assert.Equal(-1.0, solver.Objective().GetCoefficient(x));
|
||||
Assert.Equal(-2.0, solver.Objective().GetCoefficient(y));
|
||||
Assert.True(solver.Objective().Minimization());
|
||||
}
|
||||
|
||||
void SolveAndPrint(in Solver solver, in Variable[] variables, in Constraint[] constraints)
|
||||
{
|
||||
Console.WriteLine($"Number of variables = {solver.NumVariables()}");
|
||||
Console.WriteLine($"Number of constraints = {solver.NumConstraints()}");
|
||||
|
||||
Solver.ResultStatus resultStatus = solver.Solve();
|
||||
// Check that the problem has an optimal solution.
|
||||
if (resultStatus != Solver.ResultStatus.OPTIMAL)
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(x >= 1);
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct1.Lb());
|
||||
Assert.Equal(double.PositiveInfinity, ct1.Ub());
|
||||
|
||||
Constraint ct2 = solver.Add(x <= 1);
|
||||
Assert.Equal(1.0, ct2.GetCoefficient(x));
|
||||
Assert.Equal(double.NegativeInfinity, ct2.Lb());
|
||||
Assert.Equal(1.0, ct2.Ub());
|
||||
|
||||
Constraint ct3 = solver.Add(x == 1);
|
||||
Assert.Equal(1.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct3.Lb());
|
||||
Assert.Equal(1.0, ct3.Ub());
|
||||
|
||||
Constraint ct4 = solver.Add(1 >= x);
|
||||
Assert.Equal(1.0, ct4.GetCoefficient(x));
|
||||
Assert.Equal(double.NegativeInfinity, ct4.Lb());
|
||||
Assert.Equal(1.0, ct4.Ub());
|
||||
|
||||
Constraint ct5 = solver.Add(1 <= x);
|
||||
Assert.Equal(1.0, ct5.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct5.Lb());
|
||||
Assert.Equal(double.PositiveInfinity, ct5.Ub());
|
||||
|
||||
Constraint ct6 = solver.Add(1 == x);
|
||||
Assert.Equal(1.0, ct6.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct6.Lb());
|
||||
Assert.Equal(1.0, ct6.Ub());
|
||||
Console.WriteLine("The problem does not have an optimal solution!");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VarAddition()
|
||||
else
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(x + y == 1);
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(y));
|
||||
|
||||
Constraint ct2 = solver.Add(x + x == 1);
|
||||
Assert.Equal(2.0, ct2.GetCoefficient(x));
|
||||
|
||||
Constraint ct3 = solver.Add(x + (y + x) == 1);
|
||||
Assert.Equal(2.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct3.GetCoefficient(y));
|
||||
|
||||
Constraint ct4 = solver.Add(x + (y + x + 3) == 1);
|
||||
Assert.Equal(2.0, ct4.GetCoefficient(x));
|
||||
Assert.Equal(1.0, ct4.GetCoefficient(y));
|
||||
Assert.Equal(-2.0, ct4.Lb());
|
||||
Assert.Equal(-2.0, ct4.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VarMultiplication()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(3 * x == 1);
|
||||
Assert.Equal(3.0, ct1.GetCoefficient(x));
|
||||
|
||||
Constraint ct2 = solver.Add(x * 3 == 1);
|
||||
Assert.Equal(3.0, ct2.GetCoefficient(x));
|
||||
|
||||
Constraint ct3 = solver.Add(x + (2 * y + 3 * x) == 1);
|
||||
Assert.Equal(4.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(2.0, ct3.GetCoefficient(y));
|
||||
|
||||
Constraint ct4 = solver.Add(x + 5 * (y + x + 3) == 1);
|
||||
Assert.Equal(6.0, ct4.GetCoefficient(x));
|
||||
Assert.Equal(5.0, ct4.GetCoefficient(y));
|
||||
Assert.Equal(-14.0, ct4.Lb());
|
||||
Assert.Equal(-14.0, ct4.Ub());
|
||||
|
||||
Constraint ct5 = solver.Add(x + (2 * y + x + 3) * 3 == 1);
|
||||
Assert.Equal(4.0, ct5.GetCoefficient(x));
|
||||
Assert.Equal(6.0, ct5.GetCoefficient(y));
|
||||
Assert.Equal(-8.0, ct5.Lb());
|
||||
Assert.Equal(-8.0, ct5.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BinaryOperator()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(x == y);
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(x));
|
||||
Assert.Equal(-1.0, ct1.GetCoefficient(y));
|
||||
|
||||
Constraint ct2 = solver.Add(x == 3 * y + 5);
|
||||
Assert.Equal(1.0, ct2.GetCoefficient(x));
|
||||
Assert.Equal(-3.0, ct2.GetCoefficient(y));
|
||||
Assert.Equal(5.0, ct2.Lb());
|
||||
Assert.Equal(5.0, ct2.Ub());
|
||||
|
||||
Constraint ct3 = solver.Add(2 * x - 9 == y);
|
||||
Assert.Equal(2.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(-1.0, ct3.GetCoefficient(y));
|
||||
Assert.Equal(9.0, ct3.Lb());
|
||||
Assert.Equal(9.0, ct3.Ub());
|
||||
|
||||
Assert.True(x == x);
|
||||
Assert.True(!(x != x));
|
||||
Assert.True((x != y));
|
||||
Assert.True(!(x == y));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Inequalities()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
Constraint ct1 = solver.Add(2 * (x + 3) + 5 * (y + x - 1) >= 3);
|
||||
Assert.Equal(7.0, ct1.GetCoefficient(x));
|
||||
Assert.Equal(5.0, ct1.GetCoefficient(y));
|
||||
Assert.Equal(2.0, ct1.Lb());
|
||||
Assert.Equal(double.PositiveInfinity, ct1.Ub());
|
||||
|
||||
Constraint ct2 = solver.Add(2 * (x + 3) + 5 * (y + x - 1) <= 3);
|
||||
Assert.Equal(7.0, ct2.GetCoefficient(x));
|
||||
Assert.Equal(5.0, ct2.GetCoefficient(y));
|
||||
Assert.Equal(double.NegativeInfinity, ct2.Lb());
|
||||
Assert.Equal(2.0, ct2.Ub());
|
||||
|
||||
Constraint ct3 = solver.Add(2 * (x + 3) + 5 * (y + x - 1) >= 3 - x - y);
|
||||
Assert.Equal(8.0, ct3.GetCoefficient(x));
|
||||
Assert.Equal(6.0, ct3.GetCoefficient(y));
|
||||
Assert.Equal(2.0, ct3.Lb());
|
||||
Assert.Equal(double.PositiveInfinity, ct3.Ub());
|
||||
|
||||
Constraint ct4 = solver.Add(2 * (x + 3) + 5 * (y + x - 1) <= -x - y + 3);
|
||||
Assert.Equal(8.0, ct4.GetCoefficient(x));
|
||||
Assert.Equal(6.0, ct4.GetCoefficient(y));
|
||||
Assert.Equal(double.NegativeInfinity, ct4.Lb());
|
||||
Assert.Equal(2.0, ct4.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SumArray()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
|
||||
Variable[] x = solver.MakeBoolVarArray(10, "x");
|
||||
Constraint ct1 = solver.Add(x.Sum() == 3);
|
||||
Assert.Equal(1.0, ct1.GetCoefficient(x[0]));
|
||||
|
||||
Constraint ct2 = solver.Add(-2 * x.Sum() == 3);
|
||||
Assert.Equal(-2.0, ct2.GetCoefficient(x[0]));
|
||||
|
||||
LinearExpr[] array = new LinearExpr[] { x[0] + 2.0, x[0] + 3, x[0] + 4 };
|
||||
Constraint ct3 = solver.Add(array.Sum() == 1);
|
||||
Assert.Equal(3.0, ct3.GetCoefficient(x[0]));
|
||||
Assert.Equal(-8.0, ct3.Lb());
|
||||
Assert.Equal(-8.0, ct3.Ub());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Objective()
|
||||
{
|
||||
Solver solver = Solver.CreateSolver("CLP");
|
||||
Variable x = solver.MakeNumVar(0.0, 100.0, "x");
|
||||
Assert.Equal(0.0, x.Lb());
|
||||
Assert.Equal(100.0, x.Ub());
|
||||
|
||||
Variable y = solver.MakeNumVar(0.0, 100.0, "y");
|
||||
Assert.Equal(0.0, y.Lb());
|
||||
Assert.Equal(100.0, y.Ub());
|
||||
|
||||
solver.Maximize(x);
|
||||
Assert.Equal(0.0, solver.Objective().Offset());
|
||||
Assert.Equal(1.0, solver.Objective().GetCoefficient(x));
|
||||
Assert.True(solver.Objective().Maximization());
|
||||
|
||||
solver.Minimize(-x - 2 * y + 3);
|
||||
Assert.Equal(3.0, solver.Objective().Offset());
|
||||
Assert.Equal(-1.0, solver.Objective().GetCoefficient(x));
|
||||
Assert.Equal(-2.0, solver.Objective().GetCoefficient(y));
|
||||
Assert.True(solver.Objective().Minimization());
|
||||
}
|
||||
|
||||
void SolveAndPrint(in Solver solver, in Variable[] variables, in Constraint[] constraints)
|
||||
{
|
||||
Console.WriteLine($"Number of variables = {solver.NumVariables()}");
|
||||
Console.WriteLine($"Number of constraints = {solver.NumConstraints()}");
|
||||
|
||||
Solver.ResultStatus resultStatus = solver.Solve();
|
||||
// Check that the problem has an optimal solution.
|
||||
if (resultStatus != Solver.ResultStatus.OPTIMAL)
|
||||
Console.WriteLine("Solution:");
|
||||
foreach (Variable var in variables)
|
||||
{
|
||||
Console.WriteLine("The problem does not have an optimal solution!");
|
||||
Console.WriteLine($"{var.Name()} = {var.SolutionValue()}");
|
||||
}
|
||||
else
|
||||
Console.WriteLine($"Optimal objective value = {solver.Objective().Value()}");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("Advanced usage:");
|
||||
Console.WriteLine($"Problem solved in {solver.WallTime()} milliseconds");
|
||||
Console.WriteLine($"Problem solved in {solver.Iterations()} iterations");
|
||||
foreach (Variable var in variables)
|
||||
{
|
||||
Console.WriteLine("Solution:");
|
||||
foreach (Variable var in variables)
|
||||
{
|
||||
Console.WriteLine($"{var.Name()} = {var.SolutionValue()}");
|
||||
}
|
||||
Console.WriteLine($"Optimal objective value = {solver.Objective().Value()}");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("Advanced usage:");
|
||||
Console.WriteLine($"Problem solved in {solver.WallTime()} milliseconds");
|
||||
Console.WriteLine($"Problem solved in {solver.Iterations()} iterations");
|
||||
foreach (Variable var in variables)
|
||||
{
|
||||
Console.WriteLine($"{var.Name()}: reduced cost {var.ReducedCost()}");
|
||||
}
|
||||
|
||||
double[] activities = solver.ComputeConstraintActivities();
|
||||
foreach (Constraint ct in constraints)
|
||||
{
|
||||
Console.WriteLine($"{ct.Name()}: dual value = {ct.DualValue()}",
|
||||
$" activity = {activities[ct.Index()]}");
|
||||
}
|
||||
Console.WriteLine($"{var.Name()}: reduced cost {var.ReducedCost()}");
|
||||
}
|
||||
}
|
||||
|
||||
void RunLinearProgrammingExample(in String problemType)
|
||||
{
|
||||
Console.WriteLine($"------ Linear programming example with {problemType} ------");
|
||||
|
||||
Solver solver = Solver.CreateSolver(problemType);
|
||||
if (solver == null)
|
||||
return;
|
||||
|
||||
// x and y are continuous non-negative variables.
|
||||
Variable x = solver.MakeNumVar(0.0, double.PositiveInfinity, "x");
|
||||
Variable y = solver.MakeNumVar(0.0, double.PositiveInfinity, "y");
|
||||
|
||||
// Objectif function: Maximize 3x + 4y.
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetCoefficient(x, 3);
|
||||
objective.SetCoefficient(y, 4);
|
||||
objective.SetMaximization();
|
||||
|
||||
// x + 2y <= 14.
|
||||
Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 14.0, "c0");
|
||||
c0.SetCoefficient(x, 1);
|
||||
c0.SetCoefficient(y, 2);
|
||||
|
||||
// 3x - y >= 0.
|
||||
Constraint c1 = solver.MakeConstraint(0.0, double.PositiveInfinity, "c1");
|
||||
c1.SetCoefficient(x, 3);
|
||||
c1.SetCoefficient(y, -1);
|
||||
|
||||
// x - y <= 2.
|
||||
Constraint c2 = solver.MakeConstraint(double.NegativeInfinity, 2.0, "c2");
|
||||
c2.SetCoefficient(x, 1);
|
||||
c2.SetCoefficient(y, -1);
|
||||
|
||||
SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0, c1, c2 });
|
||||
}
|
||||
void RunMixedIntegerProgrammingExample(in String problemType)
|
||||
{
|
||||
Console.WriteLine($"------ Mixed integer programming example with {problemType} ------");
|
||||
|
||||
Solver solver = Solver.CreateSolver(problemType);
|
||||
if (solver == null)
|
||||
return;
|
||||
|
||||
// x and y are integers non-negative variables.
|
||||
Variable x = solver.MakeIntVar(0.0, double.PositiveInfinity, "x");
|
||||
Variable y = solver.MakeIntVar(0.0, double.PositiveInfinity, "y");
|
||||
|
||||
// Objectif function: Maximize x + 10 * y.
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetCoefficient(x, 1);
|
||||
objective.SetCoefficient(y, 10);
|
||||
objective.SetMaximization();
|
||||
|
||||
// x + 7 * y <= 17.5.
|
||||
Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 17.5, "c0");
|
||||
c0.SetCoefficient(x, 1);
|
||||
c0.SetCoefficient(y, 7);
|
||||
|
||||
// x <= 3.5.
|
||||
Constraint c1 = solver.MakeConstraint(double.NegativeInfinity, 3.5, "c1");
|
||||
c1.SetCoefficient(x, 1);
|
||||
c1.SetCoefficient(y, 0);
|
||||
|
||||
SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0, c1 });
|
||||
}
|
||||
void RunBooleanProgrammingExample(in String problemType)
|
||||
{
|
||||
Console.WriteLine($"------ Boolean programming example with {problemType} ------");
|
||||
|
||||
Solver solver = Solver.CreateSolver(problemType);
|
||||
if (solver == null)
|
||||
return;
|
||||
|
||||
// x and y are boolean variables.
|
||||
Variable x = solver.MakeBoolVar("x");
|
||||
Variable y = solver.MakeBoolVar("y");
|
||||
|
||||
// Objectif function: Maximize 2 * x + y.
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetCoefficient(x, 2);
|
||||
objective.SetCoefficient(y, 1);
|
||||
objective.SetMinimization();
|
||||
|
||||
// 1 <= x + 2 * y <= 3.
|
||||
Constraint c0 = solver.MakeConstraint(1, 3, "c0");
|
||||
c0.SetCoefficient(x, 1);
|
||||
c0.SetCoefficient(y, 2);
|
||||
|
||||
SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OptimizationProblemType()
|
||||
{
|
||||
RunLinearProgrammingExample("GLOP");
|
||||
RunLinearProgrammingExample("GLPK_LP");
|
||||
RunLinearProgrammingExample("CLP");
|
||||
RunLinearProgrammingExample("GUROBI_LP");
|
||||
|
||||
RunMixedIntegerProgrammingExample("GLPK");
|
||||
RunMixedIntegerProgrammingExample("CBC");
|
||||
RunMixedIntegerProgrammingExample("SCIP");
|
||||
RunMixedIntegerProgrammingExample("SAT");
|
||||
|
||||
RunBooleanProgrammingExample("SAT");
|
||||
RunBooleanProgrammingExample("BOP");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
static void testSetHintAndSolverGetters()
|
||||
{
|
||||
Console.WriteLine("testSetHintAndSolverGetters");
|
||||
Solver solver = Solver.CreateSolver("glop");
|
||||
// x and y are continuous non-negative variables.
|
||||
Variable x = solver.MakeIntVar(0.0, double.PositiveInfinity, "x");
|
||||
Variable y = solver.MakeIntVar(0.0, double.PositiveInfinity, "y");
|
||||
|
||||
// Objectif function: Maximize x + 10 * y.
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetCoefficient(x, 1);
|
||||
objective.SetCoefficient(y, 10);
|
||||
objective.SetMaximization();
|
||||
|
||||
// x + 7 * y <= 17.5.
|
||||
Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 17.5, "c0");
|
||||
c0.SetCoefficient(x, 1);
|
||||
c0.SetCoefficient(y, 7);
|
||||
|
||||
// x <= 3.5.
|
||||
Constraint c1 = solver.MakeConstraint(double.NegativeInfinity, 3.5, "c1");
|
||||
c1.SetCoefficient(x, 1);
|
||||
c1.SetCoefficient(y, 0);
|
||||
|
||||
Constraint[] constraints = solver.constraints();
|
||||
Assert.Equal(constraints.Length, 2);
|
||||
Variable[] variables = solver.variables();
|
||||
Assert.Equal(variables.Length, 2);
|
||||
|
||||
solver.SetHint(new Variable[] { x, y }, new double[] { 2.0, 3.0 });
|
||||
double[] activities = solver.ComputeConstraintActivities();
|
||||
foreach (Constraint ct in constraints)
|
||||
{
|
||||
Console.WriteLine($"{ct.Name()}: dual value = {ct.DualValue()}",
|
||||
$" activity = {activities[ct.Index()]}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RunLinearProgrammingExample(in String problemType)
|
||||
{
|
||||
Console.WriteLine($"------ Linear programming example with {problemType} ------");
|
||||
|
||||
Solver solver = Solver.CreateSolver(problemType);
|
||||
if (solver == null)
|
||||
return;
|
||||
|
||||
// x and y are continuous non-negative variables.
|
||||
Variable x = solver.MakeNumVar(0.0, double.PositiveInfinity, "x");
|
||||
Variable y = solver.MakeNumVar(0.0, double.PositiveInfinity, "y");
|
||||
|
||||
// Objectif function: Maximize 3x + 4y.
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetCoefficient(x, 3);
|
||||
objective.SetCoefficient(y, 4);
|
||||
objective.SetMaximization();
|
||||
|
||||
// x + 2y <= 14.
|
||||
Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 14.0, "c0");
|
||||
c0.SetCoefficient(x, 1);
|
||||
c0.SetCoefficient(y, 2);
|
||||
|
||||
// 3x - y >= 0.
|
||||
Constraint c1 = solver.MakeConstraint(0.0, double.PositiveInfinity, "c1");
|
||||
c1.SetCoefficient(x, 3);
|
||||
c1.SetCoefficient(y, -1);
|
||||
|
||||
// x - y <= 2.
|
||||
Constraint c2 = solver.MakeConstraint(double.NegativeInfinity, 2.0, "c2");
|
||||
c2.SetCoefficient(x, 1);
|
||||
c2.SetCoefficient(y, -1);
|
||||
|
||||
SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0, c1, c2 });
|
||||
}
|
||||
void RunMixedIntegerProgrammingExample(in String problemType)
|
||||
{
|
||||
Console.WriteLine($"------ Mixed integer programming example with {problemType} ------");
|
||||
|
||||
Solver solver = Solver.CreateSolver(problemType);
|
||||
if (solver == null)
|
||||
return;
|
||||
|
||||
// x and y are integers non-negative variables.
|
||||
Variable x = solver.MakeIntVar(0.0, double.PositiveInfinity, "x");
|
||||
Variable y = solver.MakeIntVar(0.0, double.PositiveInfinity, "y");
|
||||
|
||||
// Objectif function: Maximize x + 10 * y.
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetCoefficient(x, 1);
|
||||
objective.SetCoefficient(y, 10);
|
||||
objective.SetMaximization();
|
||||
|
||||
// x + 7 * y <= 17.5.
|
||||
Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 17.5, "c0");
|
||||
c0.SetCoefficient(x, 1);
|
||||
c0.SetCoefficient(y, 7);
|
||||
|
||||
// x <= 3.5.
|
||||
Constraint c1 = solver.MakeConstraint(double.NegativeInfinity, 3.5, "c1");
|
||||
c1.SetCoefficient(x, 1);
|
||||
c1.SetCoefficient(y, 0);
|
||||
|
||||
SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0, c1 });
|
||||
}
|
||||
void RunBooleanProgrammingExample(in String problemType)
|
||||
{
|
||||
Console.WriteLine($"------ Boolean programming example with {problemType} ------");
|
||||
|
||||
Solver solver = Solver.CreateSolver(problemType);
|
||||
if (solver == null)
|
||||
return;
|
||||
|
||||
// x and y are boolean variables.
|
||||
Variable x = solver.MakeBoolVar("x");
|
||||
Variable y = solver.MakeBoolVar("y");
|
||||
|
||||
// Objectif function: Maximize 2 * x + y.
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetCoefficient(x, 2);
|
||||
objective.SetCoefficient(y, 1);
|
||||
objective.SetMinimization();
|
||||
|
||||
// 1 <= x + 2 * y <= 3.
|
||||
Constraint c0 = solver.MakeConstraint(1, 3, "c0");
|
||||
c0.SetCoefficient(x, 1);
|
||||
c0.SetCoefficient(y, 2);
|
||||
|
||||
SolveAndPrint(solver, new Variable[] { x, y }, new Constraint[] { c0 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OptimizationProblemType()
|
||||
{
|
||||
RunLinearProgrammingExample("GLOP");
|
||||
RunLinearProgrammingExample("GLPK_LP");
|
||||
RunLinearProgrammingExample("CLP");
|
||||
RunLinearProgrammingExample("GUROBI_LP");
|
||||
|
||||
RunMixedIntegerProgrammingExample("GLPK");
|
||||
RunMixedIntegerProgrammingExample("CBC");
|
||||
RunMixedIntegerProgrammingExample("SCIP");
|
||||
RunMixedIntegerProgrammingExample("SAT");
|
||||
|
||||
RunBooleanProgrammingExample("SAT");
|
||||
RunBooleanProgrammingExample("BOP");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
static void testSetHintAndSolverGetters()
|
||||
{
|
||||
Console.WriteLine("testSetHintAndSolverGetters");
|
||||
Solver solver = Solver.CreateSolver("glop");
|
||||
// x and y are continuous non-negative variables.
|
||||
Variable x = solver.MakeIntVar(0.0, double.PositiveInfinity, "x");
|
||||
Variable y = solver.MakeIntVar(0.0, double.PositiveInfinity, "y");
|
||||
|
||||
// Objectif function: Maximize x + 10 * y.
|
||||
Objective objective = solver.Objective();
|
||||
objective.SetCoefficient(x, 1);
|
||||
objective.SetCoefficient(y, 10);
|
||||
objective.SetMaximization();
|
||||
|
||||
// x + 7 * y <= 17.5.
|
||||
Constraint c0 = solver.MakeConstraint(double.NegativeInfinity, 17.5, "c0");
|
||||
c0.SetCoefficient(x, 1);
|
||||
c0.SetCoefficient(y, 7);
|
||||
|
||||
// x <= 3.5.
|
||||
Constraint c1 = solver.MakeConstraint(double.NegativeInfinity, 3.5, "c1");
|
||||
c1.SetCoefficient(x, 1);
|
||||
c1.SetCoefficient(y, 0);
|
||||
|
||||
Constraint[] constraints = solver.constraints();
|
||||
Assert.Equal(constraints.Length, 2);
|
||||
Variable[] variables = solver.variables();
|
||||
Assert.Equal(variables.Length, 2);
|
||||
|
||||
solver.SetHint(new Variable[] { x, y }, new double[] { 2.0, 3.0 });
|
||||
}
|
||||
}
|
||||
} // namespace Google.OrTools.Tests
|
||||
|
||||
@@ -17,191 +17,186 @@ using Google.OrTools.ConstraintSolver;
|
||||
|
||||
namespace Google.OrTools.Tests
|
||||
{
|
||||
public class RoutingSolverTest
|
||||
public class RoutingSolverTest
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void SimpleLambdaCallback(bool callGC)
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public void SimpleLambdaCallback(bool callGC)
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
int transitCallbackIndex = routing.RegisterTransitCallback((long fromIndex, long toIndex) =>
|
||||
{
|
||||
// Convert from routing variable Index to
|
||||
// distance matrix NodeIndex.
|
||||
var fromNode = manager.IndexToNode(fromIndex);
|
||||
var toNode = manager.IndexToNode(toIndex);
|
||||
return Math.Abs(toNode - fromNode);
|
||||
});
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
if (callGC)
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
int transitCallbackIndex = routing.RegisterTransitCallback((long fromIndex, long toIndex) => {
|
||||
// Convert from routing variable Index to distance matrix NodeIndex.
|
||||
var fromNode = manager.IndexToNode(fromIndex);
|
||||
var toNode = manager.IndexToNode(toIndex);
|
||||
return Math.Abs(toNode - fromNode);
|
||||
});
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
if (callGC)
|
||||
{
|
||||
GC.Collect();
|
||||
}
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+4)-> 0 := +8
|
||||
Assert.Equal(8, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestTransitMatrix()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
long[][] matrix = new long[][] {
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
};
|
||||
int transitCallbackIndex = routing.RegisterTransitMatrix(matrix);
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+1)-> 0 := +5
|
||||
Assert.Equal(5, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestTransitCallback()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
int transitCallbackIndex = routing.RegisterTransitCallback(
|
||||
(long fromIndex, long toIndex) => {
|
||||
// Convert from routing variable Index to distance matrix NodeIndex.
|
||||
var fromNode = manager.IndexToNode(fromIndex);
|
||||
var toNode = manager.IndexToNode(toIndex);
|
||||
return Math.Abs(toNode - fromNode);
|
||||
});
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
Assert.Equal(8, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestMatrixDimension()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
long[][] matrix = new long[][] {
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
new long[] {1, 1, 1, 1, 1},
|
||||
};
|
||||
IntBoolPair result = routing.AddMatrixDimension(
|
||||
matrix,
|
||||
/*capacity=*/10,
|
||||
/*fix_start_cumul_to_zero=*/true,
|
||||
"Dimension");
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(result.first);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+1)-> 0 := +5
|
||||
Assert.Equal(5, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestUnaryTransitVector()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
long[] vector = {1, 1, 1, 1, 1};
|
||||
int transitCallbackIndex = routing.RegisterUnaryTransitVector(vector);
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+1)-> 0 := +5
|
||||
Assert.Equal(5, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestUnaryTransitCallback()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
int transitCallbackIndex = routing.RegisterUnaryTransitCallback(
|
||||
(long fromIndex) => {
|
||||
// Convert from routing variable Index to distance matrix NodeIndex.
|
||||
var fromNode = manager.IndexToNode(fromIndex);
|
||||
return fromNode + 1;
|
||||
});
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+2)-> 2 --(+3)-> 3 --(+4)-> 4 --(+5)-> 0 := +15
|
||||
Assert.Equal(15, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestVectorDimension()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
long[] vector = new long[] {1, 1, 1, 1, 1};
|
||||
IntBoolPair result = routing.AddVectorDimension(
|
||||
vector,
|
||||
/*capacity=*/10,
|
||||
/*fix_start_cumul_to_zero=*/true,
|
||||
"Dimension");
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(result.first);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+1)-> 0 := +5
|
||||
Assert.Equal(5, solution.ObjectiveValue());
|
||||
GC.Collect();
|
||||
}
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+4)-> 0 := +8
|
||||
Assert.Equal(8, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestTransitMatrix()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
long[][] matrix = new long[][] {
|
||||
new long[] { 1, 1, 1, 1, 1 }, new long[] { 1, 1, 1, 1, 1 }, new long[] { 1, 1, 1, 1, 1 },
|
||||
new long[] { 1, 1, 1, 1, 1 }, new long[] { 1, 1, 1, 1, 1 },
|
||||
};
|
||||
int transitCallbackIndex = routing.RegisterTransitMatrix(matrix);
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+1)-> 0 := +5
|
||||
Assert.Equal(5, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestTransitCallback()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
int transitCallbackIndex = routing.RegisterTransitCallback((long fromIndex, long toIndex) =>
|
||||
{
|
||||
// Convert from routing variable Index to
|
||||
// distance matrix NodeIndex.
|
||||
var fromNode = manager.IndexToNode(fromIndex);
|
||||
var toNode = manager.IndexToNode(toIndex);
|
||||
return Math.Abs(toNode - fromNode);
|
||||
});
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
Assert.Equal(8, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestMatrixDimension()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
long[][] matrix = new long[][] {
|
||||
new long[] { 1, 1, 1, 1, 1 }, new long[] { 1, 1, 1, 1, 1 }, new long[] { 1, 1, 1, 1, 1 },
|
||||
new long[] { 1, 1, 1, 1, 1 }, new long[] { 1, 1, 1, 1, 1 },
|
||||
};
|
||||
IntBoolPair result = routing.AddMatrixDimension(matrix,
|
||||
/*capacity=*/10,
|
||||
/*fix_start_cumul_to_zero=*/true, "Dimension");
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(result.first);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+1)-> 0 := +5
|
||||
Assert.Equal(5, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestUnaryTransitVector()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
long[] vector = { 1, 1, 1, 1, 1 };
|
||||
int transitCallbackIndex = routing.RegisterUnaryTransitVector(vector);
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+1)-> 0 := +5
|
||||
Assert.Equal(5, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestUnaryTransitCallback()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
int transitCallbackIndex = routing.RegisterUnaryTransitCallback((long fromIndex) =>
|
||||
{
|
||||
// Convert from routing variable Index to
|
||||
// distance matrix NodeIndex.
|
||||
var fromNode =
|
||||
manager.IndexToNode(fromIndex);
|
||||
return fromNode + 1;
|
||||
});
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+2)-> 2 --(+3)-> 3 --(+4)-> 4 --(+5)-> 0 := +15
|
||||
Assert.Equal(15, solution.ObjectiveValue());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestVectorDimension()
|
||||
{
|
||||
// Create Routing Index Manager
|
||||
RoutingIndexManager manager = new RoutingIndexManager(5 /*locations*/, 1 /*vehicle*/, 0 /*depot*/);
|
||||
// Create Routing Model.
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// Create a distance callback.
|
||||
long[] vector = new long[] { 1, 1, 1, 1, 1 };
|
||||
IntBoolPair result = routing.AddVectorDimension(vector,
|
||||
/*capacity=*/10,
|
||||
/*fix_start_cumul_to_zero=*/true, "Dimension");
|
||||
// Define cost of each arc.
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(result.first);
|
||||
// Setting first solution heuristic.
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// 0 --(+1)-> 1 --(+1)-> 2 --(+1)-> 3 --(+1)-> 4 --(+1)-> 0 := +5
|
||||
Assert.Equal(5, solution.ObjectiveValue());
|
||||
}
|
||||
}
|
||||
} // namespace Google.OrTools.Tests
|
||||
|
||||
@@ -18,376 +18,437 @@ using Google.OrTools.Sat;
|
||||
|
||||
namespace Google.OrTools.Tests
|
||||
{
|
||||
public class SatSolverTest
|
||||
public class SatSolverTest
|
||||
{
|
||||
static IntegerVariableProto NewIntegerVariable(long lb, long ub)
|
||||
{
|
||||
static IntegerVariableProto NewIntegerVariable(long lb, long ub)
|
||||
IntegerVariableProto var = new IntegerVariableProto();
|
||||
var.Domain.Add(lb);
|
||||
var.Domain.Add(ub);
|
||||
return var;
|
||||
}
|
||||
|
||||
static ConstraintProto NewLinear2(int v1, int v2, long c1, long c2, long lb, long ub)
|
||||
{
|
||||
LinearConstraintProto linear = new LinearConstraintProto();
|
||||
linear.Vars.Add(v1);
|
||||
linear.Vars.Add(v2);
|
||||
linear.Coeffs.Add(c1);
|
||||
linear.Coeffs.Add(c2);
|
||||
linear.Domain.Add(lb);
|
||||
linear.Domain.Add(ub);
|
||||
ConstraintProto ct = new ConstraintProto();
|
||||
ct.Linear = linear;
|
||||
return ct;
|
||||
}
|
||||
|
||||
static ConstraintProto NewLinear3(int v1, int v2, int v3, long c1, long c2, long c3, long lb, long ub)
|
||||
{
|
||||
LinearConstraintProto linear = new LinearConstraintProto();
|
||||
linear.Vars.Add(v1);
|
||||
linear.Vars.Add(v2);
|
||||
linear.Vars.Add(v3);
|
||||
linear.Coeffs.Add(c1);
|
||||
linear.Coeffs.Add(c2);
|
||||
linear.Coeffs.Add(c3);
|
||||
linear.Domain.Add(lb);
|
||||
linear.Domain.Add(ub);
|
||||
ConstraintProto ct = new ConstraintProto();
|
||||
ct.Linear = linear;
|
||||
return ct;
|
||||
}
|
||||
|
||||
static CpObjectiveProto NewMinimize1(int v1, long c1)
|
||||
{
|
||||
CpObjectiveProto obj = new CpObjectiveProto();
|
||||
obj.Vars.Add(v1);
|
||||
obj.Coeffs.Add(c1);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static CpObjectiveProto NewMaximize1(int v1, long c1)
|
||||
{
|
||||
CpObjectiveProto obj = new CpObjectiveProto();
|
||||
obj.Vars.Add(-v1 - 1);
|
||||
obj.Coeffs.Add(c1);
|
||||
obj.ScalingFactor = -1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
static CpObjectiveProto NewMaximize2(int v1, int v2, long c1, long c2)
|
||||
{
|
||||
CpObjectiveProto obj = new CpObjectiveProto();
|
||||
obj.Vars.Add(-v1 - 1);
|
||||
obj.Vars.Add(-v2 - 1);
|
||||
obj.Coeffs.Add(c1);
|
||||
obj.Coeffs.Add(c2);
|
||||
obj.ScalingFactor = -1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
// CpModelProto
|
||||
[Fact]
|
||||
public void SimpleLinearModelProto()
|
||||
{
|
||||
CpModelProto model = new CpModelProto();
|
||||
model.Variables.Add(NewIntegerVariable(-10, 10));
|
||||
model.Variables.Add(NewIntegerVariable(-10, 10));
|
||||
model.Variables.Add(NewIntegerVariable(-1000000, 1000000));
|
||||
model.Constraints.Add(NewLinear2(0, 1, 1, 1, -1000000, 100000));
|
||||
model.Constraints.Add(NewLinear3(0, 1, 2, 1, 2, -1, 0, 100000));
|
||||
model.Objective = NewMaximize1(2, 1);
|
||||
// Console.WriteLine("model = " + model.ToString());
|
||||
SolveWrapper solve_wrapper = new SolveWrapper();
|
||||
CpSolverResponse response = solve_wrapper.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, response.Status);
|
||||
Assert.Equal(30, response.ObjectiveValue);
|
||||
Assert.Equal(new long[] { 10, 10, 30 }, response.Solution);
|
||||
// Console.WriteLine("response = " + response.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleLinearModelProto2()
|
||||
{
|
||||
CpModelProto model = new CpModelProto();
|
||||
model.Variables.Add(NewIntegerVariable(-10, 10));
|
||||
model.Variables.Add(NewIntegerVariable(-10, 10));
|
||||
model.Constraints.Add(NewLinear2(0, 1, 1, 1, -1000000, 100000));
|
||||
model.Objective = NewMaximize2(0, 1, 1, -2);
|
||||
// Console.WriteLine("model = " + model.ToString());
|
||||
|
||||
SolveWrapper solve_wrapper = new SolveWrapper();
|
||||
CpSolverResponse response = solve_wrapper.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, response.Status);
|
||||
Assert.Equal(30, response.ObjectiveValue);
|
||||
Assert.Equal(new long[] { 10, -10 }, response.Solution);
|
||||
// Console.WriteLine("response = " + response.ToString());
|
||||
}
|
||||
|
||||
// CpModel
|
||||
[Fact]
|
||||
public void SimpleLinearModel()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
IntVar v3 = model.NewIntVar(-100000, 100000, "v3");
|
||||
model.AddLinearConstraint(v1 + v2, -1000000, 100000);
|
||||
model.AddLinearConstraint(v1 + 2 * v2 - v3, 0, 100000);
|
||||
model.Maximize(v3);
|
||||
Assert.Equal(v1.Domain.FlattenedIntervals(), new long[] { -10, 10 });
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(30, response.ObjectiveValue);
|
||||
Assert.Equal(new long[] { 10, 10, 30 }, response.Solution);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleLinearModel2()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
model.AddLinearConstraint(v1 + v2, -1000000, 100000);
|
||||
model.Maximize(v1 - 2 * v2);
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(30, response.ObjectiveValue);
|
||||
Assert.Equal(new long[] { 10, -10 }, response.Solution);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleLinearModel3()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
model.Add(-100000 <= v1 + 2 * v2 <= 100000);
|
||||
model.Minimize(v1 - 2 * v2);
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(-10, solver.Value(v1));
|
||||
Assert.Equal(10, solver.Value(v2));
|
||||
Assert.Equal(new long[] { -10, 10 }, response.Solution);
|
||||
Assert.Equal(-30, solver.Value(v1 - 2 * v2));
|
||||
Assert.Equal(-30, response.ObjectiveValue);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NegativeIntVar()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar boolvar = model.NewBoolVar("boolvar");
|
||||
IntVar x = model.NewIntVar(0, 10, "x");
|
||||
IntVar delta = model.NewIntVar(-5, 5, "delta");
|
||||
IntVar squaredDelta = model.NewIntVar(0, 25, "squaredDelta");
|
||||
model.Add(x == boolvar * 4);
|
||||
model.Add(delta == x - 5);
|
||||
model.AddMultiplicationEquality(squaredDelta, new IntVar[] { delta, delta });
|
||||
model.Minimize(squaredDelta);
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
CpSolverResponse response = solver.Response;
|
||||
Console.WriteLine("response = " + response.ToString());
|
||||
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
Assert.Equal(1, solver.Value(boolvar));
|
||||
Assert.Equal(4, solver.Value(x));
|
||||
Assert.Equal(-1, solver.Value(delta));
|
||||
Assert.Equal(1, solver.Value(squaredDelta));
|
||||
Assert.Equal(new long[] { 1, 4, -1, 1 }, response.Solution);
|
||||
Assert.Equal(1.0, response.ObjectiveValue, 5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NegativeSquareVar()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
BoolVar boolvar = model.NewBoolVar("boolvar");
|
||||
IntVar x = model.NewIntVar(0, 10, "x");
|
||||
IntVar delta = model.NewIntVar(-5, 5, "delta");
|
||||
IntVar squaredDelta = model.NewIntVar(0, 25, "squaredDelta");
|
||||
model.Add(x == 4).OnlyEnforceIf(boolvar);
|
||||
model.Add(x == 0).OnlyEnforceIf(boolvar.Not());
|
||||
model.Add(delta == x - 5);
|
||||
long[,] tuples = { { -5, 25 }, { -4, 16 }, { -3, 9 }, { -2, 4 }, { -1, 1 }, { 0, 0 },
|
||||
{ 1, 1 }, { 2, 4 }, { 3, 9 }, { 4, 16 }, { 5, 25 } };
|
||||
model.AddAllowedAssignments(new IntVar[] { delta, squaredDelta }, tuples);
|
||||
model.Minimize(squaredDelta);
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(1, solver.Value(boolvar));
|
||||
Assert.Equal(4, solver.Value(x));
|
||||
Assert.Equal(-1, solver.Value(delta));
|
||||
Assert.Equal(1, solver.Value(squaredDelta));
|
||||
Assert.Equal(new long[] { 1, 4, -1, 1 }, response.Solution);
|
||||
Assert.Equal(1.0, response.ObjectiveValue, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Division()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(0, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(1, 10, "v2");
|
||||
model.AddDivisionEquality(3, v1, v2);
|
||||
// Console.WriteLine(model.Model);
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(3, solver.Value(v1));
|
||||
Assert.Equal(1, solver.Value(v2));
|
||||
Assert.Equal(new long[] { 3, 1 }, response.Solution);
|
||||
Assert.Equal(0, response.ObjectiveValue);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Modulo()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(1, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(1, 10, "v2");
|
||||
model.AddModuloEquality(3, v1, v2);
|
||||
// Console.WriteLine(model.Model);
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(3, solver.Value(v1));
|
||||
Assert.Equal(4, solver.Value(v2));
|
||||
Assert.Equal(new long[] { 3, 4 }, response.Solution);
|
||||
Assert.Equal(0, response.ObjectiveValue);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeWeightedSumLong()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
List<long> coeffs = new List<long>();
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
IntegerVariableProto var = new IntegerVariableProto();
|
||||
var.Domain.Add(lb);
|
||||
var.Domain.Add(ub);
|
||||
return var;
|
||||
vars.Add(model.NewBoolVar(""));
|
||||
coeffs.Add(i + 1);
|
||||
}
|
||||
|
||||
static ConstraintProto NewLinear2(int v1, int v2, long c1, long c2, long lb, long ub)
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize(LinearExpr.WeightedSum(vars, coeffs));
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Long: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeWeightedSumInt()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
List<int> coeffs = new List<int>();
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
LinearConstraintProto linear = new LinearConstraintProto();
|
||||
linear.Vars.Add(v1);
|
||||
linear.Vars.Add(v2);
|
||||
linear.Coeffs.Add(c1);
|
||||
linear.Coeffs.Add(c2);
|
||||
linear.Domain.Add(lb);
|
||||
linear.Domain.Add(ub);
|
||||
ConstraintProto ct = new ConstraintProto();
|
||||
ct.Linear = linear;
|
||||
return ct;
|
||||
vars.Add(model.NewBoolVar(""));
|
||||
coeffs.Add(i);
|
||||
}
|
||||
|
||||
static ConstraintProto NewLinear3(int v1, int v2, int v3, long c1, long c2, long c3, long lb, long ub)
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize(LinearExpr.WeightedSum(vars, coeffs));
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Int: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeWeightedSumExpr()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<LinearExpr> exprs = new List<LinearExpr>();
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
LinearConstraintProto linear = new LinearConstraintProto();
|
||||
linear.Vars.Add(v1);
|
||||
linear.Vars.Add(v2);
|
||||
linear.Vars.Add(v3);
|
||||
linear.Coeffs.Add(c1);
|
||||
linear.Coeffs.Add(c2);
|
||||
linear.Coeffs.Add(c3);
|
||||
linear.Domain.Add(lb);
|
||||
linear.Domain.Add(ub);
|
||||
ConstraintProto ct = new ConstraintProto();
|
||||
ct.Linear = linear;
|
||||
return ct;
|
||||
exprs.Add(model.NewBoolVar("") * i);
|
||||
}
|
||||
|
||||
static CpObjectiveProto NewMinimize1(int v1, long c1)
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize(LinearExpr.Sum(exprs));
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Exprs: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeWeightedSumBuilder()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
List<long> coeffs = new List<long>();
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
CpObjectiveProto obj = new CpObjectiveProto();
|
||||
obj.Vars.Add(v1);
|
||||
obj.Coeffs.Add(c1);
|
||||
return obj;
|
||||
vars.Add(model.NewBoolVar(""));
|
||||
coeffs.Add(i + 1);
|
||||
}
|
||||
|
||||
static CpObjectiveProto NewMaximize1(int v1, long c1)
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
LinearExprBuilder obj = LinearExpr.NewBuilder();
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
CpObjectiveProto obj = new CpObjectiveProto();
|
||||
obj.Vars.Add(-v1 - 1);
|
||||
obj.Coeffs.Add(c1);
|
||||
obj.ScalingFactor = -1;
|
||||
return obj;
|
||||
obj.AddTerm(vars[i], coeffs[i]);
|
||||
}
|
||||
model.Minimize(obj);
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Proto: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
static CpObjectiveProto NewMaximize2(int v1, int v2, long c1, long c2)
|
||||
{
|
||||
CpObjectiveProto obj = new CpObjectiveProto();
|
||||
obj.Vars.Add(-v1 - 1);
|
||||
obj.Vars.Add(-v2 - 1);
|
||||
obj.Coeffs.Add(c1);
|
||||
obj.Coeffs.Add(c2);
|
||||
obj.ScalingFactor = -1;
|
||||
return obj;
|
||||
}
|
||||
[Fact]
|
||||
public void LinearExprStaticCompileTest()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
BoolVar b1 = model.NewBoolVar("b1");
|
||||
BoolVar b2 = model.NewBoolVar("b2");
|
||||
long[] c1 = new long[] { 2L, 4L };
|
||||
int[] c2 = new int[] { 2, 4 };
|
||||
LinearExpr e1 = LinearExpr.Sum(new IntVar[] { v1, v2 });
|
||||
Console.WriteLine(e1.ToString());
|
||||
LinearExpr e2 = LinearExpr.Sum(new ILiteral[] { b1, b2 });
|
||||
Console.WriteLine(e2.ToString());
|
||||
LinearExpr e3 = LinearExpr.Sum(new BoolVar[] { b1, b2 });
|
||||
Console.WriteLine(e3.ToString());
|
||||
LinearExpr e4 = LinearExpr.WeightedSum(new IntVar[] { v1, v2 }, c1);
|
||||
Console.WriteLine(e4.ToString());
|
||||
LinearExpr e5 = LinearExpr.WeightedSum(new ILiteral[] { b1, b2 }, c1);
|
||||
Console.WriteLine(e5.ToString());
|
||||
LinearExpr e6 = LinearExpr.WeightedSum(new BoolVar[] { b1, b2 }, c1);
|
||||
Console.WriteLine(e6.ToString());
|
||||
LinearExpr e7 = LinearExpr.WeightedSum(new IntVar[] { v1, v2 }, c2);
|
||||
Console.WriteLine(e7.ToString());
|
||||
LinearExpr e8 = LinearExpr.WeightedSum(new ILiteral[] { b1, b2 }, c2);
|
||||
Console.WriteLine(e8.ToString());
|
||||
LinearExpr e9 = LinearExpr.WeightedSum(new BoolVar[] { b1, b2 }, c2);
|
||||
Console.WriteLine(e9.ToString());
|
||||
}
|
||||
|
||||
// CpModelProto
|
||||
[Fact]
|
||||
public void SimpleLinearModelProto()
|
||||
{
|
||||
CpModelProto model = new CpModelProto();
|
||||
model.Variables.Add(NewIntegerVariable(-10, 10));
|
||||
model.Variables.Add(NewIntegerVariable(-10, 10));
|
||||
model.Variables.Add(NewIntegerVariable(-1000000, 1000000));
|
||||
model.Constraints.Add(NewLinear2(0, 1, 1, 1, -1000000, 100000));
|
||||
model.Constraints.Add(NewLinear3(0, 1, 2, 1, 2, -1, 0, 100000));
|
||||
model.Objective = NewMaximize1(2, 1);
|
||||
// Console.WriteLine("model = " + model.ToString());
|
||||
SolveWrapper solve_wrapper = new SolveWrapper();
|
||||
CpSolverResponse response = solve_wrapper.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, response.Status);
|
||||
Assert.Equal(30, response.ObjectiveValue);
|
||||
Assert.Equal(new long[] { 10, 10, 30 }, response.Solution);
|
||||
// Console.WriteLine("response = " + response.ToString());
|
||||
}
|
||||
[Fact]
|
||||
public void LinearExprBuilderCompileTest()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
BoolVar b1 = model.NewBoolVar("b1");
|
||||
BoolVar b2 = model.NewBoolVar("b2");
|
||||
long[] c1 = new long[] { 2L, 4L };
|
||||
int[] c2 = new int[] { 2, 4 };
|
||||
LinearExpr e1 = LinearExpr.NewBuilder().AddSum(new IntVar[] { v1, v2 });
|
||||
Console.WriteLine(e1.ToString());
|
||||
LinearExpr e2 = LinearExpr.NewBuilder().AddSum(new ILiteral[] { b1, b2 });
|
||||
Console.WriteLine(e2.ToString());
|
||||
LinearExpr e3 = LinearExpr.NewBuilder().AddSum(new BoolVar[] { b1, b2 });
|
||||
Console.WriteLine(e3.ToString());
|
||||
LinearExpr e4 = LinearExpr.NewBuilder().AddWeightedSum(new IntVar[] { v1, v2 }, c1);
|
||||
Console.WriteLine(e4.ToString());
|
||||
LinearExpr e5 = LinearExpr.NewBuilder().AddWeightedSum(new ILiteral[] { b1, b2 }, c1);
|
||||
Console.WriteLine(e5.ToString());
|
||||
LinearExpr e6 = LinearExpr.NewBuilder().AddWeightedSum(new BoolVar[] { b1, b2 }, c1);
|
||||
Console.WriteLine(e6.ToString());
|
||||
LinearExpr e7 = LinearExpr.NewBuilder().AddWeightedSum(new IntVar[] { v1, v2 }, c2);
|
||||
Console.WriteLine(e7.ToString());
|
||||
LinearExpr e8 = LinearExpr.NewBuilder().AddWeightedSum(new ILiteral[] { b1, b2 }, c2);
|
||||
Console.WriteLine(e8.ToString());
|
||||
LinearExpr e9 = LinearExpr.NewBuilder().AddWeightedSum(new BoolVar[] { b1, b2 }, c2);
|
||||
Console.WriteLine(e9.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleLinearModelProto2()
|
||||
{
|
||||
CpModelProto model = new CpModelProto();
|
||||
model.Variables.Add(NewIntegerVariable(-10, 10));
|
||||
model.Variables.Add(NewIntegerVariable(-10, 10));
|
||||
model.Constraints.Add(NewLinear2(0, 1, 1, 1, -1000000, 100000));
|
||||
model.Objective = NewMaximize2(0, 1, 1, -2);
|
||||
// Console.WriteLine("model = " + model.ToString());
|
||||
[Fact]
|
||||
public void ExportModel()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
model.Add(-100000 <= v1 + 2 * v2 <= 100000);
|
||||
model.Minimize(v1 - 2 * v2);
|
||||
Assert.True(model.ExportToFile("test_model_dotnet.pbtxt"));
|
||||
Console.WriteLine("Model written to file");
|
||||
}
|
||||
|
||||
SolveWrapper solve_wrapper = new SolveWrapper();
|
||||
CpSolverResponse response = solve_wrapper.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, response.Status);
|
||||
Assert.Equal(30, response.ObjectiveValue);
|
||||
Assert.Equal(new long[] { 10, -10 }, response.Solution);
|
||||
// Console.WriteLine("response = " + response.ToString());
|
||||
}
|
||||
|
||||
// CpModel
|
||||
[Fact]
|
||||
public void SimpleLinearModel()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
IntVar v3 = model.NewIntVar(-100000, 100000, "v3");
|
||||
model.AddLinearConstraint(v1 + v2, -1000000, 100000);
|
||||
model.AddLinearConstraint(v1 + 2 * v2 - v3, 0, 100000);
|
||||
model.Maximize(v3);
|
||||
Assert.Equal(v1.Domain.FlattenedIntervals(), new long[] { -10, 10 });
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(30, response.ObjectiveValue);
|
||||
Assert.Equal(new long[] { 10, 10, 30 }, response.Solution);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleLinearModel2()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
model.AddLinearConstraint(v1 + v2, -1000000, 100000);
|
||||
model.Maximize(v1 - 2 * v2);
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(30, response.ObjectiveValue);
|
||||
Assert.Equal(new long[] { 10, -10 }, response.Solution);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleLinearModel3()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
model.Add(-100000 <= v1 + 2 * v2 <= 100000);
|
||||
model.Minimize(v1 - 2 * v2);
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(-10, solver.Value(v1));
|
||||
Assert.Equal(10, solver.Value(v2));
|
||||
Assert.Equal(new long[] { -10, 10 }, response.Solution);
|
||||
Assert.Equal(-30, solver.Value(v1 - 2 * v2));
|
||||
Assert.Equal(-30, response.ObjectiveValue);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NegativeIntVar()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar boolvar = model.NewBoolVar("boolvar");
|
||||
IntVar x = model.NewIntVar(0, 10, "x");
|
||||
IntVar delta = model.NewIntVar(-5, 5, "delta");
|
||||
IntVar squaredDelta = model.NewIntVar(0, 25, "squaredDelta");
|
||||
model.Add(x == boolvar * 4);
|
||||
model.Add(delta == x - 5);
|
||||
model.AddMultiplicationEquality(squaredDelta, new IntVar[] { delta, delta });
|
||||
model.Minimize(squaredDelta);
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
CpSolverResponse response = solver.Response;
|
||||
Console.WriteLine("response = " + response.ToString());
|
||||
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
Assert.Equal(1, solver.Value(boolvar));
|
||||
Assert.Equal(4, solver.Value(x));
|
||||
Assert.Equal(-1, solver.Value(delta));
|
||||
Assert.Equal(1, solver.Value(squaredDelta));
|
||||
Assert.Equal(new long[] { 1, 4, -1, 1 }, response.Solution);
|
||||
Assert.Equal(1.0, response.ObjectiveValue, 5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NegativeSquareVar()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar boolvar = model.NewBoolVar("boolvar");
|
||||
IntVar x = model.NewIntVar(0, 10, "x");
|
||||
IntVar delta = model.NewIntVar(-5, 5, "delta");
|
||||
IntVar squaredDelta = model.NewIntVar(0, 25, "squaredDelta");
|
||||
model.Add(x == 4).OnlyEnforceIf(boolvar);
|
||||
model.Add(x == 0).OnlyEnforceIf(boolvar.Not());
|
||||
model.Add(delta == x - 5);
|
||||
long[,] tuples = { { -5, 25 }, { -4, 16 }, { -3, 9 }, { -2, 4 }, { -1, 1 }, { 0, 0 },
|
||||
{ 1, 1 }, { 2, 4 }, { 3, 9 }, { 4, 16 }, { 5, 25 } };
|
||||
model.AddAllowedAssignments(new IntVar[] { delta, squaredDelta }, tuples);
|
||||
model.Minimize(squaredDelta);
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(1, solver.Value(boolvar));
|
||||
Assert.Equal(4, solver.Value(x));
|
||||
Assert.Equal(-1, solver.Value(delta));
|
||||
Assert.Equal(1, solver.Value(squaredDelta));
|
||||
Assert.Equal(new long[] { 1, 4, -1, 1 }, response.Solution);
|
||||
Assert.Equal(1.0, response.ObjectiveValue, 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Division()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(0, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(1, 10, "v2");
|
||||
model.AddDivisionEquality(3, v1, v2);
|
||||
// Console.WriteLine(model.Model);
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(3, solver.Value(v1));
|
||||
Assert.Equal(1, solver.Value(v2));
|
||||
Assert.Equal(new long[] { 3, 1 }, response.Solution);
|
||||
Assert.Equal(0, response.ObjectiveValue);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Modulo()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(1, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(1, 10, "v2");
|
||||
model.AddModuloEquality(3, v1, v2);
|
||||
// Console.WriteLine(model.Model);
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
CpSolverStatus status = solver.Solve(model);
|
||||
Assert.Equal(CpSolverStatus.Optimal, status);
|
||||
|
||||
CpSolverResponse response = solver.Response;
|
||||
Assert.Equal(3, solver.Value(v1));
|
||||
Assert.Equal(4, solver.Value(v2));
|
||||
Assert.Equal(new long[] { 3, 4 }, response.Solution);
|
||||
Assert.Equal(0, response.ObjectiveValue);
|
||||
// Console.WriteLine("response = " + reponse.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeWeightedSumLong()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
List<long> coeffs = new List<long>();
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
vars.Add(model.NewBoolVar(""));
|
||||
coeffs.Add(i + 1);
|
||||
}
|
||||
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize(LinearExpr.WeightedSum(vars, coeffs));
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Long: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeWeightedSumInt()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
List<int> coeffs = new List<int>();
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
vars.Add(model.NewBoolVar(""));
|
||||
coeffs.Add(i);
|
||||
}
|
||||
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize(LinearExpr.WeightedSum(vars, coeffs));
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Int: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeWeightedSumExpr()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<LinearExpr> exprs = new List<LinearExpr>();
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
exprs.Add(model.NewBoolVar("") * i);
|
||||
}
|
||||
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize(LinearExpr.Sum(exprs));
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Exprs: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LargeWeightedSumProto()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
List<long> coeffs = new List<long>();
|
||||
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
vars.Add(model.NewBoolVar(""));
|
||||
coeffs.Add(i + 1);
|
||||
}
|
||||
|
||||
var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
model.Minimize();
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
{
|
||||
model.AddTermToObjective(vars[i], coeffs[i]);
|
||||
}
|
||||
watch.Stop();
|
||||
var elapsedMs = watch.ElapsedMilliseconds;
|
||||
Console.WriteLine($"Proto: Elapsed time {elapsedMs}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExportModel()
|
||||
{
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
model.Add(-100000 <= v1 + 2 * v2 <= 100000);
|
||||
model.Minimize(v1 - 2 * v2);
|
||||
Assert.True(model.ExportToFile("test_model_dotnet.pbtxt"));
|
||||
Console.WriteLine("Model written to file");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SolveFromString()
|
||||
{
|
||||
string model_str = @"
|
||||
[Fact]
|
||||
public void SolveFromString()
|
||||
{
|
||||
string model_str = @"
|
||||
{
|
||||
""variables"": [
|
||||
{ ""name"": ""C"", ""domain"": [ ""1"", ""9"" ] },
|
||||
@@ -416,45 +477,45 @@ namespace Google.OrTools.Tests
|
||||
{ ""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"" ] } }
|
||||
]
|
||||
}";
|
||||
CpModelProto model = Google.Protobuf.JsonParser.Default.Parse<CpModelProto>(model_str);
|
||||
SolveWrapper solve_wrapper = new SolveWrapper();
|
||||
CpSolverResponse response = solve_wrapper.Solve(model);
|
||||
Console.WriteLine(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CaptureLog()
|
||||
{
|
||||
Console.WriteLine("CaptureLog test");
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
IntVar v3 = model.NewIntVar(-100000, 100000, "v3");
|
||||
model.AddLinearConstraint(v1 + v2, -1000000, 100000);
|
||||
model.AddLinearConstraint(v1 + 2 * v2 - v3, 0, 100000);
|
||||
model.Maximize(v3);
|
||||
Assert.Equal(v1.Domain.FlattenedIntervals(), new long[] { -10, 10 });
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
solver.StringParameters = "log_search_progress:true log_to_stdout:false";
|
||||
string log = "";
|
||||
solver.SetLogCallback(message => log += message + "\n");
|
||||
solver.Solve(model);
|
||||
Assert.NotEmpty(log);
|
||||
Assert.Contains("OPTIMAL", log);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestInterval()
|
||||
{
|
||||
Console.WriteLine("TestInterval test");
|
||||
CpModel model = new CpModel();
|
||||
IntVar v = model.NewIntVar(-10, 10, "v");
|
||||
IntervalVar i = model.NewFixedSizeIntervalVar(v, 3, "i");
|
||||
Assert.Equal("v", i.StartExpr().ShortString());
|
||||
Assert.Equal("3", i.SizeExpr().ShortString());
|
||||
Assert.Equal("(v + 3)", i.EndExpr().ShortString());
|
||||
}
|
||||
CpModelProto model = Google.Protobuf.JsonParser.Default.Parse<CpModelProto>(model_str);
|
||||
SolveWrapper solve_wrapper = new SolveWrapper();
|
||||
CpSolverResponse response = solve_wrapper.Solve(model);
|
||||
Console.WriteLine(response);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CaptureLog()
|
||||
{
|
||||
Console.WriteLine("CaptureLog test");
|
||||
CpModel model = new CpModel();
|
||||
IntVar v1 = model.NewIntVar(-10, 10, "v1");
|
||||
IntVar v2 = model.NewIntVar(-10, 10, "v2");
|
||||
IntVar v3 = model.NewIntVar(-100000, 100000, "v3");
|
||||
model.AddLinearConstraint(v1 + v2, -1000000, 100000);
|
||||
model.AddLinearConstraint(v1 + 2 * v2 - v3, 0, 100000);
|
||||
model.Maximize(v3);
|
||||
Assert.Equal(v1.Domain.FlattenedIntervals(), new long[] { -10, 10 });
|
||||
// Console.WriteLine("model = " + model.Model.ToString());
|
||||
|
||||
CpSolver solver = new CpSolver();
|
||||
solver.StringParameters = "log_search_progress:true log_to_stdout:false";
|
||||
string log = "";
|
||||
solver.SetLogCallback(message => log += message + "\n");
|
||||
solver.Solve(model);
|
||||
Assert.NotEmpty(log);
|
||||
Assert.Contains("OPTIMAL", log);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestInterval()
|
||||
{
|
||||
Console.WriteLine("TestInterval test");
|
||||
CpModel model = new CpModel();
|
||||
IntVar v = model.NewIntVar(-10, 10, "v");
|
||||
IntervalVar i = model.NewFixedSizeIntervalVar(v, 3, "i");
|
||||
Assert.Equal("v", i.StartExpr().ToString());
|
||||
Assert.Equal("3", i.SizeExpr().ToString());
|
||||
Assert.Equal("v + 3", i.EndExpr().ToString());
|
||||
}
|
||||
}
|
||||
} // namespace Google.OrTools.Tests
|
||||
|
||||
@@ -18,39 +18,39 @@ using Google.OrTools.ConstraintSolver;
|
||||
|
||||
namespace Google.OrTools.Tests
|
||||
{
|
||||
public class Issue18Test
|
||||
public class Issue18Test
|
||||
{
|
||||
[Fact]
|
||||
public void NewSearchTest()
|
||||
{
|
||||
[Fact]
|
||||
public void NewSearchTest()
|
||||
Solver solver = new Google.OrTools.ConstraintSolver.Solver("p");
|
||||
|
||||
// creating dummy variables
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
for (int i = 0; i < 100000; i++)
|
||||
{
|
||||
Solver solver = new Google.OrTools.ConstraintSolver.Solver("p");
|
||||
|
||||
// creating dummy variables
|
||||
List<IntVar> vars = new List<IntVar>();
|
||||
for (int i = 0; i < 100000; i++)
|
||||
{
|
||||
vars.Add(solver.MakeIntVar(0, 1));
|
||||
}
|
||||
|
||||
IntExpr globalSum = solver.MakeSum(vars.ToArray());
|
||||
|
||||
DecisionBuilder db = solver.MakePhase(vars.ToArray(), Google.OrTools.ConstraintSolver.Solver.INT_VAR_SIMPLE,
|
||||
Google.OrTools.ConstraintSolver.Solver.INT_VALUE_SIMPLE);
|
||||
|
||||
solver.NewSearch(db, new OptimizeVar(solver, true, globalSum.Var(), 100));
|
||||
|
||||
// force Garbage Collector
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
|
||||
// Try to read all solutions
|
||||
int count = 0;
|
||||
while (solver.NextSolution())
|
||||
{
|
||||
count++;
|
||||
// Console.WriteLine("solution " + globalSum.Var().Value());
|
||||
}
|
||||
Console.WriteLine("Solutions: " + count);
|
||||
vars.Add(solver.MakeIntVar(0, 1));
|
||||
}
|
||||
|
||||
IntExpr globalSum = solver.MakeSum(vars.ToArray());
|
||||
|
||||
DecisionBuilder db = solver.MakePhase(vars.ToArray(), Google.OrTools.ConstraintSolver.Solver.INT_VAR_SIMPLE,
|
||||
Google.OrTools.ConstraintSolver.Solver.INT_VALUE_SIMPLE);
|
||||
|
||||
solver.NewSearch(db, new OptimizeVar(solver, true, globalSum.Var(), 100));
|
||||
|
||||
// force Garbage Collector
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
|
||||
// Try to read all solutions
|
||||
int count = 0;
|
||||
while (solver.NextSolution())
|
||||
{
|
||||
count++;
|
||||
// Console.WriteLine("solution " + globalSum.Var().Value());
|
||||
}
|
||||
Console.WriteLine("Solutions: " + count);
|
||||
}
|
||||
}
|
||||
} // namespace Google.OrTools.Tests
|
||||
|
||||
@@ -21,64 +21,64 @@ using Google.OrTools.ConstraintSolver;
|
||||
|
||||
namespace Google.OrTools.Tests
|
||||
{
|
||||
public class Issue22Test
|
||||
public class Issue22Test
|
||||
{
|
||||
private long Solve(long num_buses_check = 0)
|
||||
{
|
||||
private long Solve(long num_buses_check = 0)
|
||||
ConstraintSolverParameters sPrm = Solver.DefaultSolverParameters();
|
||||
sPrm.CompressTrail = 0;
|
||||
Solver solver = new Solver("OrTools", sPrm);
|
||||
|
||||
// this works
|
||||
// IntVar[,] x = solver.MakeIntVarMatrix(2,2, new int[] {-2,0,1,2}, "x");
|
||||
|
||||
// this doesn't work
|
||||
IntVar[,] x = solver.MakeIntVarMatrix(2, 2, new int[] { 0, 1, 2 }, "x");
|
||||
|
||||
for (int w = 0; w < 2; w++)
|
||||
{
|
||||
ConstraintSolverParameters sPrm = Solver.DefaultSolverParameters();
|
||||
sPrm.CompressTrail = 0;
|
||||
Solver solver = new Solver("OrTools", sPrm);
|
||||
|
||||
// this works
|
||||
// IntVar[,] x = solver.MakeIntVarMatrix(2,2, new int[] {-2,0,1,2}, "x");
|
||||
|
||||
// this doesn't work
|
||||
IntVar[,] x = solver.MakeIntVarMatrix(2, 2, new int[] { 0, 1, 2 }, "x");
|
||||
|
||||
for (int w = 0; w < 2; w++)
|
||||
IntVar[] b = new IntVar[2];
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
IntVar[] b = new IntVar[2];
|
||||
b[i] = solver.MakeIsEqualCstVar(x[w, i], 0);
|
||||
}
|
||||
solver.Add(solver.MakeSumGreaterOrEqual(b, 2));
|
||||
}
|
||||
|
||||
IntVar[] x_flat = x.Flatten();
|
||||
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
|
||||
solver.NewSearch(db);
|
||||
while (solver.NextSolution())
|
||||
{
|
||||
Console.WriteLine("x: ");
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
Console.Write("worker" + (j + 1).ToString() + ":");
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
b[i] = solver.MakeIsEqualCstVar(x[w, i], 0);
|
||||
Console.Write(" {0,2} ", x[j, i].Value());
|
||||
}
|
||||
solver.Add(solver.MakeSumGreaterOrEqual(b, 2));
|
||||
Console.Write("\n");
|
||||
}
|
||||
|
||||
IntVar[] x_flat = x.Flatten();
|
||||
DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
|
||||
solver.NewSearch(db);
|
||||
while (solver.NextSolution())
|
||||
{
|
||||
Console.WriteLine("x: ");
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
Console.Write("worker" + (j + 1).ToString() + ":");
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Console.Write(" {0,2} ", x[j, i].Value());
|
||||
}
|
||||
Console.Write("\n");
|
||||
}
|
||||
Console.WriteLine("End at---->" + DateTime.Now);
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
solver.EndSearch();
|
||||
return 1;
|
||||
Console.WriteLine("End at---->" + DateTime.Now);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InitialPropagateTest()
|
||||
{
|
||||
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);
|
||||
}
|
||||
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());
|
||||
|
||||
solver.EndSearch();
|
||||
return 1;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InitialPropagateTest()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
} // namespace Google.OrTools.Tests
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,7 +53,7 @@ public class LinearExpr
|
||||
public static LinearExpr Sum(IEnumerable<BoolVar> vars)
|
||||
{
|
||||
return NewBuilder().AddSum(vars);
|
||||
}
|
||||
}
|
||||
|
||||
public static LinearExpr WeightedSum(IEnumerable<LinearExpr> exprs, IEnumerable<int> coeffs)
|
||||
{
|
||||
@@ -73,7 +73,7 @@ public class LinearExpr
|
||||
public static LinearExpr WeightedSum(IEnumerable<ILiteral> literals, IEnumerable<long> coeffs)
|
||||
{
|
||||
return NewBuilder().AddWeightedSum(literals, coeffs);
|
||||
}
|
||||
}
|
||||
|
||||
public static LinearExpr WeightedSum(IEnumerable<BoolVar> vars, IEnumerable<int> coeffs)
|
||||
{
|
||||
@@ -83,29 +83,29 @@ public class LinearExpr
|
||||
public static LinearExpr WeightedSum(IEnumerable<BoolVar> vars, IEnumerable<long> coeffs)
|
||||
{
|
||||
return NewBuilder().AddWeightedSum(vars, coeffs);
|
||||
}
|
||||
}
|
||||
|
||||
public static LinearExpr Term(LinearExpr expr, long coeff)
|
||||
{
|
||||
return Prod(expr, coeff);
|
||||
}
|
||||
|
||||
public static LinearExpr Term(ILiteral literal, long coeff)
|
||||
public static LinearExpr Term(ILiteral literal, long coeff)
|
||||
{
|
||||
if (literal is BoolVar)
|
||||
if (literal is BoolVar)
|
||||
{
|
||||
return Prod((IntVar) literal, coeff);
|
||||
return Prod((IntVar)literal, coeff);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Affine((BoolVar) literal.Not(), -coeff, coeff);
|
||||
return Affine((BoolVar)literal.Not(), -coeff, coeff);
|
||||
}
|
||||
}
|
||||
|
||||
public static LinearExpr Term(BoolVar var, long coeff)
|
||||
public static LinearExpr Term(BoolVar var, long coeff)
|
||||
{
|
||||
return Prod(var, coeff);
|
||||
}
|
||||
}
|
||||
|
||||
public static LinearExpr Affine(LinearExpr expr, long coeff, long offset)
|
||||
{
|
||||
@@ -445,14 +445,14 @@ public class LinearExprBuilder : LinearExpr
|
||||
return this;
|
||||
}
|
||||
|
||||
public LinearExprBuilder AddSum(IEnumerable<BoolVar> vars)
|
||||
public LinearExprBuilder AddSum(IEnumerable<BoolVar> vars)
|
||||
{
|
||||
foreach (BoolVar var in vars)
|
||||
{
|
||||
AddTerm(var, 1);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
public LinearExprBuilder AddWeightedSum(IEnumerable<LinearExpr> exprs, IEnumerable<long> coefficients)
|
||||
{
|
||||
foreach (var p in exprs.Zip(coefficients, (e, c) => new { Expr = e, Coeff = c }))
|
||||
@@ -506,7 +506,7 @@ public class LinearExprBuilder : LinearExpr
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = "";
|
||||
|
||||
Reference in New Issue
Block a user