genetic -> master #4

Merged
s464943 merged 4 commits from genetic into master 2022-06-09 22:05:44 +02:00
4 changed files with 123 additions and 63 deletions
Showing only changes of commit 5cb4dee25e - Show all commits

View File

@ -46,14 +46,16 @@ class InitialStateFactory:
client_params = ClientParamsFactory.get_client_params() client_params = ClientParamsFactory.get_client_params()
x = random.randint(0, 2) x = random.randint(0, 3)
type = Priority.LOW type = Priority.LOW
if x == 0: if x == 0:
type = Priority.MEDIUM type = Priority.MEDIUM
elif x == 2: elif x == 1:
type = Priority.HIGH 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 @staticmethod
def __generate_order() -> Order: def __generate_order() -> Order:
@ -68,7 +70,7 @@ class InitialStateFactory:
client_params = ClientParamsFactory.get_client_params() 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 @staticmethod
def generate_input_sequence(self, input_sequence_size): def generate_input_sequence(self, input_sequence_size):

View File

@ -9,13 +9,13 @@ from data.enum.Priority import Priority
class Order: class Order:
id_counter = count(start=0) 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.id = next(self.id_counter)
self.time = time self.time = time
self.items: List[Item] = items self.items: List[Item] = items
self.client_params = client_params self.client_params = client_params
self.priority = priority self.priority = priority
self.sum = 0 self.sum = sum
# def sum_items(self, items: [Item]): # def sum_items(self, items: [Item]):
# result = 0 # result = 0

View File

@ -7,24 +7,29 @@ from data.enum.Priority import Priority
class GeneticOrder: class GeneticOrder:
mutation_chance = 50 mutation_chance = 10
reverse_chance = 20 reverse_chance = 60
cross_chance = 10 cross_chance = 5
best_fit_special = 40
best_fit_special_2 = 20 best_fit_special = 50
population_size = 500 best_fit_super_special = 20
population_size = 200
number_of_populations = 1000
punish_low = 5
punish_med = 3
def __init__(self, orders: [Order]) -> None: def __init__(self, orders: [Order]) -> None:
self.number_of_populations = 10000
self.orders = orders self.orders = orders
def get_mutation_type(self) -> GeneticMutationType: def get_mutation_type(self) -> GeneticMutationType:
x = random.randint(0, self.mutation_chance + self.cross_chance + self.reverse_chance) 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 return GeneticMutationType.MUTATION
if (x > self.mutation_chance + self.cross_chance): if x > self.mutation_chance + self.cross_chance:
return GeneticMutationType.REVERSE return GeneticMutationType.REVERSE
return GeneticMutationType.CROSS return GeneticMutationType.CROSS
@ -59,7 +64,7 @@ class GeneticOrder:
def reverse(self, population: [int]) -> [int]: def reverse(self, population: [int]) -> [int]:
x = random.randint(0, len(population)) x = random.randint(0, len(population))
y = random.randint(0, len(population)-1) y = random.randint(0, len(population)-1)
while x >= y: while y - x > 2 or x >= y:
x = random.randint(0, len(population)) x = random.randint(0, len(population))
y = random.randint(0, len(population) - 1) y = random.randint(0, len(population) - 1)
@ -92,18 +97,48 @@ class GeneticOrder:
# #
# return [list(x) for x in result] # 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: def evaluate(self, member: [int]) -> int:
result = 0 # result = 0
for i in range(len(self.orders) - 1): # for i in range(len(self.orders) - 1):
x: Order = self.orders[member[i]] # x: Order = self.orders[member[i]]
y: Order = self.orders[member[i + 1]] # 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): # return result
result += 5000
elif x.sum / x.time < y.sum / y.time:
result += y.sum * 5 + y.time
return result return self.sum_wrong(member)
def mutate_population(self, order_population: [[int]]) -> [[int]]: def mutate_population(self, order_population: [[int]]) -> [[int]]:
result = [] result = []
@ -126,20 +161,16 @@ class GeneticOrder:
def get_next_population(self, population: [[int]]) -> [[int]]: def get_next_population(self, population: [[int]]) -> [[int]]:
result = [] 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): for i in range(self.best_fit_special):
# result.append(population[i]) x = random.randint(0, self.best_fit_special)
# result.append(population[x])
# k = len(population) - self.best_fit_special
# while k < len(population) - self.best_fit_special_2: for i in range(self.best_fit_super_special):
# n = random.randint(0, self.best_fit_special) x = random.randint(0, self.best_fit_super_special)
# result.append(population[n]) result.append(population[x])
#
# left_size = len(population) - k
# while left_size < len(population):
# n = random.randint(0, self.best_fit_special_2)
# result.append(population[n])
return result return result
@ -147,7 +178,7 @@ class GeneticOrder:
self.orders = orders self.orders = orders
population: [[int]] = self.generate_first_population(self.population_size) population: [[int]] = self.generate_first_population(self.population_size)
print(population) # print(population)
population.sort(key=self.evaluate) population.sort(key=self.evaluate)
best_fit: [int] = population[0] best_fit: [int] = population[0]

73
main.py
View File

@ -1,3 +1,4 @@
import math
import random import random
from mesa.visualization.ModularVisualization import ModularServer from mesa.visualization.ModularVisualization import ModularServer
@ -101,42 +102,68 @@ if __name__ == '__main__':
"Automatyczny Wózek Widłowy", "Automatyczny Wózek Widłowy",
dict(width=gridHeight, height=gridWidth, graph=diagram, items=50, orders=3, classificator=model)) 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 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): punish_low = 5
result += 5000 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) orders = InitialStateFactory.generate_order_list_XD(20)
test: GeneticOrder = GeneticOrder(orders) 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: # 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) newOrders = test.get_orders_sorted(orders)
print("NAURA:", evaluate(newOrders)) print("NAURA after:")
sum_wrong(newOrders)
# for i in 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 # server.port = 8888