Exemple #1
0
        static void Main(string[] args)
        {
            var parameters = new Parameters(new Randomizer(), args);

            if (parameters.ShowHelp)
            {
                var helpPrinter = new HelpPrinter();
                helpPrinter.Print();
            }
            else
            {
                var verbosePrinter = new VerbosePrinter(parameters.IsVerboseEnabled);
                var calculator     = new Calculator(verbosePrinter, parameters.Target, parameters.Numbers);

                if (parameters.IsUsingRandomTarget)
                {
                    Console.WriteLine("No target number specified. Will use random number.");
                    Console.WriteLine($"The random target is {calculator.Target}");
                    Console.WriteLine();
                }

                if (parameters.IsUsingRandomNumbers)
                {
                    Console.WriteLine("No numbers specified. Will use random numbers between 1 and 20.");
                    var numbers = string.Join(", ", calculator.InputNumbers.Select(o => o.Integer.ToString()));
                    Console.WriteLine($"The numbers are {numbers}");
                    Console.WriteLine();
                }

                var result  = calculator.FindSolutions();
                var printer = new SolutionPrinter(parameters.ShowAllResults, result);
                printer.Print();
            }
        }
Exemple #2
0
    // [END solution_printer]

    static void Main()
    {
        // Constraint programming engine
        // [START model]
        CpModel model = new CpModel();
        // [START model]

        // [START variables]
        int BoardSize = 8;

        IntVar[] queens = new IntVar[BoardSize];
        for (int i = 0; i < BoardSize; ++i)
        {
            queens[i] = model.NewIntVar(0, BoardSize - 1, $"x{i}");
        }
        // [END variables]

        // Define constraints.
        // [START constraints]
        // All rows must be different.
        model.AddAllDifferent(queens);

        // All columns must be different because the indices of queens are all different.
        // No two queens can be on the same diagonal.
        LinearExpr[] diag1 = new LinearExpr[BoardSize];
        LinearExpr[] diag2 = new LinearExpr[BoardSize];
        for (int i = 0; i < BoardSize; ++i)
        {
            diag1[i] = LinearExpr.Affine(queens[i], /*coeff=*/ 1, /*offset=*/ i);
            diag2[i] = LinearExpr.Affine(queens[i], /*coeff=*/ 1, /*offset=*/ -i);
        }

        model.AddAllDifferent(diag1);
        model.AddAllDifferent(diag2);
        // [END constraints]

        // [START solve]
        // Creates a solver and solves the model.
        CpSolver        solver = new CpSolver();
        SolutionPrinter cb     = new SolutionPrinter(queens);

        // Search for all solutions.
        solver.StringParameters = "enumerate_all_solutions:true";
        // And solve.
        solver.Solve(model, cb);
        // [END solve]

        // [START statistics]
        Console.WriteLine("Statistics");
        Console.WriteLine($"  conflicts : {solver.NumConflicts()}");
        Console.WriteLine($"  branches  : {solver.NumBranches()}");
        Console.WriteLine($"  wall time : {solver.WallTime()} s");
        Console.WriteLine($"  number of solutions found: {cb.SolutionCount()}");
        // [END statistics]
    }
