Merge pull request 'genetic -> master' (#4) from genetic into master
Reviewed-on: #4
This commit is contained in:
commit
3ae78c6ee5
24
GameModel.py
24
GameModel.py
@ -18,8 +18,10 @@ from data.Order import Order
|
||||
from data.enum.ItemType import ItemType
|
||||
from decision.Action import Action
|
||||
from decision.ActionType import ActionType
|
||||
from genetic_order.GeneticOrder import GeneticOrder
|
||||
from imageClasification.Classificator import image_classification
|
||||
from pathfinding.PathfinderOnStates import PathFinderOnStates, PathFinderState
|
||||
from tree.DecisionTree import DecisionTree
|
||||
from util.PathByEnum import PathByEnum
|
||||
from util.PathDefinitions import GridLocation, GridWithWeights
|
||||
|
||||
@ -179,8 +181,26 @@ class GameModel(Model):
|
||||
self.recognised_items.append(recognised)
|
||||
|
||||
if self.phase == Phase.CLIENT_SORTING:
|
||||
# TODO GENERICS SORTING
|
||||
sorted(self.orderList, key=lambda x: len(x.items))
|
||||
orders: [Order] = self.orderList
|
||||
tree: DecisionTree = DecisionTree()
|
||||
|
||||
# CLIENT RECOGNITION
|
||||
orders_with_prio = tree.get_data_good(orders)
|
||||
|
||||
# print("before:" )
|
||||
# for i in range(len(orders_with_prio)):
|
||||
# print("ORDER {}, PRIO: {}".format(orders_with_prio[i].id, orders_with_prio[i].priority))
|
||||
|
||||
# GENERICS SORTING
|
||||
genericOrder: GeneticOrder = GeneticOrder(orders_with_prio)
|
||||
new_orders = genericOrder.get_orders_sorted(orders)
|
||||
|
||||
# print("after:" )
|
||||
# for i in range(len(new_orders)):
|
||||
# print("ORDER {}, PRIO: {}".format(new_orders[i].id, new_orders[i].priority))
|
||||
|
||||
self.orderList = new_orders
|
||||
|
||||
print("FINISHED CLIENT ORDER SORTING")
|
||||
self.phase = Phase.EXECUTION
|
||||
|
||||
|
@ -3,6 +3,7 @@ import random
|
||||
from data.Item import Item
|
||||
from data.Order import Order
|
||||
from data.enum.ItemType import ItemType
|
||||
from data.enum.Priority import Priority
|
||||
from util.ClientParamsFactory import ClientParamsFactory
|
||||
|
||||
|
||||
@ -24,6 +25,38 @@ class InitialStateFactory:
|
||||
|
||||
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, 3)
|
||||
type = Priority.LOW
|
||||
if x == 0:
|
||||
type = Priority.MEDIUM
|
||||
elif x == 1:
|
||||
type = Priority.HIGH
|
||||
|
||||
x = random.randint(20, 300)
|
||||
|
||||
return Order(final_time, items, type, x, client_params)
|
||||
|
||||
@staticmethod
|
||||
def __generate_order() -> Order:
|
||||
order_size = random.randint(1, 4)
|
||||
@ -37,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):
|
||||
|
@ -1,5 +1,7 @@
|
||||
from typing import Dict
|
||||
|
||||
from data.Item import Item
|
||||
from data.Order import Order
|
||||
from data.enum.ItemType import ItemType
|
||||
from util.PathDefinitions import GridLocation
|
||||
|
||||
@ -9,16 +11,10 @@ class GameConstants:
|
||||
self,
|
||||
grid_width: int,
|
||||
grid_height: int,
|
||||
# delivery_pos: GridLocation,
|
||||
# order_pos: GridLocation,
|
||||
# special_positions: Dict[ItemType, GridLocation],
|
||||
walls: [GridLocation],
|
||||
diffTerrain: [GridLocation]
|
||||
):
|
||||
self.grid_width = grid_width
|
||||
self.grid_height = grid_height
|
||||
# self.delivery_pos = delivery_pos
|
||||
# self.order_pos = order_pos
|
||||
# self.special_positions = special_positions
|
||||
self.walls = walls
|
||||
self.diffTerrain = diffTerrain
|
||||
|
@ -9,12 +9,18 @@ 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 = sum
|
||||
|
||||
# def sum_items(self, items: [Item]):
|
||||
# result = 0
|
||||
# for i in range(len(items)):
|
||||
# result += items[i]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "items: {} priority: {}".format(self.items, self.priority)
|
||||
|
7
data/enum/GeneticMutationType.py
Normal file
7
data/enum/GeneticMutationType.py
Normal file
@ -0,0 +1,7 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class GeneticMutationType(Enum):
|
||||
MUTATION = 1
|
||||
CROSS = 2
|
||||
REVERSE = 3
|
@ -1,6 +1,7 @@
|
||||
from data.enum.Direction import Direction
|
||||
from data.Item import Item
|
||||
from data.Order import Order
|
||||
from data.enum.Priority import Priority
|
||||
from decision.ActionType import ActionType
|
||||
from util.PathDefinitions import GridLocation
|
||||
|
||||
@ -10,7 +11,7 @@ class State:
|
||||
action_taken: ActionType,
|
||||
forklift_position: GridLocation,
|
||||
forklift_rotation: Direction,
|
||||
pending_orders: [Order],
|
||||
pending_orders: [Priority, [Order]],
|
||||
filled_orders: [Order],
|
||||
input_items: [Item]
|
||||
):
|
||||
|
9
decision/test/ForkliftActions.py
Normal file
9
decision/test/ForkliftActions.py
Normal file
@ -0,0 +1,9 @@
|
||||
from data.GameConstants import GameConstants
|
||||
|
||||
|
||||
class ForkliftActions:
|
||||
|
||||
def __init__(self, game: GameConstants,
|
||||
) -> None:
|
||||
self.game = game
|
||||
|
218
genetic_order/GeneticOrder.py
Normal file
218
genetic_order/GeneticOrder.py
Normal file
@ -0,0 +1,218 @@
|
||||
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 = 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 = 500
|
||||
punish_med = 300
|
||||
|
||||
punish_sum = 50
|
||||
|
||||
def __init__(self, orders: [Order]) -> None:
|
||||
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 y - x > 2 or 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 correct_sum(self, last_prio: Priority, last_sum: float, o: Order) -> bool:
|
||||
if o.priority == last_prio:
|
||||
return last_sum > o.sum / o.time
|
||||
return True
|
||||
|
||||
def sum_wrong(self, member: [int]) -> int:
|
||||
last_high = 0
|
||||
last_med = 0
|
||||
last_prio = Priority.HIGH
|
||||
last_sum = 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
|
||||
|
||||
if not self.correct_sum(last_prio, last_sum, o):
|
||||
counter += int(last_sum - (o.sum / o.time))
|
||||
last_prio = o.priority
|
||||
last_sum = o.sum / o.time
|
||||
|
||||
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]]
|
||||
#
|
||||
# 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)
|
||||
|
||||
# return result
|
||||
|
||||
return self.sum_wrong(member)
|
||||
|
||||
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 = []
|
||||
|
||||
for i in range(len(population) - self.best_fit_special - self.best_fit_super_special):
|
||||
result.append(population[i])
|
||||
|
||||
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
|
||||
|
||||
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
|
70
main.py
70
main.py
@ -1,3 +1,4 @@
|
||||
import math
|
||||
import random
|
||||
|
||||
from mesa.visualization.ModularVisualization import ModularServer
|
||||
@ -5,11 +6,16 @@ from mesa.visualization.modules import CanvasGrid
|
||||
|
||||
from ForkliftAgent import ForkliftAgent
|
||||
from GameModel import GameModel
|
||||
from InitialStateFactory import InitialStateFactory
|
||||
from PatchAgent import PatchAgent
|
||||
from PatchType import PatchType
|
||||
from PictureVisualizationAgent import PictureVisualizationAgent
|
||||
from data.Order import Order
|
||||
from data.enum.Direction import Direction
|
||||
from tensorflow import keras
|
||||
|
||||
from data.enum.Priority import Priority
|
||||
from genetic_order.GeneticOrder import GeneticOrder
|
||||
from util.PathDefinitions import GridWithWeights
|
||||
from visualization.DisplayAttributeElement import DisplayAttributeElement
|
||||
from visualization.DisplayItemListAttribute import DisplayItemListAttributeElement
|
||||
@ -94,7 +100,69 @@ if __name__ == '__main__':
|
||||
[grid, readyText, provided_itesm, recognised_items, ordersText,
|
||||
fulfilled_orders],
|
||||
"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=20, classificator=model))
|
||||
|
||||
# def order_rule(order: Order):
|
||||
# return order.id
|
||||
#
|
||||
#
|
||||
# punish_low = 500
|
||||
# punish_med = 300
|
||||
# def sum_wrong(member: [Order]) -> int:
|
||||
# last_high = 0
|
||||
# last_med = 0
|
||||
#
|
||||
# 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)
|
||||
# punish_low = test.punish_low
|
||||
# punish_med = test.punish_med
|
||||
#
|
||||
# print("SIEMA before: ")
|
||||
# sum_wrong(orders)
|
||||
# for i in orders:
|
||||
# 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 after:")
|
||||
# sum_wrong(newOrders)
|
||||
# for i in newOrders:
|
||||
# print("id:", i.id, "priority:", i.priority, "sum/time:", i.sum/i.time)
|
||||
# # print("id:", i.id, "priority:", i.priority)
|
||||
|
||||
server.port = 8888
|
||||
server.launch()
|
||||
|
@ -1,11 +1,17 @@
|
||||
import csv
|
||||
|
||||
import numpy as np
|
||||
import pandas
|
||||
import sklearn
|
||||
from sklearn import metrics, preprocessing
|
||||
from sklearn.model_selection import train_test_split
|
||||
from sklearn.tree import DecisionTreeClassifier
|
||||
|
||||
from InitialStateFactory import InitialStateFactory
|
||||
from data.ClientParams import ClientParams
|
||||
from data.Order import Order
|
||||
from data.enum.CompanySize import CompanySize
|
||||
from data.enum.Priority import Priority
|
||||
from util.ClientParamsFactory import ClientParamsFactory
|
||||
|
||||
|
||||
@ -58,6 +64,63 @@ class DecisionTree:
|
||||
print("\nDecisionTrees's Accuracy: ", metrics.accuracy_score(y, prediction))
|
||||
|
||||
|
||||
def get_data_good(self, orders: [Order]) -> [Order]:
|
||||
|
||||
n_array_input = []
|
||||
for i in range(len(orders)):
|
||||
o:Order = orders[i]
|
||||
cp: ClientParams = o.client_params
|
||||
pom = []
|
||||
|
||||
pom.append(cp.payment_delay)
|
||||
pom.append(cp.payed)
|
||||
pom.append(cp.net_worth)
|
||||
pom.append(cp.infuence_rate)
|
||||
pom.append(cp.is_skarbowka)
|
||||
pom.append(cp.membership)
|
||||
pom.append(cp.is_hat)
|
||||
|
||||
size: CompanySize = cp.company_size
|
||||
if(size == CompanySize.NO):
|
||||
pom.append(0)
|
||||
if (size == CompanySize.SMALL):
|
||||
pom.append(1)
|
||||
if (size == CompanySize.NORMAL):
|
||||
pom.append(2)
|
||||
if (size == CompanySize.BIG):
|
||||
pom.append(3)
|
||||
if (size == CompanySize.HUGE):
|
||||
pom.append(4)
|
||||
if (size == CompanySize.GIGANTISHE):
|
||||
pom.append(5)
|
||||
|
||||
|
||||
|
||||
n_array_input.append(pom)
|
||||
|
||||
n_array = np.array(n_array_input)
|
||||
# print(n_array)
|
||||
|
||||
# print(n_array[0])
|
||||
tree = self.get_decision_tree()
|
||||
priority = tree.predict(n_array)
|
||||
|
||||
|
||||
for i in range(len(orders)):
|
||||
print(orders[i].priority)
|
||||
orders[i].priority = priority[i]
|
||||
|
||||
if priority[i] == "LOW":
|
||||
orders[i].priority = Priority.LOW
|
||||
if priority[i] == "MEDIUM":
|
||||
orders[i].priority = Priority.MEDIUM
|
||||
if priority[i] == "HIGH":
|
||||
orders[i].priority = Priority.HIGH
|
||||
|
||||
print(orders[i].priority)
|
||||
|
||||
|
||||
return orders
|
||||
|
||||
|
||||
def get_decision_tree(self) -> DecisionTreeClassifier:
|
||||
@ -72,15 +135,25 @@ class DecisionTree:
|
||||
|
||||
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, train_size=0.8)
|
||||
|
||||
# print(len(X_train[0]))
|
||||
# print(X_train[0])
|
||||
|
||||
drugTree = DecisionTreeClassifier(criterion="entropy", max_depth=4)
|
||||
|
||||
clf = drugTree.fit(X_train, y_train)
|
||||
predicted = drugTree.predict(X_test)
|
||||
|
||||
# print(type(X_test))
|
||||
|
||||
y_test = y_test.to_list()
|
||||
|
||||
self.print_logs(X_test, y_test, predicted)
|
||||
# self.print_logs(X_test, y_test, predicted)
|
||||
|
||||
print(sklearn.tree.export_text(clf, feature_names=X_headers))
|
||||
# print(sklearn.tree.export_text(clf, feature_names=X_headers))
|
||||
|
||||
return drugTree
|
||||
return drugTree
|
||||
|
||||
|
||||
|
||||
# kurwa = DecisionTree()
|
||||
# kurwa.get_data_good(InitialStateFactory.generate_order_list(50))
|
Loading…
Reference in New Issue
Block a user