Exemple #1
0
    void Solve(int limit)
    {
        // Declares the optimization model.
        LSModel model = localsolver.GetModel();

        trucksUsed         = new LSExpression[nbTrucks];
        customersSequences = new LSExpression[nbTrucks];
        routeDistances     = new LSExpression[nbTrucks];

        // Sequence of customers visited by each truck.
        for (int k = 0; k < nbTrucks; k++)
        {
            customersSequences[k] = model.List(nbCustomers);
        }

        // All customers must be visited by the trucks
        model.Constraint(model.Partition(customersSequences));

        // Create demands and distances as arrays to be able to access it with an "at" operator
        LSExpression demandsArray           = model.Array(demands);
        LSExpression distanceWarehouseArray = model.Array(distanceWarehouses);
        LSExpression distanceArray          = model.Array(distanceMatrix);

        for (int k = 0; k < nbTrucks; k++)
        {
            LSExpression sequence = customersSequences[k];
            LSExpression c        = model.Count(sequence);

            // A truck is used if it visits at least one customer
            trucksUsed[k] = c > 0;

            // The quantity needed in each route must not exceed the truck capacity
            LSExpression demandSelector = model.Function(i => demandsArray[sequence[i]]);
            LSExpression routeQuantity  = model.Sum(model.Range(0, c), demandSelector);
            model.Constraint(routeQuantity <= truckCapacity);

            // Distance travelled by truck k
            LSExpression distSelector = model.Function(i => distanceArray[sequence[i - 1], sequence[i]]);
            routeDistances[k] = model.Sum(model.Range(1, c), distSelector)
                                + model.If(c > 0, distanceWarehouseArray[sequence[0]] + distanceWarehouseArray[sequence[c - 1]], 0);
        }

        nbTrucksUsed  = model.Sum(trucksUsed);
        totalDistance = model.Sum(routeDistances);

        // Objective: minimize the number of trucks used, then minimize the distance traveled
        model.Minimize(nbTrucksUsed);
        model.Minimize(totalDistance);

        model.Close();

        // Parameterizes the solver.
        LSPhase phase = localsolver.CreatePhase();

        phase.SetTimeLimit(limit);

        localsolver.Solve();
    }
    void Solve(int limit)
    {
        // Declares the optimization model.
        localsolver = new LocalSolver();
        LSModel model = localsolver.GetModel();

        // Decision variables x[i]
        x = new LSExpression[nbItems];
        for (int i = 0; i < nbItems; i++)
        {
            x[i] = model.Bool();
        }

        // weight constraint
        LSExpression knapsackWeight = model.Sum();

        for (int i = 0; i < nbItems; i++)
        {
            knapsackWeight.AddOperand(x[i] * weights[i]);
        }
        model.Constraint(knapsackWeight <= knapsackBound);

        // maximize value
        knapsackValue = model.Sum();
        for (int i = 0; i < nbItems; i++)
        {
            knapsackValue.AddOperand(x[i] * values[i]);
        }

        model.Maximize(knapsackValue);
        model.Close();

        // Parameterizes the solver.
        localsolver.GetParam().SetTimeLimit(limit);

        localsolver.Solve();

        solutions = new List <int>();
        for (int i = 0; i < nbItems; ++i)
        {
            if (x[i].GetValue() == 1)
            {
                solutions.Add(i);
            }
        }
    }
 public ModelBuilder(SolverVariables solverVariables)
 {
     this.solverVariables = solverVariables;
     this.model           = this.solverVariables.Model;
 }
Exemple #4
0
        public SolverVariables(LSModel model, int numberOfRoutes, List <Visit> visits, int[,] routeCosts, OptimizationInput optimizationInput, int numberOfFakeSantas)
        {
            Model              = model;
            Visits             = visits;
            NumberOfRoutes     = numberOfRoutes;
            OptimizationInput  = optimizationInput;
            NumberOfFakeSantas = numberOfFakeSantas;
            NumberOfSantas     = optimizationInput.Santas.Length;

            SantaUsed                = new LSExpression[numberOfRoutes];
            VisitSequences           = new LSExpression[numberOfRoutes + 1];
            SantaWalkingTime         = new LSExpression[numberOfRoutes];
            SantaRouteTime           = new LSExpression[numberOfRoutes];
            SantaVisitDurations      = new LSExpression[numberOfRoutes];
            SantaDesiredDuration     = new LSExpression[numberOfRoutes];
            SantaUnavailableDuration = new LSExpression[numberOfRoutes];
            SantaVisitStartingTimes  = new LSExpression[numberOfRoutes];

            SantaOvertime              = new LSExpression[numberOfRoutes];
            SantaWaitBeforeStart       = new LSExpression[numberOfRoutes];
            SantaWaitBetweenVisit      = new LSExpression[numberOfRoutes][];
            SantaWaitBetweenVisitArray = new LSExpression[numberOfRoutes];

            int numberOfVisits = Visits.Count;
            var longestDay     = OptimizationInput.Days.Max(d => d.to - d.from);

            for (var k = 0; k < numberOfRoutes; k++)
            {
                VisitSequences[k]       = Model.List(numberOfVisits);
                SantaOvertime[k]        = Model.Int(0, int.MaxValue);
                SantaWaitBeforeStart[k] = Model.Int(0, longestDay);

                SantaWaitBetweenVisit[k] = new LSExpression[numberOfVisits];
                for (var i = 0; i < SantaWaitBetweenVisit[k].Length; i++)
                {
                    SantaWaitBetweenVisit[k][i] = Model.Int(0, longestDay);
                }

                SantaWaitBetweenVisitArray[k] = Model.Array(SantaWaitBetweenVisit[k]);
            }

            // overflow for unused santa breaks
            VisitSequences[numberOfRoutes] = model.List(numberOfVisits);

            DistanceArray         = model.Array(RouteCostJagged(Visits, routeCosts));
            DistanceFromHomeArray = model.Array(Visits.Select(v => v.WayCostFromHome).ToArray());
            DistanceToHomeArray   = model.Array(Visits.Select(v => v.WayCostToHome).ToArray());
            VisitDurationArray    = model.Array(Visits.Select(v => v.Duration).ToArray());

            // desired
            var visitsOnlyDesired = visits
                                    .Select(v =>
                                            // fake arr
                                            v.Desired.Length == 0
                        ? new[] { new[] { -1, -1 } }
                        : v.Desired.Select(d => new[] { d.from, d.to }).ToArray()
                                            )
                                    .ToArray();

            VisitDesiredArray      = model.Array(visitsOnlyDesired);
            VisitDesiredCountArray = model.Array(visits.Select(v => v.Desired.Length).ToArray());

            // unavailable
            var visitsOnlyUnavailable = visits
                                        .Select(v =>
                                                // fake arr
                                                v.Unavailable.Length == 0
                        ? new[] { new[] { -1, -1 } }
                        : v.Unavailable.Select(d => new[] { d.from, d.to }).ToArray()
                                                )
                                        .ToArray();

            VisitUnavailableArray      = model.Array(visitsOnlyUnavailable);
            VisitUnavailableCountArray = model.Array(visits.Select(v => v.Unavailable.Length).ToArray());
        }