public RouteAssignment assignMultipleRoutes(List <Route> routes, List <Driver> drivers) { var tempRouteData = new List <TempRoute>(); List <Driver> alreadyAssignedDriversForADay = new List <Driver>(); List <Driver> driversAlreadyAssignedARouteThisSession = new List <Driver>(); Route prevRoute = null; List <Route> sortedRoutes = routes.OrderByDescending(r => r.DeliverBy).ToList(); foreach (Route route in sortedRoutes) { if (prevRoute != null && !prevRoute.DeliverBy.Equals(route.DeliverBy)) { alreadyAssignedDriversForADay.Clear(); } DriverAssignmentResult assignmentResult = getBestDriverForRoute(route, drivers, alreadyAssignedDriversForADay, driversAlreadyAssignedARouteThisSession, route.DeliverBy); TempRoute parameters = new TempRoute(); parameters.DriversVehicle = assignmentResult.Vehicle; parameters.ModifiedDeliverByDate = assignmentResult.DeliverByDate; parameters.Driver = assignmentResult.Driver; parameters.RouteId = route.ID; alreadyAssignedDriversForADay.Add(assignmentResult.Driver); tempRouteData.Add(parameters); prevRoute = route; driversAlreadyAssignedARouteThisSession.Add(assignmentResult.Driver); } RouteAssignment assignemnt = new RouteAssignment(); assignemnt.Routes = routes; assignemnt.TempRouteData = tempRouteData; return(assignemnt); }
public DriverAssignmentResult getBestDriverForRoute(Route route, List <Driver> drivers, List <Driver> unavailableDrivers, List <Driver> driversAlreadyAssignedRoutesInThisSession, DateTime DeliverBy) { DriverAssignmentResult[] assignmentCosts = new DriverAssignmentResult[drivers.Count()]; List <Driver> copyOfUnavailableDrivers = unavailableDrivers.ToList(); List <Driver> sortedDriverList = sortDiversInTheOrderOfBusiness(drivers.ToList(), copyOfUnavailableDrivers); foreach (Driver driver in sortedDriverList) { if (!unavailableDrivers.Contains(driver)) { DriverAssignmentResult result = getCostForDriverBeingAssignedToRoute(driver, route, DeliverBy); assignmentCosts[drivers.IndexOf(driver)] = result; } else { DriverAssignmentResult result = new DriverAssignmentResult(); result.DeliverByDate = DeliverBy; result.RouteID = route.ID; assignmentCosts[drivers.IndexOf(driver)] = result; } } List <DriverAssignmentResult> results = assignmentCosts.OrderByDescending(i => i.AssignmentProfit).ToList(); DriverAssignmentResult maxValueResult = results.FirstOrDefault(); if (maxValueResult != null && maxValueResult.AssignmentProfit != 0) { var result = getBestResult(results, driversAlreadyAssignedRoutesInThisSession); if (result == null) { return(maxValueResult); //if everyone has been assigned smth, then we can only select the one that is the best in terms of profit } else { return(result); } } else { if (numberOfTries < 3) { numberOfTries++; DateTime deliverBy = route.DeliverBy.AddDays(-numberOfTries); return(getBestDriverForRoute(route, drivers, unavailableDrivers, driversAlreadyAssignedRoutesInThisSession, deliverBy)); } else { DriverAssignmentResult result = new DriverAssignmentResult(); result.DeliverByDate = route.DeliverBy; result.RouteID = route.ID; return(result); } } }
public void testDriverSelectionWhenBothDriversAreNotAvailable() { Driver driverOne = new Driver(); driverOne.Address = new DriverAddress(); Vehicle vehicleOne = new Vehicle(300, 100, 109, 100); driverOne.Vehicles.Add(vehicleOne); Route driverRoute = new Route(); driverRoute.DeliverBy = new DateTime(2015, 12, 12); driverOne.Routes.Add(driverRoute); Driver driverTwo = new Driver(); driverTwo.Address = new DriverAddress(); driverTwo.Vehicles.Add(vehicleOne); driverTwo.Address = (DriverAddress)getAddress(true); List <Driver> drivers = new List <Driver> { driverOne, driverTwo }; driverTwo.Routes.Add(driverRoute); var responseMessageOne = new HttpResponseMessage(); responseMessageOne.Content = new StringContent("{\"destination_addresses\":[\"Village Way, Brighton BN1, United Kingdom\"],\"origin_addresses\":[\"Arts Rd, Falmer, Brighton BN1 9QN, United Kingdom\"],\"rows\":[{\"elements\":[{\"distance\":{\"text\":\"0.8 mi\",\"value\":2},\"duration\":{\"text\":\"4 min\",\"value\":235},\"status\":\"OK\"}]}],\"status\":\"OK\"}"); var responseMessageTwo = new HttpResponseMessage(); responseMessageTwo.Content = new StringContent("{\"destination_addresses\":[\"Village Way, Brighton BN1, United Kingdom\"],\"origin_addresses\":[\"Arts Rd, Falmer, Brighton BN1 9QN, United Kingdom\"],\"rows\":[{\"elements\":[{\"distance\":{\"text\":\"3.6 mi\",\"value\":10},\"duration\":{\"text\":\"4 min\",\"value\":235},\"status\":\"OK\"}]}],\"status\":\"OK\"}"); List <HttpResponseMessage> responses = new List <HttpResponseMessage> { responseMessageOne, responseMessageTwo }; TestGoogleMapsUtil googleMaps = new TestGoogleMapsUtil(responses); Route route = new Route(); route.DeliverBy = new DateTime(2015, 12, 13); route.PickUpAddress = (PickUpAddress)getAddress(false); Delivery delivery = new Delivery(); delivery.ItemWeight = 20; delivery.ItemSize = ItemSize.Small; route.Deliveries.Add(delivery); LocationService locationService = new LocationService(googleMaps); DriverAssignmentService assignmentService = new DriverAssignmentService(locationService); DriverAssignmentResult result = assignmentService.getBestDriverForRoute(route, drivers, new List <Driver>(), new List <Driver>(), new DateTime(2015, 12, 12)); Assert.Equal(result.Driver, driverOne); Assert.Equal(result.DeliverByDate, new DateTime(2015, 12, 13)); }
private DriverAssignmentResult getBestResult(List <DriverAssignmentResult> results, List <Driver> alreadyBusyDrivers) { DriverAssignmentResult firstResult = results.FirstOrDefault(); if (firstResult != null && firstResult.AssignmentProfit != 0 && !alreadyBusyDrivers.Contains(firstResult.Driver)) { return(firstResult); } else if (results.Count() >= 1) { return(getBestResult(results.GetRange(1, results.Count() - 1), alreadyBusyDrivers)); } else { return(null); } }
private DriverAssignmentResult getCostForDriverBeingAssignedToRoute(Driver driver, Route route, DateTime DeliverBy) { double profit = 0; DriverAssignmentResult result = new DriverAssignmentResult(route.ID, route.DeliverBy, driver); if (driverIsOnHoliday(driver, DeliverBy)) { result.AssignmentProfit = 0; return(result); } //if there is already a delivery on a day before deliveryby day if (driver.Routes.Where(r => r.DeliverBy.Equals(DeliverBy.AddDays(-1))).ToList().Count() != 0) { // return 0; //ifdriver is not available on a day, no need to check other result.AssignmentProfit = 0; return(result); } else { profit += 5; } double weightOfDeliveriesInRoute = 0; double capacityOfBoxes = 0; for (int i = 0; i < route.Deliveries.Count(); i++) { Delivery delivery = route.Deliveries.ElementAt(i); weightOfDeliveriesInRoute += delivery.ItemWeight; capacityOfBoxes += calculateCapacity(ItemSizeDimensionsExtension.getItemDimensionsBasedOnSize(delivery.ItemSize)); } Vehicle suitableVehicle = null; for (int i = 0; i < driver.Vehicles.Count(); i++) { Vehicle vehicle = driver.Vehicles.ElementAt(i); if (capacityOfBoxes <= calculateCapacity(new DeliveryItemDimensions(vehicle.Height, vehicle.Width, vehicle.Length)) && vehicle.MaxLoad >= weightOfDeliveriesInRoute) { suitableVehicle = vehicle; break; } } //add 0 weight if there is no if (suitableVehicle == null) { result.AssignmentProfit = 0; return(result); //if no vehicle available then no point looking further } else { result.Vehicle = suitableVehicle; profit += 5; } var distanceFromDepotLocation = locationService.getDistanceBetweenTwoAddresses(driver.Address, route.PickUpAddress).Result; profit += 100 / distanceFromDepotLocation; result.AssignmentProfit = profit; return(result); }