def k_local_search(solution, customers, facilities, k = 5, njobs = 1):
    allocations = solution.copy()
    n_cutomers = len(customers)
    n_facilities = len(facilities)
    old_cost = total_cost(allocations, customers, facilities)
    pbar = trange(n_cutomers)
    for i in pbar:
        last_cost = total_cost(allocations, customers, facilities)
        customer = customers[i]
        costs = np.zeros(n_facilities)
        old_alloc = allocations[i]
        
        current_fac = solution[i]
        closest_facs = find_k_neighbors([facilities[current_fac]],facilities,k)[0]
        parallel = Parallel(n_jobs=njobs)
        delayed_func = delayed(eval_swap_values)
        costs = parallel(
            delayed_func(
                allocations=allocations,
                customers=customers,
                facilities=facilities,
                customer=i,
                new_facility=closest_facs[j],
            ) for j in range(k))
        new_alloc = closest_facs[np.argmin(costs)]
        allocations[i] = new_alloc
        desc = '{:.1f} --> {:.1f} --> {:.1f}'.format(
            old_cost,
            last_cost,
            min(costs),
        )
        pbar.set_description(desc)
    return allocations
def ex_local_search(solution, customers, facilities, njobs=1):
    allocations = solution.copy()
    n_cutomers = len(customers)
    n_facilities = len(facilities)
    old_cost = total_cost(allocations, customers, facilities)
    pbar = trange(n_cutomers)
    for i in pbar:
        customer = customers[i]
        costs = np.zeros(n_facilities)
        old_alloc = allocations[i]

        parallel = Parallel(n_jobs=njobs)
        delayed_func = delayed(eval_swap_values)
        costs = parallel(
            delayed_func(
                allocations=allocations,
                customers=customers,
                facilities=facilities,
                customer=i,
                new_facility=j,
            ) for j in range(n_facilities))
        new_alloc = np.argmin(costs)
        allocations[i] = new_alloc
        desc = '{:.1f} --> {:.1f} --> {:.1f}'.format(
            old_cost,
            costs[old_alloc],
            costs[new_alloc],
        )
        pbar.set_description(desc)
    return allocations
示例#3
0
def ant_colony(
    customers,
    facilities,
    q=1,
    offset=0,
    evaporation=0.1,
    ants=100,
    generations=100,
):
    n_cust = len(customers)
    n_fac = len(facilities)
    dist = distance_matrix(customers, facilities)
    weights = np.ones_like(dist)
    best_sol = None
    best_cost = np.inf
    metrics = defaultdict(list)
    for gen in trange(generations):
        probs = weights / dist
        updates = np.zeros_like(dist)
        costs = []
        for ant in range(ants):
            solution = ant_simulator(customers, facilities, dist, probs)
            cost = total_cost(solution, customers, facilities)
            edges = allocation2matrix(solution, n_fac)
            updates += edges * q / (cost - offset)
            costs.append(cost)
            if cost < best_cost:
                best_cost = cost
                best_sol = solution

        weights = weights * (1 - evaporation) + updates
        metrics["min_cost"].append(np.min(costs))
        metrics["max_cost"].append(np.max(costs))
        metrics["mean_cost"].append(np.mean(costs))
    return best_sol, metrics
示例#4
0
def double_trial(customers, facilities, solver, **kwargs):
    # First attempt
    solution = solver(customers, facilities, **kwargs)
    cost = total_cost(solution, customers, facilities)
    # Choosing top facilities
    min_fac = est_facilities(customers, facilities)
    sorted_facs = sorted(Counter(solution).items(), key=itemgetter(1), reverse=True)
    top_facs_idx = [f for f, i in sorted_facs[:min_fac]]
    top_facs = [facilities[f] for f in top_facs_idx]

    # Second Attempt
    solution2 = greedy_furthest(customers, top_facs, **kwargs)

    # Rearrange the solution
    solution2 = [top_facs_idx[f] for f in solution2]
    cost2 = total_cost(solution2, customers, facilities)
    if cost2 < cost:
        return solution2
    else:
        return solution
