From 5cb4dee25ec84892f4275cb6406dc291c81717a1 Mon Sep 17 00:00:00 2001 From: xVulpeSx Date: Tue, 7 Jun 2022 23:15:04 +0200 Subject: [PATCH] wip -> working genetic sorting --- InitialStateFactory.py | 10 ++-- data/Order.py | 4 +- genetic_order/GeneticOrder.py | 99 +++++++++++++++++++++++------------ main.py | 73 ++++++++++++++++++-------- 4 files changed, 123 insertions(+), 63 deletions(-) diff --git a/InitialStateFactory.py b/InitialStateFactory.py index f147bc9..1289f0c 100644 --- a/InitialStateFactory.py +++ b/InitialStateFactory.py @@ -46,14 +46,16 @@ class InitialStateFactory: client_params = ClientParamsFactory.get_client_params() - x = random.randint(0, 2) + x = random.randint(0, 3) type = Priority.LOW if x == 0: type = Priority.MEDIUM - elif x == 2: + elif x == 1: type = Priority.HIGH - return Order(final_time, items, type, client_params) + x = random.randint(20, 300) + + return Order(final_time, items, type, x, client_params) @staticmethod def __generate_order() -> Order: @@ -68,7 +70,7 @@ class InitialStateFactory: client_params = ClientParamsFactory.get_client_params() - return Order(final_time, items, None, client_params) + return Order(final_time, items, Priority.LOW, 0, client_params) @staticmethod def generate_input_sequence(self, input_sequence_size): diff --git a/data/Order.py b/data/Order.py index 0e05d3a..1ed3763 100644 --- a/data/Order.py +++ b/data/Order.py @@ -9,13 +9,13 @@ from data.enum.Priority import Priority class Order: id_counter = count(start=0) - def __init__(self, time: int, items: [Item], priority: Priority, client_params: ClientParams): + def __init__(self, time: int, items: [Item], priority: Priority, sum: int, client_params: ClientParams): self.id = next(self.id_counter) self.time = time self.items: List[Item] = items self.client_params = client_params self.priority = priority - self.sum = 0 + self.sum = sum # def sum_items(self, items: [Item]): # result = 0 diff --git a/genetic_order/GeneticOrder.py b/genetic_order/GeneticOrder.py index fe1c311..dbc53b6 100644 --- a/genetic_order/GeneticOrder.py +++ b/genetic_order/GeneticOrder.py @@ -7,24 +7,29 @@ from data.enum.Priority import Priority class GeneticOrder: - mutation_chance = 50 - reverse_chance = 20 - cross_chance = 10 - best_fit_special = 40 - best_fit_special_2 = 20 - population_size = 500 + mutation_chance = 10 + reverse_chance = 60 + cross_chance = 5 + + best_fit_special = 50 + best_fit_super_special = 20 + + population_size = 200 + number_of_populations = 1000 + + punish_low = 5 + punish_med = 3 def __init__(self, orders: [Order]) -> None: - self.number_of_populations = 10000 self.orders = orders def get_mutation_type(self) -> GeneticMutationType: x = random.randint(0, self.mutation_chance + self.cross_chance + self.reverse_chance) - if (x < self.mutation_chance): + if x < self.mutation_chance: return GeneticMutationType.MUTATION - if (x > self.mutation_chance + self.cross_chance): + if x > self.mutation_chance + self.cross_chance: return GeneticMutationType.REVERSE return GeneticMutationType.CROSS @@ -59,9 +64,9 @@ class GeneticOrder: def reverse(self, population: [int]) -> [int]: x = random.randint(0, len(population)) y = random.randint(0, len(population)-1) - while x >= y: + while y - x > 2 or x >= y: x = random.randint(0, len(population)) - y = random.randint(0, len(population)-1) + y = random.randint(0, len(population) - 1) result = [] # print("X: ", x, " y: ", y) @@ -92,18 +97,48 @@ class GeneticOrder: # # return [list(x) for x in result] + def sum_wrong(self, member: [int]) -> int: + last_high = 0 + last_med = 0 + counter = 0 + + for i in range(len(member)): + o: Order = self.orders[member[i]] + if o.priority == Priority.HIGH : + last_high = i + elif o.priority == Priority.MEDIUM: + last_med = i + + for i in range(last_high): + o: Order = self.orders[member[i]] + if o.priority == Priority.MEDIUM: + counter += self.punish_med + elif o.priority == Priority.LOW: + counter += self.punish_low + + for i in range(last_med): + o: Order = self.orders[member[i]] + if o.priority == Priority.LOW: + counter += self.punish_low + + return counter + + def evaluate(self, member: [int]) -> int: - result = 0 - for i in range(len(self.orders) - 1): - x: Order = self.orders[member[i]] - y: Order = self.orders[member[i + 1]] + # result = 0 + # for i in range(len(self.orders) - 1): + # x: Order = self.orders[member[i]] + # y: Order = self.orders[member[i + 1]] + # + # if ((x.priority == Priority.MEDIUM or x.priority == Priority.LOW) and y.priority == Priority.HIGH) or (x.priority == Priority.LOW and y.priority == Priority.MEDIUM): + # result += 30 + # + # if x.sum / x.time < y.sum / y.time: + # result += int(y.sum / y.time) - if ((x.priority == Priority.MEDIUM or x.priority == Priority.LOW) and y.priority == Priority.HIGH) or (x.priority == Priority.LOW and y.priority == Priority.MEDIUM): - result += 5000 - elif x.sum / x.time < y.sum / y.time: - result += y.sum * 5 + y.time + # return result - return result + return self.sum_wrong(member) def mutate_population(self, order_population: [[int]]) -> [[int]]: result = [] @@ -126,20 +161,16 @@ class GeneticOrder: def get_next_population(self, population: [[int]]) -> [[int]]: result = [] - result = population + for i in range(len(population) - self.best_fit_special - self.best_fit_super_special): + result.append(population[i]) - # for i in range(len(population) - self.best_fit_special): - # result.append(population[i]) - # - # k = len(population) - self.best_fit_special - # while k < len(population) - self.best_fit_special_2: - # n = random.randint(0, self.best_fit_special) - # result.append(population[n]) - # - # left_size = len(population) - k - # while left_size < len(population): - # n = random.randint(0, self.best_fit_special_2) - # result.append(population[n]) + for i in range(self.best_fit_special): + x = random.randint(0, self.best_fit_special) + result.append(population[x]) + + for i in range(self.best_fit_super_special): + x = random.randint(0, self.best_fit_super_special) + result.append(population[x]) return result @@ -147,7 +178,7 @@ class GeneticOrder: self.orders = orders population: [[int]] = self.generate_first_population(self.population_size) - print(population) + # print(population) population.sort(key=self.evaluate) best_fit: [int] = population[0] diff --git a/main.py b/main.py index 0e8914e..e56abcc 100644 --- a/main.py +++ b/main.py @@ -1,3 +1,4 @@ +import math import random from mesa.visualization.ModularVisualization import ModularServer @@ -101,42 +102,68 @@ if __name__ == '__main__': "Automatyczny Wózek Widłowy", dict(width=gridHeight, height=gridWidth, graph=diagram, items=50, orders=3, classificator=model)) - def pizda(order: Order): + def order_rule(order: Order): return order.id - def evaluate(member: [Order]) -> int: - result = 0 - for i in range(len(member) - 1): - x: Order = member[i] - y: Order = member[i + 1] - if ((x.priority == Priority.MEDIUM or x.priority == Priority.LOW) and y.priority == Priority.HIGH) or (x.priority == Priority.LOW and y.priority == Priority.MEDIUM): - result += 5000 + punish_low = 5 + punish_med = 3 + def sum_wrong(member: [Order]) -> int: + last_high = 0 + last_med = 0 - return result + sum_high = 0 + sum_med = 0 + sum_low = 0 + + counter = 0 + + for i in range(len(member)): + o: Order = member[i] + if o.priority == Priority.HIGH : + sum_high += 1 + last_high = i + elif o.priority == Priority.MEDIUM: + sum_med += 1 + last_med = i + else: + sum_low += 1 + + for i in range(last_high): + o: Order = member[i] + if o.priority == Priority.MEDIUM: + counter += punish_med + elif o.priority == Priority.LOW: + counter += punish_low + + for i in range(last_med): + o: Order = member[i] + if o.priority == Priority.LOW: + counter += punish_low + + print("sum: high:", sum_high, "med:", sum_med, "low:", sum_low) + print("last_high:", last_high, "last_med:", last_med, "sum:", counter) + return counter orders = InitialStateFactory.generate_order_list_XD(20) test: GeneticOrder = GeneticOrder(orders) - print("SIEMA: ", evaluate(orders)) + punish_low = test.punish_low + punish_med = test.punish_med + + print("SIEMA before: ") + sum_wrong(orders) # for i in orders: - # print("id: {}, priority: {}", i.id, i.priority) + # # print("id:", i.id, "priority:", i.priority, "sum/time:", i.sum/i.time) + # print("id:", i.id, "priority:", i.priority) newOrders = test.get_orders_sorted(orders) - print("NAURA:", evaluate(newOrders)) + print("NAURA after:") + sum_wrong(newOrders) # for i in newOrders: - # print("id: {}, priority: {}", i.id, i.priority) + # # print("id:", i.id, "priority:", i.priority, "sum/time:", i.sum/i.time) + # print("id:", i.id, "priority:", i.priority) - # orders.sort(key=pizda) - # newOrders.sort(key=pizda) - # - # print("SIEMA:") - # for i in orders: - # print("id: {}, priority: {}", i.id, i.priority) - # - # print("NAURA:") - # for i in newOrders: - # print("id: {}, priority: {}", i.id, i.priority) # server.port = 8888