def solve(self, only_one_const, order_const, capacity_const, solver_type='qbsolv', num_reads=50): problem = self.problem capacity = 0 weights = problem.weights for w in weights: capacity += w # Creating new problem with one vehicle sources = [0] dests = problem.dests costs = problem.costs time_costs = problem.time_costs new_capacities = [capacity] new_problem = VRPProblem(sources, costs, time_costs, new_capacities, dests, weights) if len(dests) == 0: sol = [[] for _ in range(len(problem.capacities))] return VRPSolution(problem, None, None, sol) solver = self.solver solver.set_problem(new_problem) solution = solver.solve(only_one_const, order_const, capacity_const, solver_type=solver_type, num_reads=num_reads) sol = solution.solution[0] return self._divide_solution_random(sol)
def read_test(path, capacity=True): in_file = open(path, 'r') magazines_num = int(in_file.readline()) dests_num = int(in_file.readline()) nodes_num = magazines_num + dests_num # Reading weights of destinations. weights = np.zeros((nodes_num), dtype=int) if capacity: w = [int(s) for s in in_file.readline().split() if s.isdigit()] for i in range(dests_num): weights[i + magazines_num] = w[i] # Reading costs. costs = np.zeros((nodes_num, nodes_num), dtype=int) for i in range(nodes_num): costs[i] = [int(s) for s in in_file.readline().split() if s.isdigit()] # Reading vehicles. vehicles = int(in_file.readline()) capacities = np.ones((vehicles), dtype=int) if capacity: capacities = [ int(s) for s in in_file.readline().split() if s.isdigit() ] in_file.close() sources = [i for i in range(magazines_num)] dests = [i for i in range(magazines_num, nodes_num)] return VRPProblem(sources, costs, capacities, dests, weights)
def read_full_test(path, graph_path, capacity=True): graph = create_graph_from_csv(graph_path) in_file = open(path, 'r') nodes_id = list() # Reading magazines. next(in_file) nodes_id = [int(s) for s in in_file.readline().split() if s.isdigit()] magazines_num = len(nodes_id) # Reading destinations. dests_num = int(in_file.readline()) nodes_num = dests_num + magazines_num weights = np.zeros((nodes_num), dtype=int) for i in range(dests_num): order = in_file.readline().split() dest = int(order[0]) nodes_id.append(dest) if capacity: weight = int(order[1]) weights[i + magazines_num] = weight # Reading vehicles. vehicles = int(in_file.readline()) capacities = np.ones((vehicles), dtype=int) if capacity: capacities = [ int(s) for s in in_file.readline().split() if s.isdigit() ] # Generating costs matrix. costs = np.zeros((nodes_num, nodes_num), dtype=int) for i in range(nodes_num): source = nodes_id[i] _, paths = nx.single_source_dijkstra(graph, source, weight='cost') for j in range(nodes_num): d = nodes_id[j] path = paths[d] prev = source for node in path[1:]: edge = graph.get_edge_data(prev, node) costs[i][j] += edge['cost'] prev = node in_file.close() sources = [i for i in range(magazines_num)] dests = [i for i in range(magazines_num, nodes_num)] return VRPProblem(sources, costs, capacities, dests, weights)
# Problem parameters sources = test['sources'] costs = test['costs'] time_costs = test['time_costs'] capacities = test['capacities'] dests = test['dests'] weigths = test['weights'] time_windows = test['time_windows'] only_one_const = 10000000. order_const = 1. capacity_const = 0. #not important in this example time_const = 0. #not important in this example problem = VRPProblem(sources, costs, time_costs, capacities, dests, weigths, time_windows) solver = SolutionPartitioningSolver( problem, DBScanSolver(problem, anti_noiser=False, MAX_LEN=10)) #problem = VRPTWProblem(sources, costs, time_costs, capacities, dests, weigths, time_windows) #vrp_solver = SolutionPartitioningSolver(problem, DBScanSolver(problem, anti_noiser = False)) #solver = MergingTimeWindowsVRPTWSolver(problem, vrp_solver) result = solver.solve(only_one_const, order_const, capacity_const, solver_type='qbsolv', num_reads=500) if result == None: print("Niestety coś poszło nie tak :(\n")
def solve(self, only_one_const, order_const, capacity_const, solver_type = 'qbsolv', num_reads = 50): problem = self.problem vrp_solver = self.solver time_windows = problem.time_windows time_costs = problem.time_costs dests = problem.dests dests_blocks = dict() weights = problem.weights original_capacities = problem.capacities.copy() min_time = self.INF max_time = 0 for dest in dests: time = time_windows[dest] min_time = min(time, min_time) max_time = max(time, max_time) for time in range(min_time, max_time + 1, self.TIME_WINDOWS_DIFF): dests_blocks[time] = list() for dest in dests: time = time_windows[dest] dests_blocks[time].append(dest) solution = None for time in range(min_time, max_time + 1, self.TIME_WINDOWS_DIFF): dests = dests_blocks[time] if dests == []: continue # Counting time limits. time_limits = [time + self.TIME_WINDOW_RADIUS for _ in range(len(original_capacities))] if solution != None: it = 0 for sol in solution: if sol == []: continue prev = sol[0] for dest in sol: time_limits[it] -= time_costs[prev][dest] prev = dest it += 1 time_limits = [min(2. * self.TIME_WINDOW_RADIUS, t) for t in time_limits] first_source = (time == min_time) last_source = (time == max_time) vrp_problem = VRPProblem([problem.source], problem.costs, problem.time_costs, problem.capacities, dests, problem.weights, first_source = first_source, last_source = last_source) vrp_solver.set_problem(vrp_problem) vrp_solver.time_limits = time_limits next_sol = vrp_solver.solve(only_one_const, order_const, capacity_const, solver_type = solver_type, num_reads = num_reads) if next_sol == None: return None next_solution = next_sol.solution if time != min_time: next_solution = [sol[1:] for sol in next_solution] if time != max_time: next_solution = [sol[:-1] for sol in next_solution] if time == min_time or time == max_time: next_solution = [sol if sol != [] else [0] for sol in next_solution] problem.capacities = original_capacities.copy() solution = self._merge_all(solution, next_solution, time - self.TIME_WINDOW_RADIUS) # Changing capacities. it = 0 for sol in solution: cap = original_capacities[it] for dest in sol: cap -= weights[dest] problem.capacities[it] = cap it += 1 solution = [sol if sol != [0, 0] else [] for sol in solution] problem.capacities = original_capacities return VRPTWSolution(problem, None, None, solution)
def solve(self, only_one_const, order_const, capacity_const, solver_type='qbsolv', num_reads=50): problem = self.problem dests = problem.dests costs = problem.costs time_costs = problem.time_costs sources = [problem.source] capacities = problem.capacities weights = problem.weights vehicles = len(problem.capacities) # TODO : Is that correct? if len(dests) == 0: return VRPSolution(problem, None, None, [[]]) # Some idea #if len(dests) <= self.MAX_LEN: # solver = AveragePartitionSolver(problem) # result = solver.solve(only_one_const, order_const, capacity_const, # solver_type = solver_type, num_reads = num_reads).solution # return VRPSolution(problem, None, None, result) clusters = self._recursive_dbscan(dests, costs, 0., self.MAX_DIST, vehicles, self.MAX_LEN, 1000) if len(clusters) == vehicles: result = list() for cluster in clusters: new_problem = VRPProblem(sources, costs, time_costs, [capacities[0]], cluster, weights) solver = FullQuboSolver(new_problem) solution = solver.solve(only_one_const, order_const, capacity_const, solver_type=solver_type, num_reads=num_reads).solution[0] result.append(solution) return VRPSolution(problem, None, None, result) solutions = list() solutions.append(VRPSolution(problem, None, None, [[0]])) for cluster in clusters: new_problem = VRPProblem(sources, costs, time_costs, [capacities[0]], cluster, weights, first_source=False, last_source=False) solver = FullQuboSolver(new_problem) solution = solver.solve(only_one_const, order_const, capacity_const, solver_type=solver_type, num_reads=num_reads) solutions.append(solution) clusters_num = len(clusters) + 1 new_dests = [i for i in range(1, clusters_num)] new_costs = np.zeros((clusters_num, clusters_num), dtype=float) new_time_costs = np.zeros((clusters_num, clusters_num), dtype=float) new_weights = np.zeros((clusters_num), dtype=int) for (i, j) in product(range(clusters_num), range(clusters_num)): if i == j: new_costs[i][j] = 0 time_costs[i][j] = 0 continue id1 = solutions[i].solution[0][-1] id2 = solutions[j].solution[0][0] new_costs[i][j] = costs[id1][id2] new_time_costs[i][j] = solutions[j].all_time_costs( )[0] + time_costs[id1][id2] for i in range(clusters_num): for dest in solutions[i].solution[0]: new_weights[i] += weights[dest] new_problem = VRPProblem(sources, new_costs, new_time_costs, capacities, new_dests, new_weights) solver = DBScanSolver(new_problem) compressed_solution = solver.solve(only_one_const, order_const, capacity_const, solver_type=solver_type, num_reads=num_reads).solution uncompressed_solution = list() for vehicle_dests in compressed_solution: uncompressed = list() for dest in vehicle_dests: uncompressed += solutions[dest].solution[0] uncompressed_solution.append(uncompressed) return VRPSolution(problem, None, None, uncompressed_solution)
def solve(self, only_one_const, order_const, solver_type='cpu'): problem = self.problem dests = problem.dests costs = problem.costs sources = [problem.source] capacities = problem.capacities weights = problem.weights vehicles = len(problem.capacities) if len(dests) == 0: return VRPSolution(problem, None, None, [[]]) clusters = self._recursive_dbscan(dests, costs, 0., self.max_dist, vehicles, self.max_len, self.max_weight) # If we have as much small clusters as vehicles, we can solve TSP for every cluster. if len(clusters) == vehicles: result = list() for cluster in clusters: new_problem = VRPProblem(sources, costs, [capacities[0]], cluster, weights) solver = FullQuboSolver(new_problem) solution = solver.solve(only_one_const, order_const, solver_type=solver_type).solution[0] result.append(solution) return VRPSolution(problem, None, None, result) solutions = list() solutions.append(VRPSolution(problem, None, None, [[0]])) # Solving TSP for every cluster. for cluster in clusters: new_problem = VRPProblem(sources, costs, [capacities[0]], cluster, weights, first_source=False, last_source=False) solver = FullQuboSolver(new_problem) solution = solver.solve(only_one_const, order_const, solver_type=solver_type) solutions.append(solution) # Creating smaller instance of problem for DBScanSolver. clusters_num = len(clusters) + 1 new_dests = [i for i in range(1, clusters_num)] new_costs = np.zeros((clusters_num, clusters_num), dtype=float) new_weights = np.zeros((clusters_num), dtype=int) for (i, j) in product(range(clusters_num), range(clusters_num)): if i == j: new_costs[i][j] = 0 continue id1 = solutions[i].solution[0][-1] id2 = solutions[j].solution[0][0] new_costs[i][j] = costs[id1][id2] for i in range(clusters_num): for dest in solutions[i].solution[0]: new_weights[i] += weights[dest] new_problem = VRPProblem(sources, new_costs, capacities, new_dests, new_weights) solver = DBScanSolver(new_problem) compressed_solution = solver.solve(only_one_const, order_const, solver_type=solver_type).solution # Achieving full solution from solution of smaller version. uncompressed_solution = list() for vehicle_dests in compressed_solution: uncompressed = list() for dest in vehicle_dests: uncompressed += solutions[dest].solution[0] uncompressed_solution.append(uncompressed) return VRPSolution(problem, None, None, uncompressed_solution)