public virtual SearchMonitor getMonitor() { global::System.IntPtr cPtr = yarpPINVOKE.Searchable_getMonitor(swigCPtr); SearchMonitor ret = (cPtr == global::System.IntPtr.Zero) ? null : new SearchMonitor(cPtr, false); return(ret); }
private static void BasicLsWithFilter() { Console.WriteLine("BasicLsWithFilter"); Solver solver = new Solver("BasicLs"); IntVar[] vars = solver.MakeIntVarArray(4, 0, 4, "vars"); IntVar sum_var = vars.Sum().Var(); OptimizeVar obj = sum_var.Minimize(1); DecisionBuilder db = solver.MakePhase(vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE); MoveOneVar move_one_var = new MoveOneVar(vars); SumFilter filter = new SumFilter(vars); IntVarLocalSearchFilter[] filters = new IntVarLocalSearchFilter[] { filter }; LocalSearchFilterManager filter_manager = new LocalSearchFilterManager(filters); LocalSearchPhaseParameters ls_params = solver.MakeLocalSearchPhaseParameters(sum_var, move_one_var, db, null, filter_manager); DecisionBuilder ls = solver.MakeLocalSearchPhase(vars, db, ls_params); SolutionCollector collector = solver.MakeLastSolutionCollector(); collector.AddObjective(sum_var); SearchMonitor log = solver.MakeSearchLog(1000, obj); solver.Solve(ls, collector, obj, log); Console.WriteLine("Objective value = {0}", collector.ObjectiveValue(0)); }
SearchValue OnPropertyFilter(GameObject go, string propertyName) { if (!go) { return(SearchValue.invalid); } if (string.IsNullOrEmpty(propertyName)) { return(SearchValue.invalid); } using (var view = SearchMonitor.GetView()) { var documentKey = SearchUtils.GetDocumentKey(go); var recordKey = PropertyDatabase.CreateRecordKey(documentKey, PropertyDatabase.CreatePropertyHash(propertyName)); if (view.TryLoadProperty(recordKey, out object data) && data is SearchValue sv) { return(sv); } foreach (var c in EnumerateSubObjects(go)) { var property = FindPropertyValue(c, propertyName); if (property.valid) { view.StoreProperty(recordKey, property); return(property); } } view.StoreProperty(recordKey, SearchValue.invalid); } return(SearchValue.invalid); }
public void NewSearch(DecisionBuilder db, SearchMonitor sm1) { pinned_decision_builder_ = db; pinned_search_monitors_.Clear(); pinned_search_monitors_.Add(sm1); NewSearchAux(db, sm1); }
SearchValue OnPropertyFilter(GameObject go, string propertyName) { if (!go) { return(SearchValue.invalid); } if (string.IsNullOrEmpty(propertyName)) { return(SearchValue.invalid); } #if USE_PROPERTY_DATABASE using (var view = SearchMonitor.GetView()) #endif { #if USE_PROPERTY_DATABASE var documentKey = SearchUtils.GetDocumentKey(go); var recordKey = PropertyDatabase.CreateRecordKey(documentKey, PropertyDatabase.CreatePropertyHash(propertyName)); if (view.TryLoadProperty(recordKey, out object data)) { return((SearchValue)data); } #endif var gocs = go.GetComponents <Component>(); for (int componentIndex = 0; componentIndex < gocs.Length; ++componentIndex) { var c = gocs[componentIndex]; if (!c || (c.hideFlags & HideFlags.HideInInspector) == HideFlags.HideInInspector) { continue; } var property = FindPropertyValue(c, propertyName); if (property.valid) { #if USE_PROPERTY_DATABASE view.StoreProperty(recordKey, property); #endif return(property); } } #if USE_PROPERTY_DATABASE view.StoreProperty(recordKey, SearchValue.invalid); #endif } return(SearchValue.invalid); }
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(); }
private IEnumerator SearchItems(SearchContext context, SearchProvider provider) { if (!string.IsNullOrEmpty(context.searchQuery)) { if (m_HierarchyChanged) { m_SceneQueryEngine = new SceneQueryEngine(SearchUtils.FetchGameObjects()); m_HierarchyChanged = false; } IEnumerable <GameObject> subset = null; if (context.subset != null) { subset = context.subset .Where(item => item.provider.id == "scene") .Select(item => ObjectFromItem(item)) .Where(obj => obj != null); } #if USE_PROPERTY_DATABASE using (SearchMonitor.GetView()) #endif { yield return(m_SceneQueryEngine.Search(context, provider, subset) .Where(go => go) .Select(go => AddResult(context, provider, go))); } } else if (context.filterType != null && string.IsNullOrEmpty(context.searchQuery)) { yield return(UnityEngine.Object.FindObjectsOfType(context.filterType) .Select(obj => { if (obj is Component c) { return c.gameObject; } return obj as GameObject; }) .Where(go => go) .Select(go => AddResult(context, provider, go))); } }
private void Search() { int seed = 2; //This is a good seed to show the crash /* Assigning first tools */ DecisionBuilder myToolAssignmentPhase = new RandomSelectToolHeuristic(this, seed); /* Ranking of the tools */ DecisionBuilder sequencingPhase = solver.MakePhase(allToolSequences, Solver.SEQUENCE_DEFAULT); /* Then fixing time of tasks as early as possible */ DecisionBuilder timingPhase = solver.MakePhase( makespan, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); /* Overall phase */ DecisionBuilder mainPhase = solver.Compose(myToolAssignmentPhase, sequencingPhase, timingPhase); /* Logging */ const int logFrequency = 1000000; SearchMonitor searchLog = solver.MakeSearchLog(logFrequency, objective); /* Restarts */ SearchMonitor searchRestart = solver.MakeLubyRestart(100); /* Search Limit in ms */ SearchLimit limit = solver.MakeTimeLimit(180 * 1000); /* Collecting best solution */ SolutionCollector collector = solver.MakeLastSolutionCollector(); collector.AddObjective(makespan); //collector.Add( pile.ToArray() ); solver.NewSearch(mainPhase, searchLog, searchRestart, objective, limit); while (solver.NextSolution()) { Console.WriteLine("MAKESPAN: " + makespan.Value()); } }
private static void BasicLns() { Console.WriteLine("BasicLns"); Solver solver = new Solver("BasicLns"); IntVar[] vars = solver.MakeIntVarArray(4, 0, 4, "vars"); IntVar sum_var = vars.Sum().Var(); OptimizeVar obj = sum_var.Minimize(1); DecisionBuilder db = solver.MakePhase(vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE); OneVarLns one_var_lns = new OneVarLns(vars); LocalSearchPhaseParameters ls_params = solver.MakeLocalSearchPhaseParameters(one_var_lns, db); DecisionBuilder ls = solver.MakeLocalSearchPhase(vars, db, ls_params); SolutionCollector collector = solver.MakeLastSolutionCollector(); collector.AddObjective(sum_var); SearchMonitor log = solver.MakeSearchLog(1000, obj); solver.Solve(ls, collector, obj, log); Console.WriteLine("Objective value = {0}", collector.ObjectiveValue(0)); }
public void NewSearch(DecisionBuilder db, SearchMonitor sm1, SearchMonitor sm2, SearchMonitor sm3, SearchMonitor sm4) { pinned_decision_builder_ = db; pinned_search_monitors_.Clear(); pinned_search_monitors_.Add(sm1); pinned_search_monitors_.Add(sm2); pinned_search_monitors_.Add(sm3); pinned_search_monitors_.Add(sm4); NewSearchAux(db, sm1, sm2, sm3, sm4); }
public virtual void setMonitor(SearchMonitor monitor, string context) { yarpPINVOKE.Searchable_setMonitor__SWIG_0(swigCPtr, SearchMonitor.getCPtr(monitor), context); }
public virtual void setMonitor(SearchMonitor monitor) { yarpPINVOKE.Searchable_setMonitor__SWIG_1(swigCPtr, SearchMonitor.getCPtr(monitor)); }
/** * * This is a port of Charles Prud'homme's Java model * Partition.java * """ * Partition n numbers into two groups, so that * - the sum of the first group equals the sum of the second, * - and the sum of the squares of the first group equals the sum of * the squares of the second * """ * */ private static void Solve(int m) { Solver solver = new Solver("Partition"); // // Decision variables // IntVar[] x = solver.MakeIntVarArray(m, 1, 2 * m, "x"); IntVar[] y = solver.MakeIntVarArray(m, 1, 2 * m, "y"); // // Constraints // // break symmetries for (int i = 0; i < m - 1; i++) { solver.Add(x[i] < x[i + 1]); solver.Add(y[i] < y[i + 1]); } solver.Add(x[0] < y[0]); IntVar[] xy = new IntVar[2 * m]; for (int i = m - 1; i >= 0; i--) { xy[i] = x[i]; xy[m + i] = y[i]; } solver.Add(xy.AllDifferent()); int[] coeffs = new int[2 * m]; for (int i = m - 1; i >= 0; i--) { coeffs[i] = 1; coeffs[m + i] = -1; } solver.Add(xy.ScalProd(coeffs) == 0); IntVar[] sxy, sx, sy; sxy = new IntVar[2 * m]; sx = new IntVar[m]; sy = new IntVar[m]; for (int i = m - 1; i >= 0; i--) { sx[i] = x[i].Square().Var(); sxy[i] = sx[i]; sy[i] = y[i].Square().Var(); sxy[m + i] = sy[i]; } solver.Add(sxy.ScalProd(coeffs) == 0); solver.Add(x.Sum() == 2 * m * (2 * m + 1) / 4); solver.Add(y.Sum() == 2 * m * (2 * m + 1) / 4); solver.Add(sx.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12); solver.Add(sy.Sum() == 2 * m * (2 * m + 1) * (4 * m + 1) / 12); // // Search // DecisionBuilder db = solver.MakeDefaultPhase(xy); SearchMonitor log = solver.MakeSearchLog(10000); solver.NewSearch(db, log); while (solver.NextSolution()) { for (int i = 0; i < m; i++) { Console.Write("[" + xy[i].Value() + "] "); } Console.WriteLine(); for (int i = 0; i < m; i++) { Console.Write("[" + xy[m + i].Value() + "] "); } Console.WriteLine("\n"); } 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(); }
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; VoidToString prefix = new Prefix(); SearchMonitor search_log = solver.MakeSearchLog(kLogFrequency, objective_monitor, prefix); 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."); } }
public static void Solve(FlexibleJobShopData data, bool chatty = false) { // Compute horizon var horizon = data.JobList.Sum( j => j.TaskList.Sum( t => t.Durations.Max())); // ----- Create all intervals and vars ----- /* * // Use some profiling and change the default parameters of the solver * SolverParameters solverParams = new SolverParameters(); * // Change the profile level * solverParams.profile_level = SolverParameters.NORMAL_PROFILING; * // Constraint programming engine * Solver solver = new Solver("JobShop", solverParams); */ // Constraint programming engine Solver solver = new Solver($"FlexibleJobShop: {data.Name}"); // Initialize dictionaries to hold references to task intervals var tasksByJobId = new Dictionary <uint, List <TaskAlternative> >(); foreach (var job in data.JobList) { tasksByJobId[job.Id] = new List <TaskAlternative>(job.TaskList.Count); } var tasksByMachineId = new Dictionary <uint, IntervalVarVector>(); foreach (var machine in data.MachineList) { tasksByMachineId[machine.Id] = new IntervalVarVector(); } // Creates all individual interval variables and collect in dictionaries foreach (var job in data.JobList) { foreach (var task in job.TaskList) { var alternative = new TaskAlternative(job.Id); tasksByJobId[job.Id].Add(alternative); var activeVariables = new IntVarVector(); var hasAlternatives = task.AlternativesCount > 1; for (int alt = 0; alt < task.AlternativesCount; alt++) { var machine = task.Machines[alt]; var duration = task.Durations[alt]; var name = $"{task.Name}; Alternative {alt}: {machine.Name}, Duration {duration}"; IntervalVar interval = solver.MakeFixedDurationIntervalVar(0, horizon, duration, hasAlternatives, name); alternative.Add(interval); tasksByMachineId[machine.Id].Add(interval); if (hasAlternatives) { activeVariables.Add(interval.PerformedExpr().Var()); } } alternative.AlternativeVar = solver.MakeIntVar(0, task.AlternativesCount - 1, task.Name); if (hasAlternatives) { solver.Add(solver.MakeMapDomain(alternative.AlternativeVar, activeVariables)); } } } // ----- Create model ----- // Create precedences inside jobs foreach (var taskAltList in tasksByJobId.Values) { for (int i = 0; i < taskAltList.Count - 1; i++) { TaskAlternative currentTaskAlt = taskAltList[i]; TaskAlternative nextTaskAlt = taskAltList[i + 1]; foreach (var alt1 in currentTaskAlt) { foreach (var alt2 in nextTaskAlt) { solver.Add(solver.MakeIntervalVarRelation( alt2, Solver.STARTS_AFTER_END, alt1)); } } } } // Collect alternative variables. IntVarVector alternativeVariableVec = new IntVarVector(); foreach (var taskAltList in tasksByJobId.Values) { foreach (var taskAlt in taskAltList) { if (!taskAlt.AlternativeVar.Bound()) { alternativeVariableVec.Add(taskAlt.AlternativeVar); } } } // Add disjunctive constraints on unary resources, and create // sequence variables. A sequence variable is a dedicated variable // whose job is to sequence interval variables. SequenceVarVector allSequences = new SequenceVarVector(); foreach (var machine in data.MachineList) { DisjunctiveConstraint disjCt = solver.MakeDisjunctiveConstraint( tasksByMachineId[machine.Id], machine.Name); solver.Add(disjCt); allSequences.Add(disjCt.SequenceVar()); } // Create array of end_times of jobs IntVarVector endsVec = new IntVarVector(); foreach (var taskAltList in tasksByJobId.Values) { TaskAlternative lastTaskAlt = taskAltList.Last(); foreach (var alt in lastTaskAlt) { endsVec.Add(alt.SafeEndExpr(-1).Var()); } } // Objective: minimize the makespan (maximum end times of all tasks) // of the problem. IntVar objectiveVar = solver.MakeMax(endsVec).Var(); OptimizeVar objectiveMonitor = solver.MakeMinimize(objectiveVar, 1); // ----- Search monitors and decision builder ----- // This decision builder will assign all alternative variables. DecisionBuilder alternativePhase = solver.MakePhase(alternativeVariableVec, Solver.CHOOSE_MIN_SIZE, Solver.ASSIGN_MIN_VALUE); // 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 is // conveniently done by fixing the objective variable to its // minimum value. DecisionBuilder objectivePhase = solver.MakePhase(objectiveVar, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); // The main decision builder (ranks all tasks, then fixes the // objective_variable). DecisionBuilder mainPhase = solver.Compose(alternativePhase, sequencePhase, objectivePhase); // Search log const int kLogFrequency = 1000000; SearchMonitor searchLog = solver.MakeSearchLog(kLogFrequency, objectiveMonitor); const long FLAGS_time_limit_in_ms = 1000 * 60 * 20; SearchLimit limit = null; if (FLAGS_time_limit_in_ms > 0) { limit = solver.MakeTimeLimit(FLAGS_time_limit_in_ms); } SolutionCollector collector = solver.MakeLastSolutionCollector(); collector.AddObjective(objectiveVar); collector.Add(alternativeVariableVec); collector.Add(allSequences); foreach (var taskVec in tasksByMachineId.Values) { foreach (var task in taskVec) { collector.Add(task.StartExpr().Var()); } } // ----- 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); Console.WriteLine(); uint machineIdx = 0; foreach (var seq in allSequences) { machineIdx++; var taskSeq = collector.ForwardSequence(SOLUTION_INDEX, seq); Console.WriteLine($"{seq.Name()}:"); Console.WriteLine(" Tasks: " + string.Join(", ", taskSeq)); //foreach (var taskIndex in storedSequence) //{ // IntervalVar task = sequence.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}."); // } //} Console.WriteLine(); Console.Write(" Starting times:"); foreach (var s in taskSeq) { Console.Write(" " + collector.Value(0, tasksByMachineId[machineIdx][s].StartExpr().Var()).ToString()); } Console.WriteLine(); } //var x = tasksByMachineId[1][0].StartExpr().Var(); //var xValStr = collector.Value(0, x).ToString(); Console.WriteLine("objective function value = " + solution.ObjectiveValue()); //TEMP } // Save profile in file //solver.ExportProfilingOverview("profile.txt"); // Done solver.EndSearch(); }
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!"); } }
/** * * Golomb Ruler problem. * * This C# implementation is based on Charles Prud'homme's * or-tools/Java model: * http://code.google.com/p/or-tools/source/browse/trunk/com/google/ortools/constraintsolver/samples/GolombRuler.java * */ private static void Solve(int m = 8) { Solver solver = new Solver("GolombRuler"); // // Decision variables // IntVar[] ticks = solver.MakeIntVarArray(m, 0, ((m < 31) ? (1 << (m + 1)) - 1 : 9999), "ticks"); IntVar[] diff = new IntVar[(m * m - m) / 2]; // // Constraints // solver.Add(ticks[0] == 0); for (int i = 0; i < ticks.Length - 1; i++) { solver.Add(ticks[i] < ticks[i + 1]); } for (int k = 0, i = 0; i < m - 1; i++) { for (int j = i + 1; j < m; j++, k++) { diff[k] = (ticks[j] - ticks[i]).Var(); solver.Add(diff[k] >= (j - i) * (j - i + 1) / 2); } } solver.Add(diff.AllDifferent()); // break symetries if (m > 2) { solver.Add(diff[0] < diff[diff.Length - 1]); } // // Optimization // OptimizeVar opt = ticks[m - 1].Minimize(1); // // Search // DecisionBuilder db = solver.MakePhase(ticks, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE); // We just want the debug info for larger instances. if (m >= 11) { SearchMonitor log = solver.MakeSearchLog(10000, opt); solver.NewSearch(db, opt, log); } else { solver.NewSearch(db, opt); } while (solver.NextSolution()) { Console.Write("opt: {0} [ ", ticks[m - 1].Value()); for (int i = 0; i < m; i++) { Console.Write("{0} ", ticks[i].Value()); } 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()); solver.EndSearch(); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(SearchMonitor obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
internal static HandleRef getCPtr(SearchMonitor obj) { return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; }
/** * * Nurse rostering * * This is a simple nurse rostering model using a DFA and * the built-in TransitionConstraint. * * The DFA is from MiniZinc Tutorial, Nurse Rostering example: * - one day off every 4 days * - no 3 nights in a row. * * Also see: * - http://www.hakank.org/or-tools/nurse_rostering.py * - http://www.hakank.org/or-tools/nurse_rostering_regular.cs * which use (a decomposition of) regular constraint * */ private static void Solve(int nurse_multiplier, int week_multiplier) { Console.WriteLine("Starting Nurse Rostering"); Console.WriteLine(" - {0} teams of 7 nurses", nurse_multiplier); Console.WriteLine(" - {0} blocks of 14 days", week_multiplier); Solver solver = new Solver("NurseRostering"); // // Data // // Note: If you change num_nurses or num_days, // please also change the constraints // on nurse_stat and/or day_stat. int num_nurses = 7 * nurse_multiplier; int num_days = 14 * week_multiplier; // Note: I had to add a dummy shift. int dummy_shift = 0; int day_shift = 1; int night_shift = 2; int off_shift = 3; int[] shifts = { dummy_shift, day_shift, night_shift, off_shift }; int[] valid_shifts = { day_shift, night_shift, off_shift }; // the DFA (for regular) int initial_state = 1; int[] accepting_states = { 1, 2, 3, 4, 5, 6 }; /* * // This is the transition function * // used in nurse_rostering_regular.cs * int[,] transition_fn = { * // d,n,o * {2,3,1}, // state 1 * {4,4,1}, // state 2 * {4,5,1}, // state 3 * {6,6,1}, // state 4 * {6,0,1}, // state 5 * {0,0,1} // state 6 * }; */ // For TransitionConstraint IntTupleSet transition_tuples = new IntTupleSet(3); // state, input, next state transition_tuples.InsertAll(new long[][] { new long[] { 1, 1, 2 }, new long[] { 1, 2, 3 }, new long[] { 1, 3, 1 }, new long[] { 2, 1, 4 }, new long[] { 2, 2, 4 }, new long[] { 2, 3, 1 }, new long[] { 3, 1, 4 }, new long[] { 3, 2, 5 }, new long[] { 3, 3, 1 }, new long[] { 4, 1, 6 }, new long[] { 4, 2, 6 }, new long[] { 4, 3, 1 }, new long[] { 5, 1, 6 }, new long[] { 5, 3, 1 }, new long[] { 6, 3, 1 } }); string[] days = { "d", "n", "o" }; // for presentation // // Decision variables // // // For TransitionConstraint // IntVar[,] x = solver.MakeIntVarMatrix(num_nurses, num_days, valid_shifts, "x"); IntVar[] x_flat = x.Flatten(); // // summary of the nurses // IntVar[] nurse_stat = new IntVar[num_nurses]; // // summary of the shifts per day // int num_shifts = shifts.Length; IntVar[,] day_stat = new IntVar[num_days, num_shifts]; for (int i = 0; i < num_days; i++) { for (int j = 0; j < num_shifts; j++) { day_stat[i, j] = solver.MakeIntVar(0, num_nurses, "day_stat"); } } // // Constraints // for (int i = 0; i < num_nurses; i++) { IntVar[] reg_input = new IntVar[num_days]; for (int j = 0; j < num_days; j++) { reg_input[j] = x[i, j]; } solver.Add(reg_input.Transition(transition_tuples, initial_state, accepting_states)); } // // Statistics and constraints for each nurse // for (int nurse = 0; nurse < num_nurses; nurse++) { // Number of worked days (either day or night shift) IntVar[] nurse_days = new IntVar[num_days]; for (int day = 0; day < num_days; day++) { nurse_days[day] = x[nurse, day].IsMember(new int[] { day_shift, night_shift }); } nurse_stat[nurse] = nurse_days.Sum().Var(); // Each nurse must work between 7 and 10 // days/nights during this period solver.Add(nurse_stat[nurse] >= 7 * week_multiplier / nurse_multiplier); solver.Add(nurse_stat[nurse] <= 10 * week_multiplier / nurse_multiplier); } // // Statistics and constraints for each day // for (int day = 0; day < num_days; day++) { IntVar[] nurses = new IntVar[num_nurses]; for (int nurse = 0; nurse < num_nurses; nurse++) { nurses[nurse] = x[nurse, day]; } IntVar[] stats = new IntVar[num_shifts]; for (int shift = 0; shift < num_shifts; ++shift) { stats[shift] = day_stat[day, shift]; } solver.Add(nurses.Distribute(stats)); // // Some constraints for each day: // // Note: We have a strict requirements of // the number of shifts. // Using atleast constraints is harder // in this model. // if (day % 7 == 5 || day % 7 == 6) { // special constraints for the weekends solver.Add(day_stat[day, day_shift] == 2 * nurse_multiplier); solver.Add(day_stat[day, night_shift] == nurse_multiplier); solver.Add(day_stat[day, off_shift] == 4 * nurse_multiplier); } else { // for workdays: // - exactly 3 on day shift solver.Add(day_stat[day, day_shift] == 3 * nurse_multiplier); // - exactly 2 on night solver.Add(day_stat[day, night_shift] == 2 * nurse_multiplier); // - exactly 2 off duty solver.Add(day_stat[day, off_shift] == 2 * nurse_multiplier); } } // // Search // DecisionBuilder db = solver.MakePhase(x_flat, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE); SearchMonitor log = solver.MakeSearchLog(1000000); solver.NewSearch(db, log); int num_solutions = 0; while (solver.NextSolution()) { num_solutions++; for (int i = 0; i < num_nurses; i++) { Console.Write("Nurse #{0,-2}: ", i); var occ = new Dictionary <int, int>(); for (int j = 0; j < num_days; j++) { int v = (int)x[i, j].Value() - 1; if (!occ.ContainsKey(v)) { occ[v] = 0; } occ[v]++; Console.Write(days[v] + " "); } Console.Write(" #workdays: {0,2}", nurse_stat[i].Value()); foreach (int s in valid_shifts) { int v = 0; if (occ.ContainsKey(s - 1)) { v = occ[s - 1]; } Console.Write(" {0}:{1}", days[s - 1], v); } Console.WriteLine(); } Console.WriteLine(); Console.WriteLine("Statistics per day:\nDay d n o"); for (int j = 0; j < num_days; j++) { Console.Write("Day #{0,2}: ", j); foreach (int t in valid_shifts) { Console.Write(day_stat[j, t].Value() + " "); } Console.WriteLine(); } Console.WriteLine(); // We just show 2 solutions if (num_solutions > 1) { break; } } 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(); }
public void NewSearch(DecisionBuilder db, SearchMonitor[] monitors) { pinned_decision_builder_ = db; pinned_search_monitors_.Clear(); pinned_search_monitors_.AddRange(monitors); NewSearchAux(db, monitors); }