示例#1
0
        private void Init()
        {
            horizon                = factoryData.Horizon;
            solver                 = new Solver("Factory Scheduling");
            tasks                  = factoryData.getFlatTaskList();
            taskTypes              = factoryData.getTaskTypes();
            taskStructures         = new TaskAlternative[tasks.Length];
            location2Task          = new TaskAlternative[factoryData.NbWorkLocations][];
            tool2Task              = new List <IntervalVar> [factoryData.NbTools];
            toolIntervalVar2TaskId = new List <int> [factoryData.NbTools];
            tool2TransitionTimes   = new List <IntVar> [factoryData.NbTools];

            taskType2Tool = new List <Tool> [taskTypes.Length];
            selectedTool  = new List <IntVar>();
            for (int tt = 0; tt < taskTypes.Length; tt++)
            {
                taskType2Tool[tt] = new List <Tool>();
            }

            foreach (Tool tool in factoryData.Tools)
            {
                foreach (int taskType in tool.TaskTypes)
                {
                    taskType2Tool[taskType].Add(tool);
                }
            }
            for (int d = 0; d < factoryData.NbWorkLocations; d++)
            {
                location2Task[d] = new TaskAlternative[factoryData.Locations[d].NbTasks];
            }
            for (int t = 0; t < factoryData.NbTools; t++)
            {
                tool2Task[t] = new List <IntervalVar>();
                toolIntervalVar2TaskId[t] = new List <int>();
                tool2TransitionTimes[t]   = new List <IntVar>();
            }

            allToolSequences = new SequenceVar[factoryData.NbTools - 1];

            startingTimes = new IntVar[factoryData.NbTools - 1][];
            endTimes      = new IntVar[factoryData.NbTools - 1][];
        }
示例#2
0
        private void Model()
        {
            /* Building basic task data structures */
            for (int i = 0; i < tasks.Length; i++)
            {
                /* Create a new set of possible IntervalVars & IntVar to decide
                 * which one (and only 1) is performed */
                taskStructures[i] = new TaskAlternative(tasks[i]);

                /* Container to use when posting constraints */
                location2Task[tasks[i].LocationId][tasks[i].TaskPosition] = taskStructures[i];

                /* Get task type */
                int taskType = tasks[i].TaskType;

                /* Possible tool for this task */
                List <Tool> tools    = taskType2Tool[taskType];
                bool        optional = tools.Count > 1;

                /* List of boolean variables. If performedOnTool[t] == true then
                 * the task is performed on tool t */
                List <IntVar> performedOnTool = new List <IntVar>();
                for (int t = 0; t < tools.Count; t++)
                {
                    /* Creating an IntervalVar. If tools.Count > 1 the intervalVar
                     * is *OPTIONAL* */
                    int toolId = tools[t].Id;
                    Debug.Assert(tasks[i].Durations.ContainsKey(toolId));
                    int    duration = tasks[i].Durations[toolId];
                    string name     = "J " + tasks[i].Id + " [" + toolId + "]";

                    IntervalVar intervalVar;
                    if (taskType == factoryData.Inspection)
                    {
                        /* We set a 0 time if the task is an inspection */
                        duration    = 0;
                        intervalVar = solver.MakeFixedDurationIntervalVar(0, horizon, duration, optional, name);
                        IntVar start = intervalVar.SafeStartExpr(-1).Var();

                        intervalVar.SafeStartExpr(-1).Var().SetValues(factoryData.InspectionStarts);
                    }
                    else
                    {
                        intervalVar = solver.MakeFixedDurationIntervalVar(0, horizon, duration, optional, name);
                    }

                    taskStructures[i].Intervals.Add(intervalVar);
                    tool2Task[toolId].Add(intervalVar);
                    toolIntervalVar2TaskId[toolId].Add(i);

                    /* Collecting all the bool vars, even if they are optional */
                    performedOnTool.Add(intervalVar.PerformedExpr().Var());
                }

                /* Linking the bool var to a single integer variable: */
                /* if alternativeToolVar == t <=> performedOnTool[t] == true */
                string alternativeName    = "J " + tasks[i].Id;
                IntVar alternativeToolVar = solver.MakeIntVar(0, tools.Count - 1, alternativeName);
                taskStructures[i].ToolVar = alternativeToolVar;

                solver.Add(solver.MakeMapDomain(alternativeToolVar, performedOnTool.ToArray()));
                Debug.Assert(performedOnTool.ToArray().Length == alternativeToolVar.Max() + 1);

                selectedTool.Add(alternativeToolVar);
            }

            /* Creates precedences on a work Location in order to enforce a
             * fully ordered set within the same location
             */
            for (int d = 0; d < location2Task.Length; d++)
            {
                for (int i = 0; i < location2Task[d].Length - 1; i++)
                {
                    TaskAlternative task1 = location2Task[d][i];
                    TaskAlternative task2 = location2Task[d][i + 1];
                    /* task1 must end before task2 starts */
                    /* Adding precedence for each possible alternative pair */
                    for (int t1 = 0; t1 < task1.Intervals.Count(); t1++)
                    {
                        IntervalVar task1Alternative = task1.Intervals[t1];
                        for (int t2 = 0; t2 < task2.Intervals.Count(); t2++)
                        {
                            IntervalVar task2Alternative = task2.Intervals[t2];
                            Constraint  precedence       = solver.MakeIntervalVarRelation(
                                task2Alternative, Solver.STARTS_AFTER_END, task1Alternative);
                            solver.Add(precedence);
                        }
                    }
                }
            }

            /* Adds disjunctive constraints on unary resources, and creates
             * sequence variables. */
            for (int t = 0; t < factoryData.NbTools; t++)
            {
                string name = "Tool " + t;

                if (!factoryData.Tools[t].CanPerformTaskType(factoryData.Inspection))
                {
                    DisjunctiveConstraint ct = solver.MakeDisjunctiveConstraint(tool2Task[t].ToArray(), name);
                    solver.Add(ct);
                    allToolSequences[t] = ct.SequenceVar();
                }
                PostTransitionTimeConstraints(t, true);
            }

            /* Collecting all tasks end for makespan objective function */
            List <IntVar> intervalEnds = new List <IntVar>();

            for (int i = 0; i < tasks.Length; i++)
            {
                foreach (IntervalVar var in taskStructures[i].Intervals)
                {
                    intervalEnds.Add(var.SafeEndExpr(-1).Var());
                }
            }

            /* Objective: minimize the makespan (maximum end times of all tasks) */
            makespan  = solver.MakeMax(intervalEnds.ToArray()).Var();
            objective = solver.MakeMinimize(makespan, 1);
        }