def greedy_restart(customers,facilities,restarts=100,branches = 5,random_state=None):
    best_sol = []
    best_cost = np.inf
    pbar = trange(restarts)
    for _ in pbar:
        pbar.set_description(f'{best_cost:.1f}')
        solution = iter_greedy(customers,facilities,branches,random_state)
        cost = total_cost(solution,customers,facilities)
        if cost<best_cost:
            best_cost = cost
            best_sol = solution
    return best_sol
def iter_greedy(customers,facilities,branches = 5,random_state=None):
    np.random.seed(random_state)
    solution = greedy_furthest(customers,facilities,pbar=False)
    cost = total_cost(solution, customers, facilities)
    for _ in range(len(facilities)):
        idx = np.random.choice(np.unique(solution),5)
#         new_facilities = [f for f in facilities if f.index!=dropped_facility]
        old_facilities = facilities.copy()
        new_sols = []
        new_costs = []
        for i in idx:
            facilities = old_facilities.copy()
            dropped_facility = facilities.pop(i)
            new_sols.append( greedy_furthest(customers,facilities,pbar=False))
            new_costs.append( total_cost(new_sols[-1], customers, facilities))
        if min(new_costs)<cost:
            i = np.argmin(new_costs)
            solution = new_sols[i]
            cost = new_costs[i]
        else:
            return [old_facilities[f].index for f in solution]
def ex_local_search(solution, customers, facilities, verbose=False):
    allocations = solution.copy()
    n_cutomers = len(customers)
    n_facilities = len(facilities)
    old_cost = total_cost(allocations, customers, facilities)
    pbar = trange(n_cutomers)
    for i in pbar:
        customer = customers[i]
        costs = np.zeros(n_facilities)
        old_alloc = allocations[i]
        for j in range(n_facilities):
            allocations[i] = j
            costs[j] = total_cost(allocations, customers, facilities)
        new_alloc = np.argmin(costs)
        allocations[i] = new_alloc
        if verbose:
            desc = '{:.1f} --> {:.1f} --> {:.1f}'.format(
                old_cost,
                costs[old_alloc],
                costs[new_alloc],
            )
            pbar.set_description(desc)
    return allocations
def ant_colony(
    customers,
    facilities,
    q=1,
    offset=0,
    evaporation=.1,
    ants=100,
    generations=100,
):
    n_cust = len(customers)
    n_fac = len(facilities)
    dist = distance_matrix(customers, facilities)
    weights = np.ones_like(dist)
    best_sol = None
    best_cost = np.inf
    metrics = defaultdict(list)
    greedy_solution = double_trial(
        customers,
        facilities,
        greedy_furthest,
        p_skip=0,
        pbar=False,
    )
    for gen in trange(generations):
        probs = weights/dist
        updates = np.zeros_like(dist)
        costs = []
        for ant in range(ants):
            if ant==0:
                solution = greedy_solution.copy()
            else:
                solution = ant_simulator(customers, facilities, dist, probs)
            cost = total_cost(solution,customers, facilities)
            edges = allocation2matrix(solution, n_fac)
            updates += edges*q/(cost-offset)
            costs.append(cost)
            if cost<best_cost:
                best_cost = cost
                best_sol = solution
                
        weights = weights*(1-evaporation) + updates
        metrics['min_cost'].append(np.min(costs))
        metrics['max_cost'].append(np.max(costs))
        metrics['mean_cost'].append(np.mean(costs))
    return best_sol, metrics
