def cp_solving(vehicle_count, vehicle_capacity, customer_count, customers, fraction=0.1): model_vrp = Model("./vrp.mzn") # Find the MiniZinc solver configuration for Gecode solver = Solver.lookup("chuffed") instance = Instance(solver, model_vrp) instance["nb_customers_without_depot"] = customer_count-1 nb_customers_virtual = customer_count-1+vehicle_count+1 range_customer_virtual = range(1, nb_customers_virtual+1) instance["nb_vehicle"] = vehicle_count closest, matrix = compute_length_matrix(customers) demands = [customers[i].demand for i in range(1, customer_count)]+[0]*(vehicle_count+1) instance["demand"] = demands instance["capacity_vehicle"] = vehicle_capacity recomputed_dist = [] for i in range(1, customer_count): recomputed_dist += [[int(matrix[i, j]) for j in range(1, customer_count)]+[int(matrix[i, 0])]*(vehicle_count+1)] for v in range(vehicle_count+1): recomputed_dist += [[int(matrix[0, j]) for j in range(1, customer_count)]+[0]*(vehicle_count+1)] instance["distance"] = recomputed_dist result = instance.solve(timeout=timedelta(seconds=100)) opt: Status = result.status print(result.__dict__) objective = result["objective"] print("Objective : ", objective) print(result["circuit_vrp"]) iteration = 0 dict_result = {i+1: result["circuit_vrp"][i] for i in range(nb_customers_virtual)} current_objective = objective while iteration < 1000: with instance.branch() as child: subpart_tsp = set(random.sample(range_customer_virtual, int(fraction*len(range_customer_virtual)))) for i in range_customer_virtual: if i not in subpart_tsp: # print("constraint color_graph["+str(i)+"] == "+ str(dict_color[i])+";\n") child.add_string("constraint circuit_vrp["+str(i)+"] == "+ str(dict_result[i])+";\n") child.add_string(f"solve minimize(objective);\n") res = child.solve(timeout=timedelta(seconds=50)) print(res.status) if res.solution is not None and res["objective"] <= current_objective: iteration += 1 incumbent = res.solution current_objective = res["objective"] dict_result = {i+1: res["circuit_vrp"][i] for i in range(nb_customers_virtual)} #json.dump(dict_color, open('debug_cp.json', "w")) print(iteration , " : , ", res["objective"]) print('IMPROVED : ', iteration) print("dict result : ", dict_result) else: try: print("Not improved ") print(iteration , " : ", res["objective"]) except: print(iteration, " failed ") # print({i: res["color_graph"][i-1] for i in range_node}) iteration += 1
def run_extended(self): inst = Instance(self.solver, self.model) # we'll need a solution pool of previously seen solutions # to rule out condorcet cycles; a solution is stored as a Python dictionary from variable to value solution_pool = [] res: Result = inst.solve() print(res.solution) duels = [] new_solution = None model_counter = 0 while res.status == Status.SATISFIED: model_counter += 1 old_solution = new_solution new_solution = { var: res[var] for var in self.variables_of_interest } solution_pool += [new_solution] if hasattr(res.solution, PREFERRED_BY_KEY): preferred_by = res[PREFERRED_BY_KEY] self.num_voters = res[NUM_VOTERS_KEY] print(preferred_by) duels += [(new_solution, old_solution, preferred_by)] with inst.branch() as child: child.add_string( f"array[{self.agents_key}] of par int: old_score;") child["old_score"] = res["score"] # copy the current ranks self.add_condorcet_improvement(child) self.add_duel_bookkeeping(child) # but it should be a "new" solution self.post_something_changes(child, solution_pool) # logging self.log_and_debug_generated_files(child, model_counter) res = child.solve() if res.solution is not None: print(res.solution) for (winning_solution, losing_solution, preferrers) in duels: print( f"Solution {winning_solution} won against {losing_solution} with {preferrers} : {self.num_voters - preferrers}" )