Exemple #3
0
    static void Main(string[] args)
    {
        int numberGroups = 10;
        int numberItems  = 100;
        int numberColors = 3;
        int minItemsOfSameColorPerGroup = 4;

        var allGroups = Enumerable.Range(0, numberGroups).ToArray();
        var allItems  = Enumerable.Range(0, numberItems).ToArray();
        var allColors = Enumerable.Range(0, numberColors).ToArray();

        var values = allItems.Select(i => 1 + i + (i * i / 200)).ToArray();
        var colors = allItems.Select(i => i % numberColors).ToArray();

        var sumOfValues        = values.Sum();
        var averageSumPerGroup = sumOfValues / numberGroups;
        var numItemsPerGroup   = numberItems / numberGroups;

        var itemsPerColor = new Dictionary <int, List <int> >();

        foreach (var color in allColors)
        {
            itemsPerColor[color] = new List <int>();
            foreach (var item in allItems)
            {
                if (colors[item] == color)
                {
                    itemsPerColor[color].Add(item);
                }
            }
        }

        Console.WriteLine($"Model has {numberItems}, {numberGroups} groups and {numberColors} colors");
        Console.WriteLine($"    Average sum per group = {averageSumPerGroup}");

        var model = new CpModel();

        var itemInGroup = new IntVar[numberItems, numberGroups];

        foreach (var item in allItems)
        {
            foreach (var @group in allGroups)
            {
                itemInGroup[item, @group] = model.NewBoolVar($"item {item} in group {@group}");
            }
        }

        // Each group must have the same size.
        foreach (var @group in allGroups)
        {
            var itemsInGroup = allItems.Select(x => itemInGroup[x, @group]).ToArray();
            model.AddLinearConstraint(LinearExpr.Sum(itemsInGroup), numItemsPerGroup, numItemsPerGroup);
        }

        //# One item must belong to exactly one group.
        foreach (var item in allItems)
        {
            var groupsForItem = allGroups.Select(x => itemInGroup[item, x]).ToArray();
            model.Add(LinearExpr.Sum(groupsForItem) == 1);
        }

        // The deviation of the sum of each items in a group against the average.
        var e = model.NewIntVar(0, 550, "epsilon");

        // Constrain the sum of values in one group around the average sum per
        // group.
        foreach (var @group in allGroups)
        {
            var itemValues = allItems.Select(x => itemInGroup[x, @group]).ToArray();

            var sum = LinearExpr.ScalProd(itemValues, values);
            model.Add(sum <= averageSumPerGroup + e);
            model.Add(sum >= averageSumPerGroup - e);
        }

        // colorInGroup variables.
        var colorInGroup = new IntVar[numberColors, numberGroups];

        foreach (var @group in allGroups)
        {
            foreach (var color in allColors)
            {
                colorInGroup[color, @group] = model.NewBoolVar($"color {color} is in group {@group}");
            }
        }

        // Item is in a group implies its color is in that group.
        foreach (var item in allItems)
        {
            foreach (var @group in allGroups)
            {
                model.AddImplication(itemInGroup[item, @group], colorInGroup[colors[item], @group]);
            }
        }

        // If a color is in a group, it must contains at least
        // min_items_of_same_color_per_group items from that color.
        foreach (var color in allColors)
        {
            foreach (var @group in allGroups)
            {
                var literal = colorInGroup[color, @group];
                var items   = itemsPerColor[color].Select(x => itemInGroup[x, @group]).ToArray();
                model.Add(LinearExpr.Sum(items) >= minItemsOfSameColorPerGroup).OnlyEnforceIf(literal);
            }
        }

        // Compute the maximum number of colors in a group.
        int maxColor = numItemsPerGroup / minItemsOfSameColorPerGroup;

        // Redundant contraint: The problem does not solve in reasonable time
        // without it.
        if (maxColor < numberColors)
        {
            foreach (var @group in allGroups)
            {
                var all = allColors.Select(x => colorInGroup[x, @group]).ToArray();
                model.Add(LinearExpr.Sum(all) <= maxColor);
            }
        }

        // Minimize epsilon
        model.Minimize(e);

        var solver = new CpSolver();

        var solutionPrinter = new SolutionPrinter(values, colors, allGroups, allItems, itemInGroup);

        var status = solver.SolveWithSolutionCallback(model, solutionPrinter);
    }
