This commit is contained in:
xVulpeSx 2022-06-07 01:07:49 +02:00
parent 566a8cd868
commit 53cf8c9937
8 changed files with 277 additions and 9 deletions

View File

@ -3,6 +3,7 @@ import random
from data.Item import Item from data.Item import Item
from data.Order import Order from data.Order import Order
from data.enum.ItemType import ItemType from data.enum.ItemType import ItemType
from data.enum.Priority import Priority
from util.ClientParamsFactory import ClientParamsFactory from util.ClientParamsFactory import ClientParamsFactory
@ -24,6 +25,36 @@ class InitialStateFactory:
return order_list return order_list
@staticmethod
def generate_order_list_XD(output_order_list_size: int):
order_list: [Order] = []
for i in range(output_order_list_size):
order_list.append(InitialStateFactory.__generate_order_XD())
return order_list
@staticmethod
def __generate_order_XD() -> Order:
order_size = random.randint(1, 4)
items: [Item] = []
for i in range(order_size):
items.append(InitialStateFactory.__generate_item())
time_base = random.randint(8, 20)
final_time = time_base * order_size
client_params = ClientParamsFactory.get_client_params()
x = random.randint(0, 2)
type = Priority.LOW
if x == 0:
type = Priority.MEDIUM
elif x == 2:
type = Priority.HIGH
return Order(final_time, items, type, client_params)
@staticmethod @staticmethod
def __generate_order() -> Order: def __generate_order() -> Order:
order_size = random.randint(1, 4) order_size = random.randint(1, 4)

View File

@ -1,5 +1,7 @@
from typing import Dict from typing import Dict
from data.Item import Item
from data.Order import Order
from data.enum.ItemType import ItemType from data.enum.ItemType import ItemType
from util.PathDefinitions import GridLocation from util.PathDefinitions import GridLocation
@ -9,16 +11,10 @@ class GameConstants:
self, self,
grid_width: int, grid_width: int,
grid_height: int, grid_height: int,
# delivery_pos: GridLocation,
# order_pos: GridLocation,
# special_positions: Dict[ItemType, GridLocation],
walls: [GridLocation], walls: [GridLocation],
diffTerrain: [GridLocation] diffTerrain: [GridLocation]
): ):
self.grid_width = grid_width self.grid_width = grid_width
self.grid_height = grid_height self.grid_height = grid_height
# self.delivery_pos = delivery_pos
# self.order_pos = order_pos
# self.special_positions = special_positions
self.walls = walls self.walls = walls
self.diffTerrain = diffTerrain self.diffTerrain = diffTerrain

View File

@ -15,6 +15,12 @@ class Order:
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
# def sum_items(self, items: [Item]):
# result = 0
# for i in range(len(items)):
# result += items[i]
def __repr__(self) -> str: def __repr__(self) -> str:
return "items: {} priority: {}".format(self.items, self.priority) return "items: {} priority: {}".format(self.items, self.priority)

View File

@ -0,0 +1,7 @@
from enum import Enum
class GeneticMutationType(Enum):
MUTATION = 1
CROSS = 2
REVERSE = 3

View File

@ -1,6 +1,7 @@
from data.enum.Direction import Direction from data.enum.Direction import Direction
from data.Item import Item from data.Item import Item
from data.Order import Order from data.Order import Order
from data.enum.Priority import Priority
from decision.ActionType import ActionType from decision.ActionType import ActionType
from util.PathDefinitions import GridLocation from util.PathDefinitions import GridLocation
@ -10,7 +11,7 @@ class State:
action_taken: ActionType, action_taken: ActionType,
forklift_position: GridLocation, forklift_position: GridLocation,
forklift_rotation: Direction, forklift_rotation: Direction,
pending_orders: [Order], pending_orders: [Priority, [Order]],
filled_orders: [Order], filled_orders: [Order],
input_items: [Item] input_items: [Item]
): ):

View File

@ -0,0 +1,9 @@
from data.GameConstants import GameConstants
class ForkliftActions:
def __init__(self, game: GameConstants,
) -> None:
self.game = game

View File

