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 _merge_all(self, first_solution, second_solution, time): if first_solution == None: return second_solution capacities = self.problem.capacities # Finding best matching. size = len(first_solution) matching_costs = np.zeros((size, size), dtype=int) for (i, j) in product(range(size), range(size)): merging = self._merge_one(first_solution[i], second_solution[j], time, capacities[i]) weight = 0 if merging == []: weight = self.INF else: weight = VRPSolution(self.problem, None, None, solution = [merging]).total_cost() matching_costs[i][j] = weight row_matching, col_matching = linear_sum_assignment(matching_costs) mates = np.zeros((size), dtype=int) for i in range(size): mates[i] = col_matching[i] result = list() for i in range(size): mate = mates[i] merging = self._merge_one(first_solution[i], second_solution[mate], time, capacities[i]) result.append(merging) return result
def solve(self, only_one_const, order_const, capacity_const, solver_type='qbsolv', num_reads=50, limit_radius=1): dests = len(self.problem.dests) vehicles = len(self.problem.capacities) avg = int(dests / vehicles) limits = [(max(avg - limit_radius, 0), min(avg + limit_radius, dests)) for _ in range(vehicles)] max_limits = [r for (_, r) in limits] vrp_qubo = self.problem.get_qubo_with_both_limits( limits, only_one_const, order_const, capacity_const) samples = DWaveSolvers.solve_qubo(vrp_qubo, solver_type=solver_type, num_reads=num_reads) sample = samples[0] solution = VRPSolution(self.problem, sample, max_limits) return solution
def _divide_solution_greedy(self, solution): solution = solution[1:-1] problem = self.problem capacities = problem.capacities costs = problem.costs weights = problem.weights new_solution = [] pointer = 0 dests = len(solution) for cap in reversed(capacities): actual_cap = cap sub_dests = [] if pointer != dests: sub_dests = [0] while pointer < dests and actual_cap >= weights[solution[pointer]]: actual_cap -= weights[solution[pointer]] sub_dests.append(solution[pointer]) pointer += 1 if len(sub_dests) > 0: sub_dests.append(0) new_solution.append(sub_dests) new_solution.reverse() return VRPSolution(problem, None, None, new_solution)
def _divide_solution_greedy_dp(self, solution): problem = self.problem capacities = problem.capacities time_limits = self.time_limits costs = problem.costs time_costs = problem.time_costs weights = problem.weights dests = len(solution) vehicles = len(capacities) div_costs = np.zeros(dests) for i in range(1, dests - 1): d1 = solution[i] d2 = solution[i + 1] div_costs[i] = costs[d1][0] + costs[0][d2] - costs[d1][d2] dp = np.zeros((dests, vehicles + 1), dtype=float) prev_state = np.zeros((dests, vehicles + 1), dtype=int) for i in range(dests): if i != 0: dp[i][0] = self.INF for j in range(1, vehicles + 1): cap = capacities[j - 1] time = time_limits[j - 1] pointer = i dp[i][j] = dp[i][j - 1] prev_state[i][j] = i while pointer > 0 and cap >= weights[solution[pointer]] and ( pointer == i or time >= time_costs[solution[pointer]][solution[pointer + 1]]): pointer -= 1 new_cost = div_costs[pointer] + dp[pointer][j - 1] if new_cost < dp[i][j]: dp[i][j] = new_cost prev_state[i][j] = pointer cap -= weights[solution[pointer + 1]] if pointer != i - 1: time -= time_costs[solution[pointer + 1]][solution[pointer + 2]] new_solution = [] pointer = dests - 1 for j in reversed(range(1, vehicles + 1)): prev = prev_state[pointer][j] if prev != pointer: lis = solution[(prev + 1):(pointer + 1)] if prev != -1: lis = [0] + lis if pointer != dests - 1: lis = lis + [0] new_solution.append(lis) else: new_solution.append([]) pointer = prev new_solution.reverse() return VRPSolution(problem, None, None, new_solution)
def solve(self, only_one_const, order_const, capacity_const, time_const, solver_type = 'qbsolv', num_reads = 50): dests = len(self.problem.dests) vehicles = len(self.problem.capacities) limits = [dests for _ in range(vehicles)] vrp_qubo = self.problem.get_qubo_with_limits(limits, only_one_const, order_const, capacity_const, time_const) samples = DWaveSolvers.solve_qubo(vrp_qubo, solver_type = solver_type, num_reads = num_reads) sample = samples[0] solution = VRPSolution(self.problem, sample, limits) return 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'): qubo = self.problem.get_full_qubo(only_one_const, order_const) sample = DWaveSolvers.solve_qubo(qubo, solver_type=solver_type) solution = VRPSolution(self.problem, sample) return 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)