Exemple #4
0
    // [END solution_printer]

    public static void Main(String[] args)
    {
        // [START data]
        const int numNurses = 4;
        const int numDays   = 3;
        const int numShifts = 3;

        int[] allNurses = Enumerable.Range(0, numNurses).ToArray();
        int[] allDays   = Enumerable.Range(0, numDays).ToArray();
        int[] allShifts = Enumerable.Range(0, numShifts).ToArray();
        // [END data]

        // Creates the model.
        // [START model]
        CpModel model = new CpModel();
        // [END model]

        // Creates shift variables.
        // shifts[(n, d, s)]: nurse 'n' works shift 's' on day 'd'.
        // [START variables]
        Dictionary <Tuple <int, int, int>, IntVar> shifts = new Dictionary <Tuple <int, int, int>, IntVar>();

        foreach (int n in allNurses)
        {
            foreach (int d in allDays)
            {
                foreach (int s in allShifts)
                {
                    shifts.Add(Tuple.Create(n, d, s), model.NewBoolVar($"shifts_n{n}d{d}s{s}"));
                }
            }
        }
        // [END variables]

        // Each shift is assigned to exactly one nurse in the schedule period.
        // [START exactly_one_nurse]
        foreach (int d in allDays)
        {
            foreach (int s in allShifts)
            {
                IntVar[] x = new IntVar[numNurses];
                foreach (int n in allNurses)
                {
                    var key = Tuple.Create(n, d, s);
                    x[n] = shifts[key];
                }
                model.Add(LinearExpr.Sum(x) == 1);
            }
        }
        // [END exactly_one_nurse]

        // Each nurse works at most one shift per day.
        // [START at_most_one_shift]
        foreach (int n in allNurses)
        {
            foreach (int d in allDays)
            {
                IntVar[] x = new IntVar[numShifts];
                foreach (int s in allShifts)
                {
                    var key = Tuple.Create(n, d, s);
                    x[s] = shifts[key];
                }
                model.Add(LinearExpr.Sum(x) <= 1);
            }
        }
        // [END at_most_one_shift]

        // [START assign_nurses_evenly]
        // Try to distribute the shifts evenly, so that each nurse works
        // minShiftsPerNurse shifts. If this is not possible, because the total
        // number of shifts is not divisible by the number of nurses, some nurses will
        // be assigned one more shift.
        int minShiftsPerNurse = (numShifts * numDays) / numNurses;
        int maxShiftsPerNurse;

        if ((numShifts * numDays) % numNurses == 0)
        {
            maxShiftsPerNurse = minShiftsPerNurse;
        }
        else
        {
            maxShiftsPerNurse = minShiftsPerNurse + 1;
        }
        foreach (int n in allNurses)
        {
            IntVar[] numShiftsWorked = new IntVar[numDays * numShifts];
            foreach (int d in allDays)
            {
                foreach (int s in allShifts)
                {
                    var key = Tuple.Create(n, d, s);
                    numShiftsWorked[d * numShifts + s] = shifts[key];
                }
            }
            model.AddLinearConstraint(LinearExpr.Sum(numShiftsWorked), minShiftsPerNurse, maxShiftsPerNurse);
        }
        // [END assign_nurses_evenly]

        // [START parameters]
        CpSolver solver = new CpSolver();

        solver.StringParameters += "linearization_level:0 ";
        // Tell the solver to enumerate all solutions.
        solver.StringParameters += "enumerate_all_solutions:true ";
        // [END parameters]

        // Display the first five solutions.
        // [START solution_printer_instantiate]
        const int       solutionLimit = 5;
        SolutionPrinter cb            = new SolutionPrinter(allNurses, allDays, allShifts, shifts, solutionLimit);
        // [END solution_printer_instantiate]

        // Solve
        // [START solve]
        CpSolverStatus status = solver.Solve(model, cb);

        Console.WriteLine($"Solve status: {status}");
        // [END solve]

        // [START statistics]
        Console.WriteLine("Statistics");
        Console.WriteLine($"  conflicts: {solver.NumConflicts()}");
        Console.WriteLine($"  branches : {solver.NumBranches()}");
        Console.WriteLine($"  wall time: {solver.WallTime()}s");
        // [END statistics]
    }