private CeplexParameters GetCeplexParametersMultipleVehicleRoutingProblem(Depot depot, List <DeliveryTruckTrip> fractionedScheduledTrips) { var ceplexParameters = new CeplexParameters(); var availablesVehicles = _vehicleRepository.GetAvailableVehiclesByDepot(depot.DepotId); ceplexParameters.QuantityOfVehiclesAvailable = availablesVehicles.Count; ceplexParameters.QuantityOfClients = fractionedScheduledTrips.Count; ceplexParameters.VehiclesGreatestPossibleDemand = 11; ceplexParameters.GreatestPossibleDemand = (int)fractionedScheduledTrips.Max(trip => trip.QuantityProduct) + 1; var numberOfPoints = fractionedScheduledTrips.Count + 1; var distancesAndDurations = GetDistancesAndDurations(depot, fractionedScheduledTrips, ceplexParameters.QuantityOfClients); ceplexParameters.Distance = distancesAndDurations.Item1; ceplexParameters.Duration = distancesAndDurations.Item2; ceplexParameters.VehicleCapacity = new int[ceplexParameters.QuantityOfVehiclesAvailable]; for (int i = 0; i < ceplexParameters.QuantityOfVehiclesAvailable; i++) { ceplexParameters.VehicleCapacity[i] = 10; } ceplexParameters.ClientsDemand = new double[ceplexParameters.QuantityOfClients]; for (int i = 0; i < ceplexParameters.QuantityOfClients; i++) { ceplexParameters.ClientsDemand[i] = fractionedScheduledTrips[i].QuantityProduct; } return(ceplexParameters); }
private int[][] GetRouteVehicleRoutingProblem(CeplexParameters ceplexParameters) { int[][] routeMatrix = new int[ceplexParameters.QuantityOfClients + 1][]; using (var reader = new StreamReader(ConfigurationManager.AppSettings["SOLUTION_VEHICLE_ROUTING_PROBLEM"])) { string solutionText = Task.Run(() => reader.ReadToEndAsync()).Result; for (int j = 0; j < ceplexParameters.QuantityOfClients + 1; j++) { routeMatrix[j] = new int[ceplexParameters.QuantityOfClients + 1]; for (int i = 0; i <= ceplexParameters.QuantityOfClients + 1; i++) { if (solutionText.Contains("x[" + (j + 1) + "][" + (i + 1) + "]")) { routeMatrix[j][i % 5] = 1; } else { routeMatrix[j][i % 5] = 0; } } } } return(routeMatrix); }
public int[][] FindOptimalSequenceForSubRoutes(CeplexParameters ceplexParameters) { bool optimalSolution; CreateDataFileVehicleRoutingProblem(ceplexParameters); CallSolver(LinearProgrammingProblems.VRP, out optimalSolution); return(GetRouteVehicleRoutingProblem(ceplexParameters)); }
private void CreateDataFileVehicleRoutingProblem(CeplexParameters ceplexParameters) { using (var writer = new StreamWriter(ConfigurationManager.AppSettings["DATA_FILE_VEHICLE_ROUTING_PROBLEM"])) { writer.Flush(); writer.WriteLine("QuantityOfClients = " + ceplexParameters.QuantityOfClients + ";"); double wtot = 0; writer.Write("ClientsDemand = [0,"); for (int i = 0; i < ceplexParameters.QuantityOfClients; i++) { if (i == (ceplexParameters.QuantityOfClients - 1)) { writer.Write(ceplexParameters.ClientsDemand[i]); } else { writer.Write(ceplexParameters.ClientsDemand[i] + ","); } wtot += ceplexParameters.ClientsDemand[i]; } writer.WriteLine("];"); writer.WriteLine("wtot = " + wtot + ";"); writer.WriteLine("Distance = ["); for (int j = 0; j < (ceplexParameters.QuantityOfClients + 1); j++) { writer.Write("["); for (int i = 0; i < (ceplexParameters.QuantityOfClients + 1); i++) { if (i == ceplexParameters.QuantityOfClients) { writer.Write(ceplexParameters.Distance[j][i]); } else { writer.Write(ceplexParameters.Distance[j][i] + ","); } } if (j == ceplexParameters.QuantityOfClients) { writer.Write("]" + Environment.NewLine); } else { writer.Write("]," + Environment.NewLine); } } writer.WriteLine("];"); } }
private CeplexParameters GetCeplexParametersVehicleRoutingProblem(Depot depot, VehicleRoute vehicleRoute) { var ceplexParametersVRP = new CeplexParameters(); ceplexParametersVRP.QuantityOfClients = vehicleRoute.SubRoutes.Count - 1; ceplexParametersVRP.ClientsDemand = new double[ceplexParametersVRP.QuantityOfClients]; for (int i = 0; i < ceplexParametersVRP.QuantityOfClients; i++) { ceplexParametersVRP.ClientsDemand[i] = vehicleRoute.SubRoutes[(i + 1)].DemandOrigin; } ceplexParametersVRP.Distance = new double[vehicleRoute.SubRoutes.Count][]; ceplexParametersVRP.Duration = new long[vehicleRoute.SubRoutes.Count][]; vehicleRoute.SubRoutes = vehicleRoute.SubRoutes.OrderBy(s => s.SequenceNumber).ToList(); for (int i = 0; i < vehicleRoute.SubRoutes.Count; i++) { ceplexParametersVRP.Distance[i] = new double[vehicleRoute.SubRoutes.Count]; ceplexParametersVRP.Duration[i] = new long[vehicleRoute.SubRoutes.Count]; for (int j = 0; j < vehicleRoute.SubRoutes.Count; j++) { vehicleRoute.SubRoutes[i].AddressOrigin.indexVRPDistanceMatrix = i; if (i == 0 && i != j) { var tupleDistanceDuration = _googleMapsRepository.GetDistanceBetweenTwoAddressesWithCache(depot.Address, vehicleRoute.SubRoutes[j].AddressOrigin); ceplexParametersVRP.Distance[i][j] = tupleDistanceDuration.Item1.Value; ceplexParametersVRP.Duration[i][j] = tupleDistanceDuration.Item2; } else if (i != 0 && i < j && i != j) { var tupleDistanceDuration = _googleMapsRepository.GetDistanceBetweenTwoAddressesWithCache( vehicleRoute.SubRoutes[i].AddressOrigin, vehicleRoute.SubRoutes[j].AddressDestiny); ceplexParametersVRP.Distance[i][j] = tupleDistanceDuration.Item1.Value; ceplexParametersVRP.Duration[i][j] = tupleDistanceDuration.Item2; } else if (i != 0 && i > j && i != j) { ceplexParametersVRP.Distance[i][j] = ceplexParametersVRP.Distance[j][i]; ceplexParametersVRP.Duration[i][j] = ceplexParametersVRP.Duration[j][i]; } else { ceplexParametersVRP.Distance[i][j] = 0; ceplexParametersVRP.Duration[i][j] = 0; } } } return(ceplexParametersVRP); }
private int GetIndexNearestAddress(int indexOrigin, CeplexParameters ceplexParameters, List <Address> addresses, List <int> indexesAlreadyVisited) { int indexDestiny = 0; double smallestDistance = double.MaxValue; for (int i = 0; i <= ceplexParameters.QuantityOfClients; i++) { if (i != indexOrigin && !indexesAlreadyVisited.Any(index => index == i) && smallestDistance > ceplexParameters.Distance[indexOrigin][i]) { smallestDistance = ceplexParameters.Distance[indexOrigin][i]; indexDestiny = i; } } return(indexDestiny); }
private void CreateDataFileMultipleVehicleRoutingProblem(CeplexParameters ceplexParameters) { using (var writer = new StreamWriter(ConfigurationManager.AppSettings["DATA_FILE_MULTIPLE_VEHICLE_ROUTING_PROBLEM"])) { writer.Flush(); writer.WriteLine("QuantityOfVehiclesAvailable = " + ceplexParameters.QuantityOfVehiclesAvailable + ";"); writer.WriteLine("QuantityOfClients = " + ceplexParameters.QuantityOfClients + ";"); writer.WriteLine("Time = ["); for (int j = 0; j < (ceplexParameters.QuantityOfClients + 1); j++) { writer.Write("["); for (int i = 0; i < (ceplexParameters.QuantityOfClients + 1); i++) { if (i == ceplexParameters.QuantityOfClients) { writer.Write(ceplexParameters.Distance[j][i]); } else { writer.Write(ceplexParameters.Distance[j][i] + ","); } } if (j == ceplexParameters.QuantityOfClients) { writer.Write("]" + Environment.NewLine); } else { writer.Write("]," + Environment.NewLine); } } writer.WriteLine("];"); writer.Write("VehiclesCapacity = ["); for (int i = 0; i < ceplexParameters.QuantityOfVehiclesAvailable; i++) { if (i == (ceplexParameters.QuantityOfVehiclesAvailable - 1)) { writer.Write(ceplexParameters.VehicleCapacity[i]); } else { writer.Write(ceplexParameters.VehicleCapacity[i] + ","); } } writer.WriteLine("];"); writer.WriteLine("VehiclesGreatestPossibleDemand = " + ceplexParameters.VehiclesGreatestPossibleDemand + ";"); writer.WriteLine("GreatestPossibleDemand = " + ceplexParameters.GreatestPossibleDemand + ";"); writer.Write("ClientsDemand = [0,"); for (int i = 0; i < ceplexParameters.QuantityOfClients; i++) { if (i == (ceplexParameters.QuantityOfClients - 1)) { writer.Write(ceplexParameters.ClientsDemand[i]); } else { writer.Write(ceplexParameters.ClientsDemand[i] + ","); } } writer.WriteLine("];"); writer.WriteLine("VehicleCost = 100000;"); } }
public int[][][] SolveFractionedTrips(CeplexParameters ceplexParameters, out bool optimalSolution) { CreateDataFileMultipleVehicleRoutingProblem(ceplexParameters); CallSolver(LinearProgrammingProblems.MVRP, out optimalSolution); return(GetRouteMultipleVehicleRoutingProblem(ceplexParameters)); }
public void GetOptimalSequenceOfClientsToVisit(Depot depot, VehicleRoute vehicleRoute, int[][] routeMatrix, CeplexParameters ceplexParameters, List <Address> addresses) { vehicleRoute.SubRoutes = new List <SubRoute>(); int sequenceNumber = 1; for (int j = 0; j <= ceplexParameters.QuantityOfClients; j++) { for (int i = 0; i <= ceplexParameters.QuantityOfClients; i++) { if (routeMatrix[j][i] == 1 && j != i && j == 0) { var subRoute = new SubRoute(); subRoute.AddressOriginId = depot.Address.AddressId; var addressDestiny = addresses.FirstOrDefault(a => a.indexVRPDistanceMatrix == i); subRoute.AddressDestinyId = addressDestiny.AddressId; subRoute.Distance = ceplexParameters.Distance[j][i]; subRoute.Duration = ceplexParameters.Duration[j][i].ConvertMinutesToDateTime(); subRoute.AddressOrigin = depot.Address; subRoute.AddressDestiny = addressDestiny; subRoute.SequenceNumber = sequenceNumber; sequenceNumber++; vehicleRoute.SubRoutes.Add(subRoute); } else if (routeMatrix[j][i] == 1 && j != i && j > 0 && i != 0) { var subRoute = new SubRoute(); var addressOrigin = addresses.FirstOrDefault(c => c.indexVRPDistanceMatrix == j); subRoute.AddressOriginId = addressOrigin.AddressId; var addressDestiny = addresses.FirstOrDefault(c => c.indexVRPDistanceMatrix == i); subRoute.AddressDestinyId = addressDestiny.AddressId; subRoute.Distance = ceplexParameters.Distance[j][i]; subRoute.Duration = ceplexParameters.Duration[j][i].ConvertMinutesToDateTime(); subRoute.AddressOrigin = addressOrigin; subRoute.AddressDestiny = addressDestiny; subRoute.SequenceNumber = sequenceNumber; sequenceNumber++; vehicleRoute.SubRoutes.Add(subRoute); } else if (routeMatrix[j][i] == 1 && j != i && j > 0 && i == 0) { var subRoute = new SubRoute(); var addressOrigin = addresses.FirstOrDefault(c => c.indexVRPDistanceMatrix == j); subRoute.AddressOriginId = addressOrigin.AddressId; subRoute.AddressDestinyId = depot.Address.AddressId; subRoute.Distance = ceplexParameters.Distance[j][i]; subRoute.Duration = ceplexParameters.Duration[j][i].ConvertMinutesToDateTime(); subRoute.AddressOrigin = addressOrigin; subRoute.AddressDestiny = depot.Address; subRoute.SequenceNumber = sequenceNumber; sequenceNumber++; vehicleRoute.SubRoutes.Add(subRoute); } } } }
private List <VehicleRoute> GetRoutesFindedMultipleVehicleRouteProblem(Depot depot, List <DeliveryTruckTrip> fractionedScheduledTrips, CeplexParameters ceplexParameters, int[][][] routeMatrix) { var routes = new List <VehicleRoute>(); for (int k = 0; k < ceplexParameters.QuantityOfVehiclesAvailable; k++) { var route = new VehicleRoute(); route.DepotId = depot.DepotId; route.DateCreation = DateTime.Now.Date; route.DateScheduled = DateTime.Now.Date; for (int j = 0; j <= ceplexParameters.QuantityOfClients; j++) { for (int i = 0; i <= ceplexParameters.QuantityOfClients; i++) { if (routeMatrix[k][j][i] == 1 && j != i && j == 0) { var subRoute = new SubRoute(); subRoute.AddressOriginId = depot.Address.AddressId; subRoute.DemandOrigin = 0; var clientDestiny = fractionedScheduledTrips.FirstOrDefault(c => c.ColumnIndex == i); subRoute.DemandDestiny = clientDestiny.QuantityProduct; subRoute.AddressDestinyId = clientDestiny.Address.AddressId; subRoute.Distance = ceplexParameters.Distance[j][i]; subRoute.Duration = ceplexParameters.Duration[j][i].ConvertMinutesToDateTime(); subRoute.AddressOrigin = depot.Address; subRoute.AddressDestiny = clientDestiny.Address; route.SubRoutes.Add(subRoute); } else if (routeMatrix[k][j][i] == 1 && j != i && j > 0 && i != 0) { var subRoute = new SubRoute(); var clientOrigin = fractionedScheduledTrips.FirstOrDefault(c => c.ColumnIndex == j); subRoute.DemandOrigin = clientOrigin.QuantityProduct; subRoute.AddressOriginId = clientOrigin.Address.AddressId; var clientDestiny = fractionedScheduledTrips.FirstOrDefault(c => c.ColumnIndex == i); subRoute.DemandDestiny = clientDestiny.QuantityProduct; subRoute.AddressDestinyId = clientDestiny.Address.AddressId; subRoute.Distance = ceplexParameters.Distance[j][i]; subRoute.Duration = ceplexParameters.Duration[j][i].ConvertMinutesToDateTime(); subRoute.AddressOrigin = clientOrigin.Address; subRoute.AddressDestiny = clientDestiny.Address; route.SubRoutes.Add(subRoute); } else if (routeMatrix[k][j][i] == 1 && j != i && j > 0 && i == 0) { var subRoute = new SubRoute(); var clientOrigin = fractionedScheduledTrips.FirstOrDefault(c => c.ColumnIndex == j); subRoute.DemandOrigin = clientOrigin.QuantityProduct; subRoute.AddressOriginId = clientOrigin.Address.AddressId; subRoute.DemandDestiny = 0; subRoute.AddressDestinyId = depot.Address.AddressId; subRoute.Distance = ceplexParameters.Distance[j][i]; subRoute.Duration = ceplexParameters.Duration[j][i].ConvertMinutesToDateTime(); subRoute.AddressOrigin = clientOrigin.Address; subRoute.AddressDestiny = depot.Address; route.SubRoutes.Add(subRoute); } } } if (route.SubRoutes.Count > 0) { routes.Add(route); } } return(routes); }
private void PostProcessWithMinimumPathAlgorithm(Depot depot, VehicleRoute vehicleRoute, CeplexParameters ceplexParameters, List <Address> addresses) { vehicleRoute.SubRoutes = new List <SubRoute>(); int i = 0; int indexOrigin = 0; int indexDestiny = 0; List <int> indexesAlreadyVisited = new List <int>(); indexesAlreadyVisited.Add(0); while (i <= ceplexParameters.QuantityOfClients) { if (i == 0) { var subRoute = new SubRoute(); subRoute.AddressOriginId = depot.Address.AddressId; indexDestiny = GetIndexNearestAddress(i, ceplexParameters, addresses, indexesAlreadyVisited); var addressDestiny = addresses.FirstOrDefault(a => a.indexVRPDistanceMatrix == indexDestiny); subRoute.AddressDestinyId = addressDestiny.AddressId; subRoute.Distance = ceplexParameters.Distance[0][addressDestiny.indexVRPDistanceMatrix]; subRoute.Duration = ceplexParameters.Duration[0][addressDestiny.indexVRPDistanceMatrix].ConvertMinutesToDateTime(); subRoute.AddressOrigin = depot.Address; subRoute.AddressDestiny = addressDestiny; vehicleRoute.SubRoutes.Add(subRoute); } else if (i == ceplexParameters.QuantityOfClients) { var subRoute = new SubRoute(); var addressOrigin = addresses.FirstOrDefault(a => a.indexVRPDistanceMatrix == indexOrigin); subRoute.AddressOriginId = addressOrigin.AddressId; subRoute.AddressDestinyId = depot.Address.AddressId; subRoute.Distance = ceplexParameters.Distance[indexOrigin][0]; subRoute.Duration = ceplexParameters.Duration[indexOrigin][0].ConvertMinutesToDateTime(); subRoute.AddressOrigin = addressOrigin; subRoute.AddressDestiny = depot.Address; vehicleRoute.SubRoutes.Add(subRoute); } else { var subRoute = new SubRoute(); var addressOrigin = addresses.FirstOrDefault(a => a.indexVRPDistanceMatrix == indexOrigin); subRoute.AddressOriginId = addressOrigin.AddressId; indexDestiny = GetIndexNearestAddress(indexOrigin, ceplexParameters, addresses, indexesAlreadyVisited); var addressDestiny = addresses.FirstOrDefault(a => a.indexVRPDistanceMatrix == indexDestiny); subRoute.AddressDestinyId = addressDestiny.AddressId; subRoute.Distance = ceplexParameters.Distance[indexOrigin][addressDestiny.indexVRPDistanceMatrix]; subRoute.Duration = ceplexParameters.Duration[indexOrigin][addressDestiny.indexVRPDistanceMatrix].ConvertMinutesToDateTime(); subRoute.AddressOrigin = addressOrigin; subRoute.AddressDestiny = addressDestiny; vehicleRoute.SubRoutes.Add(subRoute); } indexesAlreadyVisited.Add(indexDestiny); indexOrigin = indexDestiny; i++; } }