Ejemplo n.º 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();
    }
        /// <summary>
        /// adds a constraint that time after the day-end is considered overtime
        /// </summary>
        /// <param name="day"></param>
        /// <param name="santa"></param>
        public void AddOvertimeConstraint(int day, int santa)
        {
            var s        = GetSantaId(day, santa);
            var sequence = solverVariables.VisitSequences[s];
            var c        = model.Count(sequence);

            model.Constraint(model.If(solverVariables.SantaUsed[s],
                                      solverVariables.SantaVisitStartingTimes[s][c - 1] + solverVariables.VisitDurationArray[sequence[c - 1]] + solverVariables.DistanceToHomeArray[sequence[c - 1]],
                                      0) <= solverVariables.OptimizationInput.Days[day].to + solverVariables.SantaOvertime[s]);
        }