예제 #1
0
    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);
    }
예제 #2
0
    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));
    }
예제 #3
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);
        }
예제 #4
0
 public void NewSearch(DecisionBuilder db, SearchMonitor sm1)
 {
     pinned_decision_builder_ = db;
     pinned_search_monitors_.Clear();
     pinned_search_monitors_.Add(sm1);
     NewSearchAux(db, sm1);
 }
예제 #5
0
        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();
        }
예제 #7
0
        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)));
            }
        }
예제 #8
0
        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());
            }
        }
예제 #9
0
    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));
    }
예제 #10
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);
 }
예제 #11
0
 public virtual void setMonitor(SearchMonitor monitor, string context)
 {
     yarpPINVOKE.Searchable_setMonitor__SWIG_0(swigCPtr, SearchMonitor.getCPtr(monitor), context);
 }
예제 #12
0
 public virtual void setMonitor(SearchMonitor monitor)
 {
     yarpPINVOKE.Searchable_setMonitor__SWIG_1(swigCPtr, SearchMonitor.getCPtr(monitor));
 }
예제 #13
0
    /**
     *
     * 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();
    }
예제 #14
0
        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.");
            }
        }
예제 #15
0
 public virtual void setMonitor(SearchMonitor monitor, string context)
 {
     yarpPINVOKE.Searchable_setMonitor__SWIG_0(swigCPtr, SearchMonitor.getCPtr(monitor), context);
 }
예제 #16
0
        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();
        }
예제 #17
0
    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!");
        }
    }
예제 #18
0
    /**
     *
     * 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();
    }
예제 #19
0
 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);
 }
예제 #20
0
 internal static HandleRef getCPtr(SearchMonitor obj)
 {
     return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
 }
예제 #21
0
 public virtual void setMonitor(SearchMonitor monitor)
 {
     yarpPINVOKE.Searchable_setMonitor__SWIG_1(swigCPtr, SearchMonitor.getCPtr(monitor));
 }
    /**
     *
     * 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();
    }
예제 #23
0
 public void NewSearch(DecisionBuilder db, SearchMonitor[] monitors) {
   pinned_decision_builder_ = db;
   pinned_search_monitors_.Clear();
   pinned_search_monitors_.AddRange(monitors);
   NewSearchAux(db, monitors);
 }