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
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