diff --git a/collect b/collect index ba376a1..4e3f8f0 100644 --- a/collect +++ b/collect @@ -24,11 +24,11 @@ edge [fontname="helvetica"] ; 6 -> 10 ; 11 [label="garbage_weight <= 0.612\ngini = 0.094\nsamples = 61\nvalue = [3, 58]\nclass = no-collect"] ; 10 -> 11 ; -12 [label="garbage_type <= 2.0\ngini = 0.5\nsamples = 2\nvalue = [1, 1]\nclass = collect"] ; +12 [label="space_occupied <= 0.382\ngini = 0.5\nsamples = 2\nvalue = [1, 1]\nclass = collect"] ; 11 -> 12 ; -13 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]\nclass = collect"] ; +13 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]\nclass = no-collect"] ; 12 -> 13 ; -14 [label="gini = 0.0\nsamples = 1\nvalue = [0, 1]\nclass = no-collect"] ; +14 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]\nclass = collect"] ; 12 -> 14 ; 15 [label="garbage_type <= 2.5\ngini = 0.065\nsamples = 59\nvalue = [2, 57]\nclass = no-collect"] ; 11 -> 15 ; @@ -50,11 +50,11 @@ edge [fontname="helvetica"] ; 5 -> 23 ; 24 [label="gini = 0.0\nsamples = 2\nvalue = [0, 2]\nclass = no-collect"] ; 23 -> 24 ; -25 [label="odour_intensity <= 8.841\ngini = 0.219\nsamples = 8\nvalue = [7, 1]\nclass = collect"] ; +25 [label="days_since_last_collection <= 22.0\ngini = 0.219\nsamples = 8\nvalue = [7, 1]\nclass = collect"] ; 23 -> 25 ; 26 [label="gini = 0.0\nsamples = 6\nvalue = [6, 0]\nclass = collect"] ; 25 -> 26 ; -27 [label="days_since_last_collection <= 22.0\ngini = 0.5\nsamples = 2\nvalue = [1, 1]\nclass = collect"] ; +27 [label="odour_intensity <= 8.841\ngini = 0.5\nsamples = 2\nvalue = [1, 1]\nclass = collect"] ; 25 -> 27 ; 28 [label="gini = 0.0\nsamples = 1\nvalue = [1, 0]\nclass = collect"] ; 27 -> 28 ; diff --git a/collect.pdf b/collect.pdf index 3e1b6cf..b0339fe 100644 Binary files a/collect.pdf and b/collect.pdf differ diff --git a/garbage_truck.py b/garbage_truck.py index da0b00d..5a340b0 100644 --- a/garbage_truck.py +++ b/garbage_truck.py @@ -54,6 +54,8 @@ class GarbageTruck: def next_destination(self): for i in range(len(self.request_list)): + if(self.request_list==[]): + break request = self.request_list[i] #nie ma miejsca w zbiorniku lub za ciężkie śmieci @@ -64,25 +66,10 @@ class GarbageTruck: if heuristicfn(request.x_pos, request.y_pos, self.dump_x, self.dump_y) // 50 * 200 > self.fuel: continue - - - distance = heuristicfn(self.rect.x, self.rect.y, request.x_pos, request.y_pos) // 50 - - r = [ - self.fuel, - distance, - request.volume, - request.last_collection, - request.is_paid, - request.odour_intensity, - request.weight, - request.type - ] - if self.clf.predict([r]) == True: - self.request_list.pop(i) - self.free_space -= request.volume - self.weight_capacity -= request.weight - return request.x_pos, request.y_pos + self.request_list.pop(i) + self.free_space -= request.volume + self.weight_capacity -= request.weight + return request.x_pos, request.y_pos return self.dump_x, self.dump_y @@ -96,7 +83,10 @@ class GarbageTruck: self.weight_capacity_mixed = MAX_WEIGHT_MIXED self.weight_capacity_glass = MAX_WEIGHT_GLASS self.weight_capacity_paper = MAX_WEIGHT_PAPER - request = self.request_list[0] + if self.request_list==[]: + return 1 + else: + request = self.request_list[0] if garbage_type == "glass": if request.weight > self.weight_capacity_glass: return 1 diff --git a/genetic.py b/genetic.py new file mode 100644 index 0000000..b917977 --- /dev/null +++ b/genetic.py @@ -0,0 +1,162 @@ +import pygame +from treelearn import treelearn +import loadmodel +from astar import astar +from state import State +import time +from garbage_truck import GarbageTruck +from heuristicfn import heuristicfn +from map import randomize_map +from heuristicfn import heuristicfn +import pygame as pg +import random +from request import Request + +def determine_fitness(requests_list): + distances = [] + for i in range(len(requests_list)+1): #from: request_list[i].x_pos and .y_pos + temp = [] + for j in range(len(requests_list)+1): + if ji: + if i==0: + dist = heuristicfn(0, 0, requests_list[j-1].x_pos, requests_list[j-1].y_pos) + temp.append(dist) + else: + dist = heuristicfn(requests_list[i-1].x_pos, requests_list[i-1].y_pos, requests_list[j-1].x_pos, requests_list[j-1].y_pos) + temp.append(dist) + distances.append(temp) + return(distances) + + +def perform_permutation(obj_list, perm_list): + result = [None] * len(obj_list) + + for i, index in enumerate(perm_list): + result[int(index)-1] = obj_list[i-1] + return result + +def apply_genetic(request_list): + print("Genetic algorithm started") + + distances = determine_fitness(request_list) + population_size = 12 + num_generations = 8 + mutation_rate = 0.3 + NUM = len(distances) + + def initialize_population(): + population = [] + for _ in range(population_size): + chromosome = ['0'] + while True: + if len(chromosome) == NUM: + chromosome.append('0') + break + + temp = random.randint(1, NUM-1) + temp_str = str(temp) + if temp_str not in chromosome: + chromosome.append(temp_str) + population.append(chromosome) + return population + + def calculate_route_length(route): + length = 0 + for i in range(len(route)-1): + p = int(route[i]) + q = int(route[i + 1]) + length += distances[int(min(p,q))][int(max(p,q))] + return length + + def calculate_fitness(population): + fitness_scores = [] + for chromosome in population: + fitness_scores.append(1 / calculate_route_length(chromosome)) + return fitness_scores + + def parents_selection(population, fitness_scores): + selected_parents = [] + for _ in range(len(population)): + candidates = random.sample(range(len(population)), 2) + fitness1 = fitness_scores[candidates[0]] + fitness2 = fitness_scores[candidates[1]] + selected_parent = population[candidates[0]] if fitness1 > fitness2 else population[candidates[1]] + selected_parents.append(selected_parent) + return selected_parents + + + + def david_crossover(parent1, parent2): + start_index = random.randint(1, len(parent1)-3) + end_index = random.randint(start_index+1, len(parent1)-2) + parent1_chain = parent1[start_index:end_index+1] + parent2_letters = [] + for trash in parent2[1:-1]: + if trash not in parent1_chain: + parent2_letters.append(trash) + child = [parent2[0]]+parent2_letters[0:start_index] + parent1_chain + parent2_letters[start_index:]+[parent2[-1]] + """ print('PARENTS: ') + print(parent1) + print(parent2) + print('CHILDS:') + print(child) """ + return child + + def mutation(chromosome): + index1 = random.randint(1, len(chromosome)-2) + index2 = random.randint(1, len(chromosome)-2) + chromosome[index1], chromosome[index2] = chromosome[index2], chromosome[index1] + return chromosome + + def genetic_algorithm(): + population = initialize_population() + for _ in range(num_generations): + fitness_scores = calculate_fitness(population) + parents = parents_selection(population, fitness_scores) + offspring = [] + for i in range(0, len(parents), 2): + parent1 = parents[i] + parent2 = parents[i+1] + child1 = david_crossover(parent1, parent2) + child2 = david_crossover(parent2, parent1) + offspring.extend([child1, child2]) + population = offspring + for i in range(len(population)): + if random.random() < mutation_rate: + population[i] = mutation(population[i]) + return population + + + best_route = None + best_length = float('inf') + population = genetic_algorithm() + for chromosome in population: + length = calculate_route_length(chromosome) + if length < best_length: + best_length = length + best_route = chromosome + + print("Permutation chosen: ", best_route) + print("Its length:", best_length) + permuted_list = perform_permutation(request_list, best_route[1:-1]) + + + + + + + + + + + + + + + + + diff --git a/main.py b/main.py index 2a5b1cc..157f5a4 100644 --- a/main.py +++ b/main.py @@ -7,6 +7,8 @@ import time from garbage_truck import GarbageTruck from heuristicfn import heuristicfn from map import randomize_map +from tree import apply_tree +from genetic import apply_genetic pygame.init() @@ -38,6 +40,8 @@ def main(): clock = pygame.time.Clock() run = True fields, priority_array, request_list, imgpath_array = randomize_map() + apply_tree(request_list) + apply_genetic(request_list) agent = GarbageTruck(0, 0, pygame.Rect(0, 0, 50, 50), 0, request_list, clf) # tworzenie pola dla agenta low_space = 0 while run: diff --git a/tree.py b/tree.py new file mode 100644 index 0000000..8ca867c --- /dev/null +++ b/tree.py @@ -0,0 +1,35 @@ +import pygame +from treelearn import treelearn +import loadmodel +from astar import astar +from state import State +import time +from garbage_truck import GarbageTruck +from heuristicfn import heuristicfn +from map import randomize_map +from heuristicfn import heuristicfn +import pygame as pg +import random +from request import Request + +def apply_tree(request_list): + + print("Przed zastosowaniem drzewa na liście jest śmieci: ", len(request_list)) + + for address in request_list: + r = [ + 0, + 0, + address.volume, + address.last_collection, + address.is_paid, + address.odour_intensity, + address.weight, + address.type + ] + clf = treelearn() + if clf.predict([r]) == False: + request_list.pop(request_list.index(address)) + + print("Po zastosowaniu drzewa na liście jest śmieci: ", len(request_list)) + return request_list