def FisherJaikumar_Routing(graph, clusterAssignment, k_clusters, saveFolder): routes = [] demand = graph.getDemand() capacity = graph.getCapacity() for k in range(len(k_clusters)): cluster = [] for i in range(len(clusterAssignment)): if (clusterAssignment[i] == k): cluster.append(i + 1) appoRoute = Route(capacity) appoRoute.addCustomer(0, 0, False) while (len(cluster) > 0): prevnode = appoRoute.getCustomers()[len(appoRoute.getCustomers()) - 1] distPrevNode = graph.getValue(prevnode, [c for c in cluster]) nearestN = cluster[np.argmin(distPrevNode)] if nearestN not in appoRoute.getCustomers(): appoRoute.addCustomer(nearestN, demand[nearestN], False) cluster.remove(nearestN) appoRoute.addCustomer(0, 0, False) appoRoute.printRoute("Route cluster:" + str(k)) routes.append(appoRoute) return routes
def LocalSearch_FlippingPath(route: Route, graph: cvrpGraph, candidate1, candidate2): node1 = candidate1 % len(route.getCustomers()) node2 = candidate2 % len(route.getCustomers()) if (node2 != 0): firstCandidate = route.getCustomers()[node1] prevfc = route.getCustomers()[node1 - 1] nextfc = route.getCustomers()[node1 + 1] secondCandidate = route.getCustomers()[node2] prevsc = route.getCustomers()[node2 - 1] nextsc = route.getCustomers()[node2 + 1] cost1 = graph.getValue(prevfc, firstCandidate) + graph.getValue( firstCandidate, nextfc) cost2 = graph.getValue(prevsc, secondCandidate) + graph.getValue( secondCandidate, nextsc) route.setCost(route.getCost() - (cost1 + cost2)) a = route.getCustomers().index(firstCandidate) b = route.getCustomers().index(secondCandidate) route.getCustomers()[a] = secondCandidate route.getCustomers()[b] = firstCandidate cost3 = graph.getValue(prevfc, secondCandidate) + graph.getValue( secondCandidate, nextfc) cost4 = graph.getValue(prevsc, firstCandidate) + graph.getValue( firstCandidate, nextsc) route.setCost(route.getCost() + (cost3 + cost4)) return route
def Crossover(winner1, winner2, graph: cvrpGraph, tabuSearch: bool = False, tabuLister: list = []): demand = graph.getDemand() capacity = graph.getCapacity() tabuList = tabuLister winner1Sequence = [] winner2Sequence = [] child1 = [] child2 = [] solution1 = [] solution2 = [] winner1Sequence += [p.getCustomers() for p in winner1] winner1Sequence = [y for x in winner1Sequence for y in x if y != 0] winner2Sequence += [p.getCustomers() for p in winner2] winner2Sequence = [y for x in winner2Sequence for y in x if y != 0] crossover_point1 = np.random.randint(int(len(winner1Sequence) / 4), (int(len(winner1Sequence) / 2))) crossover_point2 = np.random.randint( int(len(winner1Sequence) / 2), (int(len(winner1Sequence) / 2) + int(len(winner1Sequence) / 4))) #Form child one List for node in (winner1Sequence[crossover_point1:crossover_point2]): if node not in child1 and node != 0: child1.append(node) for node in (winner2Sequence[crossover_point2:]): if node not in child1 and node != 0: child1.append(node) for node in (winner2Sequence[:crossover_point2]): if node not in child1 and node != 0: child1.insert(0, node) #Build and check the child one Route i = 0 while (i < len(child1)): route = Route(capacity) cost = 0 route.setCost(0) route.addCustomer(0, demand[0], False) for node in child1[i:]: i = i + 1 if (route.addCustomer(node, demand[node], False) < 0): if (route.checkCustomer(node) == -1): route.addCustomer(0, demand[0], False) i = i - 1 break if (len(child1) == i): route.addCustomer(0, demand[0], False) for n in range(len(route.getCustomers()) - 1): cost += graph.getValue(route.getCustomers()[n], route.getCustomers()[n + 1]) route.setCost(cost) solution1.append(route) #Form child two List for node2 in (winner2Sequence[crossover_point1:crossover_point2]): if node2 not in child2 and node2 != 0: child2.append(node2) for node2 in (winner1Sequence[crossover_point2:]): if node2 not in child2 and node2 != 0: child2.append(node2) for node2 in (winner1Sequence[:crossover_point2]): if node2 not in child2 and node2 != 0: child2.append(node2) #Build and check the child one Route i = 0 while (i < len(child2)): route2 = Route(capacity) cost = 0 route2.setCost(0) route2.addCustomer(0, demand[0], True) for node in child2[i:]: i = i + 1 if (route2.addCustomer(node, demand[node], False) < 0): route2.addCustomer(0, demand[0], False) i = i - 1 break if (len(child2) == i): route2.addCustomer(0, demand[0], False) for n in range(len(route2.getCustomers()) - 1): cost += graph.getValue(route2.getCustomers()[n], route2.getCustomers()[n + 1]) route2.setCost(cost) solution2.append(route2) f1 = sum([c.getCost() for c in solution1]) f2 = sum([c.getCost() for c in solution2]) tabuState = [] if (f1 > f2): tabuState = f1 else: tabuState = f2 if (tabuSearch == True and int(tabuState) in tabuList): #print("TABULISTED ==> " +str(int(tabuState))) return Crossover(winner1, winner2, graph, tabuList) else: tabuList.append(int(tabuState)) if (f1 < f2): return solution1, tabuList, f1 else: return solution2, tabuList, f2
def ClusterFirst_RouteSecond(graph, saveFolder): finalRoutes = [] capacity = graph.getCapacity() demand = graph.getDemand() dimension = graph.getDimension() dist = [np.inf for i in range(dimension)] nodeQueue = [] auxGraph = [(i, Route(capacity)) for i in range(dimension)] #Source Node has 0 cost, in this case route Depot - 1- Depot dist[0] = 0 #nodeQueue = [(c+1,dist[c]) for c in range(len(dist))] route = Route(capacity) route.addCustomer(0, demand[0], False) route.addCustomer(1, demand[1], False) route.addCustomer(0, demand[0], False) route.setCost(graph.getValue(0, 1) + graph.getValue(1, 0)) nodeQueue = [(1, route.getCost(), route)] node = 0 nodeQueue.sort(key=lambda x: x[1], reverse=True) while len(nodeQueue) > 0: #Give the node in the auxiliary graph that has low cost nodeToexpand = nodeQueue.pop() node = nodeToexpand[0] cost = nodeToexpand[1] #Give the corresponding route, that contain node #auxGraph.pop() #Create each child of the node in the auxiliary graph for j in range(1, dimension): #j child if (j >= node): newRoute = Route(capacity) newRoute.setCost(0) newRoute.addCustomer(0, demand[0], False) control = -3 #for each child that not exceed the truck capacity for i in range(node, j + 1): #The not is not in the route and it not exceed the truck capacity #Add Node if (newRoute.checkCustomer(i) == -1): control = newRoute.addCustomer(i, demand[i], False) #Update Cost if (control > 0): newRoute.setCost( newRoute.getCost() + graph.getValue( newRoute.getCustomers()[node - i], i)) else: break #Close the route if (control > 0): newRoute.setCost(newRoute.getCost() + graph.getValue(j, 0)) newRoute.addCustomer(0, demand[0], False) if (dist[j] > newRoute.getCost() + cost): dist[j] = newRoute.getCost() + cost nodeQueue.append((j + 1, dist[j], newRoute)) auxGraph[j] = (node - 1, newRoute) nodeQueue.sort(key=lambda x: x[1], reverse=True) else: break u = len(auxGraph) - 1 while (u != 0): node = auxGraph[u] u = node[0] finalRoutes.append(node[1]) return finalRoutes
def Sequential_CW(routes, savings, graph: cvrpGraph): capacity = graph.getCapacity() demand = graph.getDemand() toDo, checked, _ = SearchaAndCompleteSequence(routes, graph, True) #no routes have been created yet while (SearchaAndCompleteSequence(routes, graph) == True and len(savings) > 0): routeSelected = Route(capacity) printable = savings.copy() k = 0 saveNow = savings[0] l = saveNow[1] m = saveNow[2] if ((l not in checked) and (m not in checked) and (len(routeSelected.getCustomers()) == 0)): #No one served i and j so this route will be teh first routeSelected.addCustomer(l, demand[l], True) routeSelected.addCustomer(m, demand[m], False) savings.remove(saveNow) while k < len(savings): save = savings[k] k = k + 1 i = save[1] j = save[2] customerI = -1 customerJ = -1 toprint = save if (toDo == True): #Check if someone alraedy served i and j if ((i not in checked) and (j not in checked)): if (-2 < customerI < 0 and len(routeSelected.getCustomers()) > 0): customerI = routeSelected.checkCustomer(i) if (-2 < customerJ < 0 and len(routeSelected.getCustomers()) > 0): customerJ = routeSelected.checkCustomer(j) # case: i and j have not been served and they are not route first entry #customer i is served from this route but j is not. if (customerI >= 0 and customerJ == -1): if (customerI == 0): control = routeSelected.addCustomer( j, demand[j], True) if (control != -1): savings.remove(save) k = 0 else: control = routeSelected.addCustomer( j, demand[j], False) if (control != -1): savings.remove(save) k = 0 #customer j is served from this route but i is not. if (customerI == -1 and customerJ >= 0): if (customerJ == 0): control = routeSelected.addCustomer( i, demand[i], True) if (control != -1): savings.remove(save) k = 0 else: control = routeSelected.addCustomer( i, demand[i], False) if (control != -1): savings.remove(save) k = 0 print("Savings number :" + str(printable.index(toprint))) routes.append(routeSelected) routeCost = 0 for i in range(len(routeSelected.getCustomers()) - 1): routeCost += graph.getValue( routeSelected.getCustomers()[i], routeSelected.getCustomers()[i + 1]) routeSelected.setCost(routeCost) toDo, checked, _ = SearchaAndCompleteSequence(routes, graph, True) savings.append((float( graph.getValue(i, 0) + graph.getValue(0, j) - routeSelected.getCost()), i, j)) savings.sort(key=lambda x: x[0], reverse=True) else: savings.remove(saveNow) return routes