private void Pack(Solver cp, IntVar[] binvars, int[] weights, IntVar[] loadvars) { IntVar[] b = new IntVar[binvars.Length]; for(long j=0; j<loadvars.Length; j++) { for (int i = 0; i < binvars.Length; i++) { b[i] = cp.MakeIsEqualCstVar(binvars[i], j); } cp.Add(cp.MakeScalProd(b, weights) == loadvars[j]); } cp.Add(cp.MakeSumEquality(loadvars, cp.MakeIntVar(weights.Sum(), weights.Sum(), "Sum"))); }
internal SolverContext Constrain(Func <Solver, Constraint> constrain) { var c = constrain(Solver); Solver.Add(c); Constraints.Add(c); Clr.Add(c); return(this); }
public void VerifyModelOnlySerializesToFile() { const string path = "AnotherSimpleTest.dat"; const string modelName = "TestModelLoader"; { using (var s = new Solver(modelName)) { var x = s.MakeIntVar(0, 10, "x"); var y = s.MakeIntVar(0, 10, "y"); var c = x + y == 5; //c.Cst.SetName("equation"); s.Add(c); Assert.That(s.ConstraintCount(), Is.EqualTo(1)); var model = s.ExportModel(); using (var stream = File.Open(path, Create)) { model.WriteTo(stream); } } } { var model = new CpModel(); using (var s = new Solver(modelName)) { using (var stream = File.Open(path, Open)) { model.MergeFrom(stream); } s.LoadModel(model); var loader = s.ModelLoader(); Assert.That(loader, Is.Not.Null); var x = loader.IntegerExpressionByName("x").Var(); var y = loader.IntegerExpressionByName("y").Var(); // Just check that all things are equivalent. var c = x + y == 5; Assert.That(c.Cst.ToString(), Is.Not.EqualTo("TrueConstraint()")); // Constraints should reflect what was actually there. Assert.That(s.ConstraintCount(), Is.EqualTo(1)); } } }
public void VerifyThatInMemoryExportToProtoAfterSolutionFoundWorks() { CpModel model; // Model name must be the same because loading does not re-set it. const string modelName = "TestModelLoader"; string modelText; using (var s = new Solver(modelName)) { var x = s.MakeIntVar(0, 10, "x"); var y = s.MakeIntVar(0, 10, "y"); s.Add(x + y == 5); // Verify that adding one Constraint appears in the Count. Assert.That(s.ConstraintCount(), Is.EqualTo(1)); var db = s.MakePhase(x, y, ChooseFirstUnbound, AssignMinValue); { // TODO: TBD: consider adding a disposable search wrapper to hide that detail a bit... // Ending the new search after next solution block is CRITICAL. s.NewSearch(db); while (s.NextSolution()) { Console.WriteLine($"Found next solution: {x.ToString()} + {y.ToString()} == 5"); break; } s.EndSearch(); } // Capture the ExportedModel textual (JSON) representation. model = s.ExportModel(); Assert.That(model, Is.Not.Null); modelText = VerifyJsonText(model.ToString()); } using (var s = new Solver(modelName)) { Assert.That(s.LoadModel(model), Is.True); // Straight after load the Constraints should report the same number. Assert.That(s.ConstraintCount(), Is.EqualTo(1)); // The textual representation must be the same. var actual = s.ExportModel(); var actualText = VerifyJsonText(actual.ToString()); Assert.That(actualText, Is.EqualTo(modelText)); } }
public void VerifyThatInMemoryExportToProtoWorks() { CpModel model; // Model name must be the same because loading does not re-set it. const string modelName = "TestModelLoader"; string modelText; using (var s = new Solver(modelName)) { var x = s.MakeIntVar(0, 10, "x"); var y = s.MakeIntVar(0, 10, "y"); s.Add(x + y == 5); // Verify that adding one Constraint appears in the Count. Assert.That(s.ConstraintCount(), Is.EqualTo(1)); // Capture the ExportedModel textual (JSON) representation. model = s.ExportModel(); Assert.That(model, Is.Not.Null); modelText = VerifyJsonText(model.ToString()); } using (var s = new Solver(modelName)) { Assert.That(s.LoadModel(model), Is.True); // Straight after load the Constraints should report the same number. Assert.That(s.ConstraintCount(), Is.EqualTo(1)); // The textual representation must be the same. var actual = s.ExportModel(); var actualText = VerifyJsonText(actual.ToString()); Assert.That(actualText, Is.EqualTo(modelText)); } }
static void Main(string[] args) { InitTaskList(); int taskCount = GetTaskCount(); Solver solver = new Solver("ResourceConstraintScheduling"); IntervalVar[] tasks = new IntervalVar[taskCount]; IntVar[] taskChoosed = new IntVar[taskCount]; IntVar[] makeSpan = new IntVar[GetEndTaskCount()]; int endJobCounter = 0; foreach (Job j in myJobList) { IntVar[] tmp = new IntVar[j.AlternativeTasks.Count]; int i = 0; foreach (Task t in j.AlternativeTasks) { long ti = taskIndexes[t.Name]; taskChoosed[ti] = solver.MakeIntVar(0, 1, t.Name + "_choose"); tmp[i++] = taskChoosed[ti]; tasks[ti] = solver.MakeFixedDurationIntervalVar( 0, 100000, t.Duration, false, t.Name + "_interval"); if (j.Successor == null) makeSpan[endJobCounter++] = tasks[ti].EndExpr().Var(); if (!tasksToEquipment.ContainsKey(t.Equipment)) tasksToEquipment[t.Equipment] = new List<IntervalVar>(); tasksToEquipment[t.Equipment].Add(tasks[ti]); } solver.Add(IntVarArrayHelper.Sum(tmp) == 1); } List<SequenceVar> all_seq = new List<SequenceVar>(); foreach (KeyValuePair<long, List<IntervalVar>> pair in tasksToEquipment) { DisjunctiveConstraint dc = solver.MakeDisjunctiveConstraint( pair.Value.ToArray(), pair.Key.ToString()); solver.Add(dc); all_seq.Add(dc.SequenceVar()); } IntVar objective_var = solver.MakeMax(makeSpan).Var(); OptimizeVar objective_monitor = solver.MakeMinimize(objective_var, 1); DecisionBuilder sequence_phase = solver.MakePhase(all_seq.ToArray(), Solver.SEQUENCE_DEFAULT); DecisionBuilder objective_phase = solver.MakePhase(objective_var, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); DecisionBuilder main_phase = solver.Compose(sequence_phase, objective_phase); const int kLogFrequency = 1000000; SearchMonitor search_log = solver.MakeSearchLog(kLogFrequency, objective_monitor); SolutionCollector collector = solver.MakeLastSolutionCollector(); collector.Add(all_seq.ToArray()); collector.AddObjective(objective_var); if (solver.Solve(main_phase, search_log, objective_monitor, null, collector)) Console.Out.WriteLine("Optimal solution = " + collector.ObjectiveValue(0)); else Console.Out.WriteLine("No solution."); }
static void Main(string[] args) { Program obj = new Program(); obj.Readfile(@"C:\binpackdata.txt"); obj.nbCourses = obj.credits.Length; Solver solver = new Solver("BinPacking"); IntVar[] x = new IntVar[obj.nbCourses]; IntVar[] loadVars = new IntVar[obj.nbPeriods]; for (int i = 0; i < obj.nbCourses; i++) x[i] = solver.MakeIntVar(0, obj.nbPeriods - 1, "x" + i); for (int i = 0; i < obj.nbPeriods; i++) loadVars[i] = solver.MakeIntVar(0, obj.credits.Sum(), "loadVars" + i); //-------------------post of the constraints-------------- obj.Pack(solver, x, obj.credits, loadVars); foreach (Tuple<int, int> t in obj.prereqTupleArr) solver.Add(x[t.Item1] < x[t.Item2]); //-------------------------Objective--------------------------- IntVar objectiveVar = solver.MakeMax(loadVars).Var(); OptimizeVar objective = solver.MakeMinimize(objectiveVar, 1); //------------start the search and optimization----------- DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.INT_VALUE_DEFAULT); SearchMonitor searchLog = solver.MakeSearchLog(100000, objectiveVar); solver.NewSearch(db, objective, searchLog); while (solver.NextSolution()) { Console.WriteLine(">> Objective: " + objectiveVar.Value()); } solver.EndSearch(); }
public SecretSantaDraw MakeNextDraw(List<Person> people, List<SecretSantaDraw> previousDraws) { //Only adults are included string[] AllNames = GetNamesOfAdults(people); List<Person> AllPeople = GetAdults(people); Solver solver = new Solver("XmasDraw"); int n = AllNames.Count(); IEnumerable<int> RANGE = Enumerable.Range(0, n); // // Decision variables // IntVar[] santas = solver.MakeIntVarArray(n, 0, n - 1, "santas"); // // Constraints // solver.Add(santas.AllDifferent()); foreach (int i in RANGE) { string currentPerson = AllNames[i]; //Can't buy for yourself solver.Add(santas[i] != i); //Can't buy for people in same family group foreach (string familyMember in GetFamilyGroupMembers(currentPerson, AllPeople)) { solver.Add(CantBuyFor(currentPerson, familyMember, AllNames, santas)); } //Constraints based on history foreach (SecretSantaDraw previousDraw in previousDraws) { if (previousDraw.Draw.ContainsKey(currentPerson)) { string previousRecipient = previousDraw.Draw[currentPerson]; //Can't buy for who you previously bought for solver.Add(CantBuyFor(currentPerson, previousRecipient, AllNames, santas)); //Your partner(s) can't buy for previousRecipient foreach (string partner in GetImmediateFamilyMembers(currentPerson, AllPeople)) { solver.Add(CantBuyFor(partner, previousRecipient, AllNames, santas)); } //Can't buy for previousRecipient's partner(s) foreach (string partner in GetImmediateFamilyMembers(previousRecipient, AllPeople)) { solver.Add(CantBuyFor(currentPerson, partner, AllNames, santas)); } } } //Constraints based on potential solutions //TODO - Partners don't buy for other partners } solver.Add(solver.MakeCircuit(santas)); ////Custom constraints //solver.Add(CantBuyFor("Homer", "Fred", AllNames, santas)); //solver.Add(CantBuyFor("Homer", "Peter", AllNames, santas)); //solver.Add(CantBuyFor("Peter", "Homer", AllNames, santas)); //solver.Add(CantBuyFor("Peter", "Fred", AllNames, santas)); //solver.Add(CantBuyFor("Fred", "Homer", AllNames, santas)); //solver.Add(CantBuyFor("Fred", "Peter", AllNames, santas)); // // Search // DecisionBuilder db = solver.MakePhase(santas, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE); solver.NewSearch(db); if (solver.NextSolution()) { Dictionary<string, string> result = new Dictionary<string, string>(); foreach (int i in RANGE) { result[AllNames[i]] = AllNames[santas[i].Value()]; } return new SecretSantaDraw("Result:" + DateTime.Now.Ticks, result); } else { return null; } }
public void SimpleTestWithSearchMonitorsAndDecisionBuilder() { CpModel model; string modelText; const string modelName = "TestModelLoader"; const string equationText = "((x(0..10) + y(0..10)) == 5)"; using (var s = new Solver(modelName)) { var x = s.MakeIntVar(0, 10, "x"); var y = s.MakeIntVar(0, 10, "y"); var c = x + y == 5; Assert.That(c.Cst.ToString(), Is.EqualTo(equationText)); s.Add(c); Assert.That(s.ConstraintCount(), Is.EqualTo(1)); var collector = s.MakeAllSolutionCollector(); var db = s.MakePhase(x, y, ChooseFirstUnbound, AssignMinValue); Console.WriteLine("First search..."); s.NewSearch(db, collector); while (s.NextSolution()) { Console.WriteLine($"{x.ToString()} + {y.ToString()} == 5"); break; } s.EndSearch(); using (var vect = new SearchMonitorVector()) { vect.Add(collector); model = s.ExportModelWithSearchMonitorsAndDecisionBuilder(vect, db); modelText = model.ToString(); } } using (var s = new Solver(modelName)) { // TODO: TBD: load but without any monitors and/or DB ... s.LoadModel(model); var loader = s.ModelLoader(); // Do a quick sanity check that we at least have the proper constraint loaded. Assert.That(s.ConstraintCount(), Is.EqualTo(1)); var x = loader.IntegerExpressionByName("x").Var(); var y = loader.IntegerExpressionByName("y").Var(); { var c = x + y == 5; // These should PASS as well... Assert.That(c.Cst.ToString(), Is.Not.EqualTo("TrueConstraint()")); Assert.That(c.Cst.ToString(), Is.EqualTo(equationText)); } { /* I dare say that THIS should PASS as well, but due to the fact that IntVar and * derivatives are treated as IntExpr, it is FAILING. */ var actual = s.ExportModel(); Assert.That(actual.ToString(), Is.EqualTo(modelText)); } var db = s.MakePhase(x, y, ChooseFirstUnbound, AssignMinValue); Console.WriteLine("Second search..."); s.NewSearch(db); while (s.NextSolution()) { Console.WriteLine($"{x.ToString()} + {y.ToString()} == 5"); } s.EndSearch(); } }