Пример #1
0
        /*
         * 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();
        }
Пример #2
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!");
        }
    }
Пример #3
0
    //  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));
        }
    }
Пример #4
0
 internal SearchAgentPredicateEventArgs(Solver solver, SolutionCollector collector)
     : base(solver)
 {
     Collector = collector;
 }