Beispiel #1
0
    def get_first_dest_qubo(self, start_step, dests, costs, source):
        fir_qubo = Qubo()

        for dest in dests:
            in_index = ((start_step, dest), (start_step, dest))
            in_cost = costs[source][dest]
            fir_qubo.add(in_index, in_cost)

        return fir_qubo
Beispiel #2
0
    def get_last_dest_qubo(self, final_step, dests, costs, source):
        las_qubo = Qubo()

        for dest in dests:
            out_index = ((final_step, dest), (final_step, dest))
            out_cost = costs[dest][source]
            las_qubo.add(out_index, out_cost)

        return las_qubo
Beispiel #3
0
    def get_capacity_qubo(self, capacity, start_step, final_step):
        dests = self.dests
        weights = self.weights
        cap_qubo = Qubo()

        for (d1, d2) in combinations(dests, 2):
            for (s1, s2) in combinations(range(start_step, final_step + 1), 2):
                index = ((s1, d1), (s2, d2))
                cost = weights[d1] * weights[d2] / capacity**2
                cap_qubo.add(index, cost)

        return cap_qubo
Beispiel #4
0
    def get_order_qubo(self, start_step, final_step, dests, costs):
        source = self.source
        ord_qubo = Qubo()

        # Order constraint
        for step in range(start_step, final_step):
            for dest1 in dests:
                for dest2 in dests:
                    cost = costs[dest1][dest2]
                    index = ((step, dest1), (step + 1, dest2))
                    ord_qubo.add(index, cost)

        return ord_qubo
Beispiel #5
0
    def get_time_qubo(self, start_step, final_step):
        dests = self.dests
        time_windows = self.time_windows
        tim_qubo = Qubo()

        for (d1, d2) in product(dests, dests):
            for (s1, s2) in combinations(range(start_step, final_step + 1), 2):
                index = ((s1, d1), (s2, d2))

                time_diff = time_windows[d1] - time_windows[d2] + 1
                step_diff = s2 - s1
                cost = float(time_diff) * float(step_diff)
                if time_diff < 0:
                    cost = 0.

                tim_qubo.add(index, cost)

        return tim_qubo
    def get_qubo(self, only_one_const, order_const):
        tsp_qubo = Qubo()
        steps_num = len(self.dests)
        source = self.source

        # Only one vertex for one step.
        for step in range(steps_num):
            tsp_qubo.add_only_one_constraint([(step, i) for i in self.dests], only_one_const)

        # Only one step for one vertex
        for dest in self.dests:
            tsp_qubo.add_only_one_constraint([(step, dest) for step in range(steps_num)], only_one_const)

        # Constraints for first and last destination.
        for dest in self.dests:
            in_index = ((0, dest), (0, dest))
            out_index = (steps_num - 1, dest), (steps_num - 1, dest)
            in_cost = self.costs[source][dest]
            out_cost = self.costs[dest][source]
            tsp_qubo.add(in_index, in_cost * order_const)
            tsp_qubo.add(out_index, out_cost * order_const)

        # Constraints for next steps.
        for step in range(steps_num - 1):
            for i in self.dests:
                for j in self.dests:
                    cost = self.costs[i][j]
                    index = ((step, i), (step + 1, j))
                    tsp_qubo.add(index, cost * order_const)

        return tsp_qubo
