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)
Beispiel #6
0
    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)
Beispiel #8
0
 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
Beispiel #9
0
    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)