示例#9
0
def view_solution(solution, customers, facilities, figsize=(8, 8)):
    loc_cust = np.array([c.location for c in customers])
    loc_fac = np.array([f.location for f in facilities])
    plt.figure(figsize=figsize)
    plt.scatter(loc_cust[:, 0], loc_cust[:, 1], marker="o", c="k", s=5)
    plt.scatter(loc_fac[:, 0], loc_fac[:, 1], marker="*", c="r", s=5)

    cost = total_cost(solution, customers, facilities)
    s = ""
    try:
        validate(solution, customers, facilities)
    except AssertionError:
        s = "*"
    plt.title(
        f"{len(customers)} Customers    {len(facilities)} Facilities   Total Cost{s} = {cost:.1f}"
    )
    for c, f in enumerate(solution):
        x = [facilities[f].location.x, customers[c].location.x]
        y = [facilities[f].location.y, customers[c].location.y]
        plt.plot(x, y, "-k", alpha=0.5)
def eval_swap_values(allocations, customers, facilities, customer,
                     new_facility):
    alloc = allocations.copy()
    alloc[customer] = new_facility
    return total_cost(alloc, customers, facilities)
    kdtree = KDTree(y)
    dist, neighbors = kdtree.query(x,k)
    return neighbors


# -

from algorithms import greedy
from calc import total_cost

customers, facilities = load_data('fl_1000_2')
len(customers),len(facilities)

# sol = random_allocation(customers,facilities)
sol = greedy(customers,facilities)
total_cost(sol,customers,facilities)

sol2 = k_local_search(sol,customers,facilities,12)

sol = greedy(customers,facilities)
total_cost(sol,customers,facilities)

sol2 = local_search(sol,customers,facilities,True)

view_solution(sol2,customers,facilities)



validate(sol2,customers,facilities)

# ## Constraint Programming
示例#12
0
def solve_it(input_data):
    # Modify this code to run your optimization algorithm

    # parse the input
    customers, facilities = parse_input(input_data)
    facility_count = len(facilities)
    customer_count = len(customers)

    # Solution
    # Selecting the solver
    if facility_count > 100:
        mode = 6
    else:
        mode = 5

    # Applying the solver
    status = "FEASIBLE"
    if mode == 0:
        solution = greedy(customers, facilities)
        solution = ex_local_search(solution, customers, facilities, True)
    elif mode == 1:
        solution = clustering(customers, facilities)
    elif mode == 2:
        print("*** Using MIP solver ***")
        solution, status = cap_mip(customers, facilities, 8 * 3600)
        print(f'MIP Solver finished with status "{status}"')
    elif mode == 3:
        print("Double trial with greedy")
        solution = double_trial(customers, facilities, greedy_furthest)
    elif mode == 4:
        print("*** Using Ant Colony Optimisation ***")
        solution = double_trial(
            customers,
            facilities,
            greedy_furthest,
            p_skip=0,
            pbar=False,
        )
        cost = total_cost(solution, customers, facilities)
        q = cost
        offset = cost * 0.75
        solution, _ = ant_colony(
            customers,
            facilities,
            q=q,
            offset=offset,
            evaporation=0.1,
        )
    elif mode == 5:
        print("*** Using Gurobi Solver ***")
        solution = cap_mip_gr(customers, facilities, 120)
        solution1 = fix_allocations(solution, customers, facilities)
        cost1 = total_cost(solution1, customers, facilities)
        solution2 = double_trial(customers, facilities, greedy_furthest)
        cost2 = total_cost(solution2, customers, facilities)
        if cost1 < cost2:
            solution = solution1
        else:
            solution = solution2
    elif mode == 6:
        print("*** Using Piecewise Gurobi Solver ***")
        solution1 = piecewise_mip(customers, facilities, per_grid=80)
        cost1 = total_cost(solution1, customers, facilities)
        solution2 = double_trial(customers, facilities, greedy_furthest)
        cost2 = total_cost(solution2, customers, facilities)
        if cost1 < cost2:
            solution = solution1
        else:
            solution = solution2
    else:
        solution = greedy(customers, facilities)
        status = "FEASIBLE"

    # calculate the cost of the solution

    obj = total_cost(solution, customers, facilities)
    # prepare the solution in the specified output format
    status_code = 1 if status == "OPTIMAL" else 0
    output_data = "%.2f" % obj + " " + str(status_code) + "\n"
    output_data += " ".join(map(str, solution))

    return output_data