Beispiel #7
0
    def get_qubo_with_time(self, vehicle_limits, only_one_const, order_const,
                           capacity_const, time_const):
        # Steps counting.
        steps = 0
        for (_, r) in vehicle_limits:
            steps += r

        dests = self.dests
        costs = self.costs
        source = self.source
        time_windows = self.time_windows
        dests_with_times = list()
        vrp_qubo = Qubo()

        # Time blocks counting.
        time_blocks_num = int(
            max([time_windows[i] for i in time_windows]) / self.TIME_BLOCK)
        for dest in dests:
            first = int((time_windows[dest] - self.TIME_WINDOW_RADIUS) /
                        self.TIME_BLOCK)
            last = int((time_windows[dest] + self.TIME_WINDOW_RADIUS) /
                       self.TIME_BLOCK)
            dests_with_times += [(time, dest) for time in range(first, last)]

            vrp_qubo.add_only_one_constraint(
                [(step, (time, dest))
                 for step, time in product(range(steps), range(first, last))],
                only_one_const)

        # Adding qubits for source.
        dests_with_source = dests_with_times.copy()
        dests_with_source += [(time, source)
                              for time in range(time_blocks_num)]

        # Costs for dests_with_times.
        costs_with_times = dict()
        for (t1, d1), (t2, d2) in product(dests_with_source,
                                          dests_with_source):
            cost = only_one_const
            if t1 <= t2:
                cost = costs[d1][d2]
            if not (t1, d1) in costs_with_times:
                costs_with_times[(t1, d1)] = dict()
            costs_with_times[(t1, d1)][(t2, d2)] = cost

        start = 0
        for vehicle in range(len(vehicle_limits)):
            min_size = vehicle_limits[vehicle][0]
            max_size = vehicle_limits[vehicle][1]
            min_final = start + min_size - 1
            max_final = start + max_size - 1

            # First steps should have normal destinations.
            if min_size != 0:
                for step in range(start, min_final + 1):
                    vrp_qubo.add_only_one_constraint(
                        [(step, dest) for dest in dests_with_times],
                        only_one_const)
                ord_min_qubo = self.get_order_qubo(start, min_final,
                                                   dests_with_times)
                vrp_qubo.merge_with(ord_min_qubo, 1., order_const)

            # In other steps vehicles can wait in source.
            if max_size != min_size:
                for step in range(min_final + 1, max_final + 1):
                    vrp_qubo.add_only_one_constraint(
                        [(step, dest) for dest in dests_with_source],
                        only_one_const)
                ord_max_qubo = self.get_order_qubo(min_final + 1, max_final,
                                                   dests_with_source,
                                                   costs_with_times)
                vrp_qubo.merge_with(ord_max_qubo, 1., order_const)

            # From min_final step to min_final + 1 step.
            if min_size != 0 and min_size != max_size:
                for dest1 in dests_with_times:
                    for dest2 in dests_with_source:
                        cost = costs[dest1][dest2]
                        index = ((min_final, dest1), (min_final + 1, dest2))
                        vrp_qubo.add(index, cost * order_const)

            # First and last destinations.
            fir_qubo = self.get_first_dest_qubo(start, dests_with_times,
                                                costs_with_times, (0, source))
            las_qubo = self.get_last_dest_qubo(max_final, dests_with_source,
                                               costs_with_times,
                                               (time_blocks_num - 1, source))
            vrp_qubo.merge_with(fir_qubo, 1., order_const)
            vrp_qubo.merge_with(las_qubo, 1., order_const)

            # Capacity constraints.
            if capacity_const != 0:
                capacity = capacities[vehicle]
                cap_qubo = self.get_capacity_qubo(capacity, start, max_final)
                vrp_qubo.merge_with(cap_qubo, 1., capacity_const)

            # Time constraints.
            if time_const != 0:
                time_costs = self.time_costs
                new_time_costs = dict()
                for ((t1, d1), (t2, d2)) in product(dests_with_source,
                                                    dests_with_source):
                    new_time_costs[(t1, d1)][(t2, d2)] = time_costs[d1][d2]
                tim_qubo = self.get_time_qubo2(start, max_final)
                vrp_qubo.merge_with(tim_qubo, 1., time_const)

            start = max_final + 1

        return vrp_qubo
Beispiel #8
0
    def get_qubo_with_both_limits(self, vehicle_limits, only_one_const,
                                  order_const, capacity_const, time_const):
        steps = 0
        for (_, r) in vehicle_limits:
            steps += r

        capacities = self.capacities
        dests = self.dests
        source = self.source
        dests_with_source = dests.copy()
        dests_with_source.append(source)
        costs = self.costs
        vrp_qubo = Qubo()

        # Only one step for one destination.
        for dest in self.dests:
            vrp_qubo.add_only_one_constraint([(step, dest)
                                              for step in range(steps)],
                                             only_one_const)

        start = 0
        for vehicle in range(len(vehicle_limits)):
            min_size = vehicle_limits[vehicle][0]
            max_size = vehicle_limits[vehicle][1]
            min_final = start + min_size - 1
            max_final = start + max_size - 1

            # First steps should have normal destinations.
            if min_size != 0:
                for step in range(start, min_final + 1):
                    vrp_qubo.add_only_one_constraint([(step, dest)
                                                      for dest in dests],
                                                     only_one_const)
                ord_min_qubo = self.get_order_qubo(start, min_final, dests,
                                                   costs)
                vrp_qubo.merge_with(ord_min_qubo, 1., order_const)

            # In other steps vehicles can wait in source.
            if max_size != min_size:
                for step in range(min_final + 1, max_final + 1):
                    vrp_qubo.add_only_one_constraint(
                        [(step, dest) for dest in dests_with_source],
                        only_one_const)
                ord_max_qubo = self.get_order_qubo(min_final + 1, max_final,
                                                   dests_with_source, costs)
                vrp_qubo.merge_with(ord_max_qubo, 1., order_const)

            # From min_final step to min_final + 1 step.
            if min_size != 0 and min_size != max_size:
                for dest1 in dests:
                    for dest2 in dests_with_source:
                        cost = costs[dest1][dest2]
                        index = ((min_final, dest1), (min_final + 1, dest2))
                        vrp_qubo.add(index, cost * order_const)

            # First and last destinations.
            fir_qubo = self.get_first_dest_qubo(start, dests, costs, source)
            las_qubo = self.get_last_dest_qubo(max_final, dests_with_source,
                                               costs, source)
            vrp_qubo.merge_with(fir_qubo, 1., order_const)
            vrp_qubo.merge_with(las_qubo, 1., order_const)

            # Capacity constraints.
            if capacity_const != 0:
                capacity = capacities[vehicle]
                cap_qubo = self.get_capacity_qubo(capacity, start, max_final)
                vrp_qubo.merge_with(cap_qubo, 1., capacity_const)

            # Time constraints.
            if time_const != 0:
                tim_qubo = self.get_time_qubo(start, max_final)
                vrp_qubo.merge_with(tim_qubo, 1., time_const)

            start = max_final + 1

        return vrp_qubo