import random import time import matplotlib.pyplot as plt import sys def greedy(n, weight, value, capacity ): ratios = [(value[i] / weight[i], weight[i]) for i in range(n)] ratios.sort(reverse=True, key=lambda x: x[0]) current_weight = 0 current_value = 0 items_taken = [] for ratio, weight in ratios: if current_weight + weight <= capacity and current_value + value[ratios.index((ratio, weight))] <= capacity: current_weight += weight current_value += value[ratios.index((ratio, weight))] items_taken.append(ratios.index((ratio, weight))) return current_value def dynamic(n, weight, value, capacity, print_table=False): table = [[0 for _ in range(capacity + 1)] for _ in range(n + 1)] for i in range(1, n + 1): for w in range(capacity + 1): if weight[i - 1] <= w: table[i][w] = max(table[i - 1][w], table[i - 1][w - weight[i - 1]] + value[i - 1]) else: table[i][w] = table[i - 1][w] if print_table: print("\n".join(["\t".join(map(str, row)) for row in table])) return table[n][capacity] def benchmark_containers(container_list, capacity): greedy_times = [] dynamic_times = [] greedy_values = [] dynamic_values = [] rel_errors = [] # For each container number or capacity for containers in container_list: weights = [random.randint(1, 10) for _ in range(containers)] values = [random.randint(1, 20) for _ in range(containers)] # Dynamic start = time.time() dyn = dynamic(containers, weights, values, capacity) dyn_time = (time.time() - start) * 1000 # Greedy start = time.time() gr = greedy(containers, weights, values, capacity) gr_time = (time.time() - start) * 1000 greedy_times.append(gr_time) dynamic_times.append(dyn_time) greedy_values.append(gr) dynamic_values.append(dyn) rel_errors.append((dyn - gr) / dyn * 100 if dyn != 0 else 0) return greedy_times, dynamic_times, rel_errors def benchmark_capacity(capacity_list, containers): greedy_times = [] dynamic_times = [] greedy_values = [] dynamic_values = [] rel_errors = [] # For each container number or capacity for capacity in capacity_list: weights = [random.randint(1, 10) for _ in range(containers)] values = [random.randint(1, 20) for _ in range(containers)] # Dynamic start = time.time() dyn = dynamic(containers, weights, values, capacity) dyn_time = (time.time() - start) * 1000 # Greedy start = time.time() gr = greedy(containers, weights, values, capacity) gr_time = (time.time() - start) * 1000 greedy_times.append(gr_time) dynamic_times.append(dyn_time) greedy_values.append(gr) dynamic_values.append(dyn) rel_errors.append(abs((dyn - gr) / dyn) * 100 if dyn != 0 else 0) return greedy_times, dynamic_times, rel_errors if __name__ == "__main__": # Check if there was given a second argument, if yes run a test instead of the benchmark if len(sys.argv) > 1: file = sys.argv[1] """ Format we are expecting: 5 - liczba elementów 3 2 4 3 1 - rozmiary 5 3 4 4 2 - wartości 8 - rozmiar plecaka """ with open(file, 'r') as f: lines = f.readlines() n = int(lines[0].strip()) weights = list(map(int, lines[1].strip().split())) values = list(map(int, lines[2].strip().split())) capacity = int(lines[3].strip()) dynamic(n, weights, values, capacity, print_table=True) exit(0) # First test case - constant capacity, variable number of containers containers_list = list(range(5, 101, 5)) # Constant capacity of 20 greedy_times, dynamic_times, rel_errors = benchmark_containers(containers_list, 20) plt.figure(figsize=(12,5)) plt.subplot(1,2,1) plt.plot(containers_list, greedy_times, label='Zachłanny', marker='o') plt.plot(containers_list, dynamic_times, label='Dynamiczny', marker='o') plt.xlabel('Liczba kontenerów') plt.ylabel('Czas [ms]') plt.title('Czas działania dla zmiennej liczby kontenerów (B=20)') plt.legend() axis = plt.subplot(1,2,2) plt.bar(containers_list, rel_errors) plt.xlabel('Liczba kontenerów') plt.ylabel('Błąd względny [%]') axis.yaxis.set_major_formatter(lambda x, pos: f'{x}%'.replace('.0', '')) plt.title('Błąd względny') plt.savefig('benchmark_vary_n.png') # Second test case - variable capacity, constant number of containers capacity_list = list(range(5, 101, 5)) # Constant number of containers of 50 greedy_times, dynamic_times, rel_errors = benchmark_capacity(capacity_list, 50) plt.figure(figsize=(12,5)) plt.subplot(1,2,1) plt.plot(capacity_list, greedy_times, label='Zachłanny', marker='o') plt.plot(capacity_list, dynamic_times, label='Dynamiczny' , marker='o') plt.xlabel('Pojemność') plt.ylabel('Czas [ms]') plt.title('Czas działania dla zmiennej pojemności (n=50)') plt.legend() axis = plt.subplot(1,2,2) plt.bar(capacity_list, rel_errors ) plt.xlabel('Pojemność') plt.ylabel('Błąd względny [%]') axis.yaxis.set_major_formatter(lambda x, pos: f'{x}%'.replace('.0', '')) plt.title('Błąd względny') plt.savefig('benchmark_vary_capacity.png')