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