示例#1
0
def genetic_algorithm(sol, population_size, mutation_prob):
    l1_size = len(sol.level1)
    l2_size = len(sol.level2)
    clients_size = len(sol.clients)

    population = [generate_individual(l1_size, l2_size, clients_size) for x in range(population_size)]
    for ind in population:
        ind_sol = construct_from_RK(ind, sol)
        ind.func_obj = obj_function(ind_sol.level1, ind_sol.level2)
    population.sort(key=lambda x : x.func_obj)

    start_time = time.time()
    while time.time() - start_time < 60 * 0.05:
        sel_prob = normalize_obj_func(population)
        new_generation = []
        for i in range(population_size):
            par1, par2 = parent_selection(sel_prob)
            par1 = population[par1]
            par2 = population[par2]
            son = crossover(par1, par2)
            if random() < mutation_prob:
                son = mutate(son)
            new_generation.append(son)

        # Calcular la función objetivo de la nueva generación
        for ind in new_generation:
            ind_sol = construct_from_RK(ind, sol)
            ind.func_obj = obj_function(ind_sol.level1, ind_sol.level2)

        population = population + new_generation
        population.sort(key=lambda x : x.func_obj)
        population = population[:population_size]


    return variable_neighborhood_descent(construct_from_RK(population[0], sol))
示例#2
0
def variable_neighborhood_descent(sol):
    print('VND')
    cur_cost = obj_function(sol.level1, sol.level2)
    found_better = True

    neighborhoods = [inlevel_neighborhood, facility_inout_neighborhood]

    j = 0
    while j < len(neighborhoods):
        best_cand = None
        best_cand_cost = inf
        for cand_sol, cost_delta in neighborhoods[j](sol):
            cand_cost = cur_cost + cost_delta
            if cand_cost < cur_cost:
                best_cand = cand_sol
                best_cand_cost = cand_cost
                break

        if best_cand_cost < cur_cost:
            j = 0
            sol = best_cand
            cur_cost = best_cand_cost
        else:
            j += 1

    return sol
示例#3
0
def inlevel_neighborhood(sol):
    setup_solution(sol)
    initial_cost = obj_function(sol.level1, sol.level2)

    level2 = list(filter(lambda x: x.is_in, sol.level2))

    for l2 in level2:
        for l1 in sol.level1:
            if l2.u[l1.i] == 0: continue
            cur_flow = l2.u[l1.i]

            for new_l2 in level2:
                if new_l2.i == l2.i: continue
                avail_cap = new_l2.m - new_l2.uSum
                flow_delta = min(avail_cap, cur_flow)

                if flow_delta == 0: continue

                func_obj_delta = flow_delta * sol.level2[new_l2.i].c[l1.i] - flow_delta * sol.level2[l2.i].c[l1.i]
                if func_obj_delta < 0:
                    next_sol = sol.copy_solution(copyFlow=True)
                    next_sol.level2[l2.i].u[l1.i] -= flow_delta
                    next_sol.level2[new_l2.i].u[l1.i] += flow_delta
                else: next_sol = None

                yield next_sol, func_obj_delta
示例#4
0
def random_method(level1, level2, clients, p, q, iterations=1):
    bestObj = inf
    ans_sel_level1, ans_sel_level2, ans_clients = None, None, None

    for i in range(iterations):
        # Elegir aleatoriamente p instalaciones
        sel_level1 = sample(level1, p)
        sel_level2 = sample(level2, q)
        sel_level1 = list(map(lambda x : x.new_clone(), sel_level1))
        sel_level2 = list(map(lambda x : x.new_clone(), sel_level2))

        # Calcular la asignación óptima usando MinCostMaxFlow
        cand_sel_level1, cand_sel_level2, cand_clients, flow, fcost = min_cost_max_flow(sel_level1, sel_level2, clients, p, q)
        cand_obj = obj_function(cand_sel_level1, cand_sel_level2)

        # Omit unfeasible solutions
        if flow != sum([x.d for x in clients]):
            continue

        if cand_obj < bestObj:
            ans_sel_level1, ans_sel_level2, ans_clients = cand_sel_level1, cand_sel_level2, cand_clients
            bestObj = cand_obj

    assert(ans_sel_level1 is not None)

    return ans_sel_level1, ans_sel_level2, ans_clients