@ -0,0 +1,175 @@
import itertools
import random
from data.Order import Order
from data.enum.GeneticMutationType import GeneticMutationType
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
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):
return GeneticMutationType.MUTATION
if (x > self.mutation_chance + self.cross_chance):
return GeneticMutationType.REVERSE
return GeneticMutationType.CROSS
def mutation(self, population: [int]) -> [int]:
x = random.randint(0, len(population)-1)
y = random.randint(0, len(population)-1)
while x == y:
y = random.randint(0, len(population)-1)
result = population
pom = population[x]
result[x] = population[y]
result[y] = pom
if(result[x] == result[y]):
print("PIZDA I CHUJ")
return result
def cross(self, population: [int]) -> [int]:
x = random.randint(1, len(population)-1)
result = []
for i in range(len(population)):
result.append(population[(i + x) % len(population)])
return result
def reverse(self, population: [int]) -> [int]:
x = random.randint(0, len(population))
y = random.randint(0, len(population)-1)
while x >= y:
x = random.randint(0, len(population))
y = random.randint(0, len(population)-1)
result = []
# print("X: ", x, " y: ", y)
for i in range(len(population)):
if x <= i <= y:
new_i = i - x
# print("len:", len(population), " new_i: ", new_i)
result.append(population[y - new_i])
else:
result.append(population[i])
return result
def generate_first_population(self, k: int) -> [[int]]:
result = []
s = range(len(self.orders))
p = itertools.permutations(s)
while len(result) < k:
n = p.__next__()
if n not in result:
result.append(n)
return [list(x) for x in result]
# result = itertools.permutations(range(len(self.orders)))
#
# return [list(x) for x in result]
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]]
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
def mutate_population(self, order_population: [[int]]) -> [[int]]:
result = []
for i in range(len(order_population)):
member: [int] = order_population[i]
operation: GeneticMutationType = self.get_mutation_type()
if operation == GeneticMutationType.MUTATION:
member = self.mutation(member)
elif operation == GeneticMutationType.REVERSE:
member = self.reverse(member)
else:
member = self.cross(member)
result.append(member)
return result
def get_next_population(self, population: [[int]]) -> [[int]]:
result = []
result = population
# 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])
return result
def get_orders_sorted(self, orders: [Order]) -> [Order]:
self.orders = orders
population: [[int]] = self.generate_first_population(self.population_size)
print(population)
population.sort(key=self.evaluate)
best_fit: [int] = population[0]
for i in range(self.number_of_populations):
# print("population: ", i)
population = self.mutate_population(population)
population.sort(key=self.evaluate)
if self.evaluate(best_fit) > self.evaluate(population[0]):
best_fit = population[0]
# population = self.get_next_population(population).sort(key=self.evaluate)
if self.evaluate(best_fit) < self.evaluate(population[0]):
population[0] = best_fit
best: [int] = population[0]
result: [Order] = []
for i in range(len(best)):
result.append(self.orders[best[i]])
return result

47
main.py
View File

@ -5,11 +5,16 @@ from mesa.visualization.modules import CanvasGrid
from ForkliftAgent import ForkliftAgent from ForkliftAgent import ForkliftAgent
from GameModel import GameModel from GameModel import GameModel
from InitialStateFactory import InitialStateFactory
from PatchAgent import PatchAgent from PatchAgent import PatchAgent
from PatchType import PatchType from PatchType import PatchType
from PictureVisualizationAgent import PictureVisualizationAgent from PictureVisualizationAgent import PictureVisualizationAgent
from data.Order import Order
from data.enum.Direction import Direction from data.enum.Direction import Direction
from tensorflow import keras from tensorflow import keras
from data.enum.Priority import Priority
from genetic_order.GeneticOrder import GeneticOrder
from util.PathDefinitions import GridWithWeights from util.PathDefinitions import GridWithWeights
from visualization.DisplayAttributeElement import DisplayAttributeElement from visualization.DisplayAttributeElement import DisplayAttributeElement
from visualization.DisplayItemListAttribute import DisplayItemListAttributeElement from visualization.DisplayItemListAttribute import DisplayItemListAttributeElement
@ -96,5 +101,43 @@ 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))
server.port = 8888 def pizda(order: Order):
server.launch() 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
return result
orders = InitialStateFactory.generate_order_list_XD(20)
test: GeneticOrder = GeneticOrder(orders)
print("SIEMA: ", evaluate(orders))
# for i in orders:
# print("id: {}, priority: {}", i.id, i.priority)
newOrders = test.get_orders_sorted(orders)
print("NAURA:", evaluate(newOrders))
# for i in newOrders:
# print("id: {}, priority: {}", i.id, 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.launch()