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; }
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()); }