示例#5
0
def facility_inout_neighborhood(sol):
    setup_solution(sol)
    initial_cost = obj_function(sol.level1, sol.level2)

    l1_in = list(filter(lambda x : x.is_in, sol.level1))
    l1_out = list(filter(lambda x : not x.is_in, sol.level1))

    # Intercambiar instalaciones de nivel 1
    for l_in in l1_in:
        for l_out in l1_out:
            if l_in.uSum <= l_out.m:
                func_obj_delta = 0
                for i in range(len(l_in.u)):
                    func_obj_delta += (l_out.u[i] - l_in.u[i]) * l_in.c[i]
                for i in range(len(l_in.u)):
                    func_obj_delta += (l_in.u[i] - l_out.u[i]) * l_out.c[i]
                for l2 in sol.level2:
                    func_obj_delta += (l2.u[l_out.i] - l2.u[l_in.i]) * l2.c[l_in.i]
                    func_obj_delta += (l2.u[l_in.i] - l2.u[l_out.i]) * l2.c[l_out.i]

                if func_obj_delta < 0:
                    next_sol = sol.copy_solution(copyFlow = True)
                    next_l_in = next_sol.level1[l_in.i]
                    next_l_out = next_sol.level1[l_out.i]
                    next_l_in.is_in = False
                    next_l_out.is_in = True
                    next_l_in.u, next_l_out.u = next_l_out.u, next_l_in.u

                    for l2 in next_sol.level2:
                        l2.u[l_in.i], l2.u[l_out.i] = l2.u[l_out.i], l2.u[l_in.i]

                else: next_sol = None

                yield next_sol, func_obj_delta


    # Intercambiar instalaciones de nivel 2
    l2_in = list(filter(lambda x : x.is_in, sol.level2))
    l2_out = list(filter(lambda x : not x.is_in, sol.level2))
    for l_in in l2_in:
        for l_out in l2_out:
            if l_in.uSum <= l_out.m:
                func_obj_delta = 0
                for i in range(len(l_in.u)):
                    func_obj_delta += (l_out.u[i] - l_in.u[i]) * l_in.c[i]
                for i in range(len(l_in.u)):
                    func_obj_delta += (l_in.u[i] - l_out.u[i]) * l_out.c[i]

                if func_obj_delta < 0:
                    next_sol = sol.copy_solution(copyFlow = True)
                    next_l_in = next_sol.level2[l_in.i]
                    next_l_out = next_sol.level2[l_out.i]
                    next_l_in.is_in = False
                    next_l_out.is_in = True
                    next_l_in.u, next_l_out.u = next_l_out.u, next_l_in.u
                else: next_sol = None

                yield next_sol, func_obj_delta
示例#6
0
def grasp(empty_sol, iterations = 10, k=5, rcl_method=rcl_constructive2):
    print('Method: {}'.format(rcl_method.__name__))
    best_sol = None
    best_obj = inf
    for i in range(iterations):
        level1_temp, level2_temp, clients_temp = copy_solution(empty_sol.level1, empty_sol.level2, empty_sol.clients)
        sel_level1, sel_level2, clients = rcl_method(level1_temp, level2_temp, clients_temp, empty_sol.p, empty_sol.q, k = k)

        sel_solution = Solution(sel_level1, sel_level2, clients, empty_sol.p, empty_sol.q)
        empty_solution = Solution(empty_sol.level1, empty_sol.level2, empty_sol.clients, empty_sol.p, empty_sol.q)
        full_solution = mergeSolutions(sel_solution, empty_solution)
        func_obj = obj_function(full_solution.level1, full_solution.level2)
        #print('GRASP it {} starts with {:,.2f}'.format(i+1, func_obj))

        sol = variable_neighborhood_descent(full_solution)
        func_obj = obj_function(sol.level1, sol.level2)
        #print('GRASP it {} ends with {:,.2f}'.format(i+1, func_obj))

        if func_obj < best_obj:
            best_sol = sol
            best_obj = func_obj

    return best_sol
示例#7
0
def local_search(sol):
    cur_cost = obj_function(sol.level1, sol.level2)
    print('initial cost: {:.2f}'.format(cur_cost))
    found_better = True
    while found_better:
        found_better = False
        for next_sol, delta in facility_inout_neighborhood(sol):
            #cand_cost = obj_function(next_sol.level1, next_sol.level2)
            cand_cost = cur_cost + delta
            if cand_cost < cur_cost:
                print('new best')
                sol = next_sol
                cur_cost = cand_cost
                found_better = True
                break

    return sol