Пример #1
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
Пример #2
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