// Copyright 2010-2017 Google // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using Google.OrTools.Sat; public class CsTestCpOperator { // TODO(user): Add proper tests. static int error_count_ = 0; static void Check(bool test, String message) { if (!test) { Console.WriteLine("Error: " + message); error_count_++; } } static void CheckLongEq(long v1, long v2, String message) { if (v1 != v2) { Console.WriteLine("Error: " + v1 + " != " + v2 + " " + message); error_count_++; } } 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; } static void TestSimpleLinearModel() { 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); CpSolverResponse response = SatHelper.Solve(model); Console.WriteLine("model = " + model.ToString()); Console.WriteLine("response = " + response.ToString()); } static void TestSimpleLinearModel2() { 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); CpSolverResponse response = SatHelper.Solve(model); Console.WriteLine("model = " + model.ToString()); Console.WriteLine("response = " + response.ToString()); } static void TestNegativeIntVar() { 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(x == boolvar * 4); model.Add(delta == x - 5 ); model.AddProdEquality(squaredDelta, new IntVar[] {delta, delta}); model.Minimize(squaredDelta); // Creates the solver and solve. CpSolver solver = new CpSolver(); CpSolverStatus status = solver.Solve(model); Console.WriteLine(solver.ResponseStats()); } static void TestNegativeSquareVar() { 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); // Creates the solver and solve. CpSolver solver = new CpSolver(); CpSolverStatus status = solver.Solve(model); Console.WriteLine(solver.ResponseStats()); } static void Main() { TestSimpleLinearModel(); TestSimpleLinearModel2(); TestNegativeIntVar(); TestNegativeSquareVar(); if (error_count_ != 0) { Console.WriteLine("Found " + error_count_ + " errors."); Environment.Exit(1); } } }