def mkp_mst(D, W): best_approx = DeliveryPath() for count in range(1, len(D)): continue_ = False for haul in combinations(D, count): shortest_path = DeliveryPath(haul) if shortest_path.weight > W: continue continue_ = True approx = DeliveryPath(haul) if approx > best_approx: best_approx = approx if not continue_: break return best_approx if __name__ == '__main__': deliveries = Delivery.generate(20) weight_limit = 250 path = mkp_mst(D=deliveries, W=weight_limit) path.plot(all_deliveries=deliveries) print(f"best profit: ${path.profit:.2f}") print(f"capacity used: {path.weight / weight_limit:.1%}")
def compare_mkp_solutions(): print("Comparing up to brute force limits (n=8)") results = results_init() for i in range(10): deliveries = Delivery.generate(8) weight_limit = 250 for algo in algorithms: t0 = perf_counter() path = algo(D=deliveries, W=weight_limit) results[algo.__name__]['time'] += perf_counter() - t0 results[algo.__name__]['profit'] += path.profit print(f"Round {i+1}/10") pprint(results, width=50) print('Compared to brute force:') bf_res = results[algorithms[0].__name__] for algo in algorithms[1:]: n = algo.__name__ print(f"{n}: " f"{results[n]['profit'] / bf_res['profit']:.1%} profit, " f"{bf_res['time'] / results[n]['time']:.0f}x faster") del algorithms[0] print("\nComparing up to combinatorial mst limits (n=16)") results = results_init() for i in range(10): deliveries = Delivery.generate(16) weight_limit = 250 for algo in algorithms: t0 = perf_counter() path = algo(D=deliveries, W=weight_limit) results[algo.__name__]['time'] += perf_counter() - t0 results[algo.__name__]['profit'] += path.profit print(f"Round {i+1}/10") pprint(results, width=50) print('Compared to combinatorial mst:') cmst_res = results[algorithms[0].__name__] for algo in algorithms[1:]: n = algo.__name__ print(f"{n}: " f"{results[n]['profit'] / cmst_res['profit']:.1%} profit, " f"{cmst_res['time'] / results[n]['time']:.0f}x faster") del algorithms[0] print("\nComparing the two fast approximation algorithms (n=200)") results = results_init() for i in range(10): deliveries = Delivery.generate(250) weight_limit = 2000 for algo in algorithms: t0 = perf_counter() path = algo(D=deliveries, W=weight_limit) results[algo.__name__]['time'] += perf_counter() - t0 results[algo.__name__]['profit'] += path.profit print(f"Round {i+1}/10") pprint(results, width=50) print('Comparing:') for index in (0, 1): n1 = algorithms[index].__name__ n2 = algorithms[not index].__name__ print(f"{n1}: " f"{results[n1]['profit'] / results[n2]['profit']:.1%} profit, " f"{results[n2]['time'] / results[n1]['time']:.2f}x faster")
def brute_force_mkp(D, W): best_path = DeliveryPath() for count in range(len(D)): for haul in combinations(D, count + 1): new_path = DeliveryPath(haul, make_mst=False) if new_path.weight > W: continue for path in permutations(haul): path = DeliveryPath(path, make_mst=False) if path > new_path: new_path = path if new_path.profit > best_path.profit: best_path = new_path return best_path if __name__ == '__main__': deliveries = Delivery.generate(10) weight_limit = 250 path = brute_force_mkp(D=deliveries, W=weight_limit) path.plot(all_deliveries=deliveries) print(f"best profit: ${path.profit:.2f}") print(f"capacity used: {path.weight / weight_limit:.1%}")