/* * Create Optimization Model and Solve Coloring Problem: */ public static void SolveAsOptimizationProblem(int nbNodes, IEnumerable <Tuple <int, int> > edges) { var solver = new Solver("Coloring"); // The colors for each node: IntVar[] nodes = solver.MakeIntVarArray(nbNodes, 0, nbNodes - 1); foreach (var edge in edges) { solver.Add(nodes[edge.Item1] != nodes[edge.Item2]); } // Some Symmetry breaking solver.Add(nodes[0] == 0); // The number of times each color is used: IntVar[] colors = solver.MakeIntVarArray(nbNodes, 0, nbNodes - 1); for (int i = 0; i < colors.Length; i++) { solver.Add(solver.MakeCount(nodes, i, colors[i])); } // Objective function = number of colors used: IntVar obj = solver.MakeSum((from j in colors select(j > 0).Var()).ToArray()).Var(); /* * Start Solver: */ DecisionBuilder db = solver.MakePhase(nodes, Solver.INT_VAR_SIMPLE, Solver.INT_VALUE_SIMPLE); // Remember only the best solution found: SolutionCollector collector = solver.MakeBestValueSolutionCollector(false); collector.AddObjective(obj); // What to remember in addition to the objective function value: collector.Add(nodes); Console.WriteLine("Coloring Problem:\n"); if (solver.Solve(db, collector)) { // Extract best solution found: Assignment sol = collector.Solution(0); Console.WriteLine("Solution found with " + sol.ObjectiveValue() + " colors.\n"); for (int i = 0; i < nodes.Length; i++) { long v = sol.Value(nodes[i]); if (i < Names.Length) { Console.WriteLine("Nodes " + i + " obtains color " + Names.GetValue(v)); } else { Console.WriteLine("Nodes " + i + " obtains color " + v); } } Console.WriteLine(); } 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()); Console.ReadKey(); }
public static void Main(String[] args) { InitTaskList(); Solver solver = new Solver("Jobshop"); // ----- Creates all Intervals and vars ----- // All tasks List <IntervalVar> allTasks = new List <IntervalVar>(); // Stores all tasks attached interval variables per job. List <List <IntervalVar> > jobsToTasks = new List <List <IntervalVar> >(jobsCount); // machinesToTasks stores the same interval variables as above, but // grouped my machines instead of grouped by jobs. List <List <IntervalVar> > machinesToTasks = new List <List <IntervalVar> >(machinesCount); for (int i = 0; i < machinesCount; i++) { machinesToTasks.Add(new List <IntervalVar>()); } // Creates all individual interval variables. foreach (List <Task> job in myJobList) { jobsToTasks.Add(new List <IntervalVar>()); foreach (Task task in job) { IntervalVar oneTask = solver.MakeFixedDurationIntervalVar( 0, horizon, task.Duration, false, task.Name); jobsToTasks[task.JobId].Add(oneTask); allTasks.Add(oneTask); machinesToTasks[task.Machine].Add(oneTask); } } // ----- Creates model ----- // Creates precedences inside jobs. foreach (List <IntervalVar> jobToTask in jobsToTasks) { int tasksCount = jobToTask.Count; for (int task_index = 0; task_index < tasksCount - 1; ++task_index) { IntervalVar t1 = jobToTask[task_index]; IntervalVar t2 = jobToTask[task_index + 1]; Constraint prec = solver.MakeIntervalVarRelation(t2, Solver.STARTS_AFTER_END, t1); solver.Add(prec); } } // Adds disjunctive constraints on unary resources, and creates // sequence variables. A sequence variable is a dedicated variable // whose job is to sequence interval variables. SequenceVar[] allSequences = new SequenceVar[machinesCount]; for (int machineId = 0; machineId < machinesCount; ++machineId) { string name = "Machine_" + machineId; DisjunctiveConstraint ct = solver.MakeDisjunctiveConstraint(machinesToTasks[machineId].ToArray(), name); solver.Add(ct); allSequences[machineId] = ct.SequenceVar(); } // Creates array of end_times of jobs. IntVar[] allEnds = new IntVar[jobsCount]; for (int i = 0; i < jobsCount; i++) { IntervalVar task = jobsToTasks[i].Last(); allEnds[i] = task.EndExpr().Var(); } // Objective: minimize the makespan (maximum end times of all tasks) // of the problem. IntVar objectiveVar = solver.MakeMax(allEnds).Var(); OptimizeVar objectiveMonitor = solver.MakeMinimize(objectiveVar, 1); // ----- Search monitors and decision builder ----- // This decision builder will rank all tasks on all machines. DecisionBuilder sequencePhase = solver.MakePhase(allSequences, Solver.SEQUENCE_DEFAULT); // After the ranking of tasks, the schedule is still loose and any // task can be postponed at will. But, because the problem is now a PERT // (http://en.wikipedia.org/wiki/Program_Evaluation_and_Review_Technique), // we can schedule each task at its earliest start time. This iscs // conveniently done by fixing the objective variable to its // minimum value. DecisionBuilder objPhase = solver.MakePhase( objectiveVar, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); // The main decision builder (ranks all tasks, then fixes the // objectiveVariable). DecisionBuilder mainPhase = solver.Compose(sequencePhase, objPhase); // Search log. const int kLogFrequency = 1000000; SearchMonitor searchLog = solver.MakeSearchLog(kLogFrequency, objectiveMonitor); SearchLimit limit = null; if (timeLimitInMs > 0) { limit = solver.MakeTimeLimit(timeLimitInMs); } SolutionCollector collector = solver.MakeLastSolutionCollector(); collector.Add(allSequences); collector.Add(allTasks.ToArray()); // Search. bool solutionFound = solver.Solve(mainPhase, searchLog, objectiveMonitor, limit, collector); if (solutionFound) { //The index of the solution from the collector const int SOLUTION_INDEX = 0; Assignment solution = collector.Solution(SOLUTION_INDEX); for (int m = 0; m < machinesCount; ++m) { Console.WriteLine("Machine " + m + " :"); SequenceVar seq = allSequences[m]; int[] storedSequence = collector.ForwardSequence(SOLUTION_INDEX, seq); foreach (int taskIndex in storedSequence) { IntervalVar task = seq.Interval(taskIndex); long startMin = solution.StartMin(task); long startMax = solution.StartMax(task); if (startMin == startMax) { Console.WriteLine("Task " + task.Name() + " starts at " + startMin + "."); } else { Console.WriteLine("Task " + task.Name() + " starts between " + startMin + " and " + startMax + "."); } } } } else { Console.WriteLine("No solution found!"); } }
// We don't need helper functions here // Csharp syntax is easier than C++ syntax! private static void CPisFun(int kBase) { // Constraint Programming engine Solver solver = new Solver("CP is fun!"); // Decision variables IntVar c = solver.MakeIntVar(1, kBase - 1, "C"); IntVar p = solver.MakeIntVar(0, kBase - 1, "P"); IntVar i = solver.MakeIntVar(1, kBase - 1, "I"); IntVar s = solver.MakeIntVar(0, kBase - 1, "S"); IntVar f = solver.MakeIntVar(1, kBase - 1, "F"); IntVar u = solver.MakeIntVar(0, kBase - 1, "U"); IntVar n = solver.MakeIntVar(0, kBase - 1, "N"); IntVar t = solver.MakeIntVar(1, kBase - 1, "T"); IntVar r = solver.MakeIntVar(0, kBase - 1, "R"); IntVar e = solver.MakeIntVar(0, kBase - 1, "E"); // We need to group variables in a vector to be able to use // the global constraint AllDifferent IntVar[] letters = new IntVar[] { c, p, i, s, f, u, n, t, r, e }; // Check if we have enough digits if (kBase < letters.Length) { throw new Exception("kBase < letters.Length"); } // Constraints solver.Add(letters.AllDifferent()); // CP + IS + FUN = TRUE solver.Add(p + s + n + kBase * (c + i + u) + kBase * kBase * f == e + kBase * u + kBase * kBase * r + kBase * kBase * kBase * t); SolutionCollector all_solutions = solver.MakeAllSolutionCollector(); // Add the interesting variables to the SolutionCollector all_solutions.Add(c); all_solutions.Add(p); // Create the variable kBase * c + p IntVar v1 = solver.MakeSum(solver.MakeProd(c, kBase), p).Var(); // Add it to the SolutionCollector all_solutions.Add(v1); // Decision Builder: hot to scour the search tree DecisionBuilder db = solver.MakePhase(letters, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); solver.Solve(db, all_solutions); // Retrieve the solutions int numberSolutions = all_solutions.SolutionCount(); Console.WriteLine("Number of solutions: " + numberSolutions); for (int index = 0; index < numberSolutions; ++index) { Assignment solution = all_solutions.Solution(index); Console.WriteLine("Solution found:"); Console.WriteLine("v1=" + solution.Value(v1)); } }
internal SearchAgentPredicateEventArgs(Solver solver, SolutionCollector collector) : base(solver) { Collector = collector; }