Compare commits

..

2 Commits

Author SHA1 Message Date
andrzej
32c80c0c0e Dodanie funkcji h(start, goal) 2020-04-26 22:05:27 +02:00
andrzej
1e265ec281 Wyłączenie ruchu demo, szkielet szkieletu szukania ścieżki 2020-04-26 19:57:00 +02:00
29 changed files with 190 additions and 1926 deletions

View File

@ -1,141 +0,0 @@
## Podprojekt: drzewa decyzyjne
### Andrzej Preibisz
#### Opis problemu
Metodą uczenia, którą postanowiłem zaimplementować w projekcie były
drzewa decyzyjne. Pola reprezentujące regały, lub chłodziarki
różnią się między sobą temperaturą, oraz wilgotnością powietrza w danym miejscu.
Paczki z kolei mogą zawierać towary następujących rodzajów:
- towar zwykły(normal)
- mrożony(freezed)
- kruchy(fragile)
- łatwo niszczejący pod wpływem wilgoci (keep_dry)
- łatwopalne(flammable)
Paczki zawierające określony rodzaj towarów mają pewne parametry
środowiskowe, w których zdecydowanie nie powinno się danego typu towaru
przechowywać. Jako przykład może posłużyć mrożone jedzenie, którego stan
stosunkowo szybko ulegnie pogorszeniu w temperaturze dodatniej, lub lakier,
który zdecydowanie nie powinien znaleźć się w części magazynu, gdzie panuje temperatura 30 stopni.
Celem drzewa decyzyjnego jest w tym wypadku przewidzenie prawdopodobnej szansy na to, że towar po przechowywaniu
na danym regale przez dłuższy czas będzie w dobrym stanie.
##### Zastosowane drzewo
Drzewa decyzyjne dzielą się ogólnie na dwa rodzaje - drzew klasyfikujących, lub drzew regresyjnych.
Drzewo klasyfikujące pozwala podzielić zmienna przewidywaną na kategorie, na przykład Tak i Nie.
Drzewo regresyjne z kolei dostarczy nam informacji o oczekiwanej wartości zmiennej estymowanej przy
danej wartości atrybutów.
W świecie projektu różny rodzaj towarów ma różne "progi", od których można go kłaść na regale X,
na przykład kładąc paczkę z lakierem/benzyną na regale lepiej mieć trochę większą pewność, że towar nie nagrzeje się nadmiernie, aniżeli
kładąc książkę - że nie zniszczeje od wilgoci. W związku z tym zamiast prostej odpowiedzi Tak/Nie na pytanie
czy dany obiekt można położyć na danym regale potrzebna była przewidywana wartość prawdopodobieństwa że w danym miejscu
zachowa się on w dobrym stanie. Wszystkie te progi wynoszą odpowiednio:
``` python
PACKAGE_PLACE_TRESHOLD = {
"normal": 0.8,
"freezed": 0.85,
"fragile": 0.85,
"flammable": 0.9,
"keep_dry": 0.8
}
```
Zdecydowałem się więc na wybór drzewa regresyjnego.
Biblioteką której użyłem w celu implementacji drzewa jest scikit-learn.
Najważniejszym problemem oprócz dokładności oszacowań dokonanych przy pomocy drzewa było uniknięcie overfittingu(przepasowania),
czyli sytuacji, w której drzewo perfekcyjnie dopasuje się do danych ze zbioru uczącego, jednak
z danymi spoza tego zbioru poradzi sobie już dużo gorzej. Oprócz błędnej oceny danych innych niż ze zbioru uczącego sygnałem wskazującym na overfitting drzewa
jest zbyt duża jego głębokość drzewa (odległość od korzenia do najdalszego liścia), oraz liście zawierające tylko 1 rekord.
W celu uniknięcia overfittingu zdecydowałem się na ograniczenie maksymalnej głębokości drzewa, oraz na ustawienie minimalnej
ilości rekordów w liściu. Drzewo wraz z odpowiednimi ograniczeniami zdefiniowane jest w następujący sposób
```python
clf = DecisionTreeRegressor(ccp_alpha=0.02, min_samples_leaf=5, max_depth=5)
```
gdzie argumenty min_samples_leaf, oraz max_depth oznaczają odpowiednio minimalną ilość rekordów(przykładów ze zbioru uczącego) w liściu, oraz maksymalną głębokość drzewa.
Argument ccp_alpha oznacza parametr \alpha stosowany przy complexity-cost pruning. Pruning oznacza dalsze przycięcie drzewa, aby uniknąć overfittingu
Kryterium według którego mierzona jest "jakość" rozgałęzienia jest tzw. MSE(Mean Squared Error), czyli błąd średniokwadratowy(średnia kwadratów odchylenia wielkości oczekiwanej od rzeczywistej).
Dobierając te parametry wyszedłem z założenia że jeżeli 5 rekordów będzie w jednym liściu, to znaczy że najprawdopodbniej zachodzi
już w ich przypadku pewna prawidłowość, i mają one jakieś wspólne cechy, które determinują taką, a nie inną wartość przewidywaną,
w odróżnieniu od sytuacji gdy liść zawierałby tylko 1-2 rekordy, co wskazywałoby na bardzo specyficzne parametry takiego/ich rekordu/ów,
i prawdopodobnie oznaczało overfitting drzewa. W przypadku głębokości chodziło o uniknięcie nadmiernego rozrostu drzewa.
Zastosowany zbiór uczący obejmuje 373 rekordy zapisane w formacie .csv, w którym poszczególne kolumny oznaczają odpowiednio:
produkt, kategorię produktu, temperature na regale, wilgotność powietrza na danym regale, szansę że przedmiot po dłuższym czasie przechowywania będzie w dobrym stanie, oraz informację czy można bezpiecznie go tu położyć.
Przykładowy rekord: ``frozen food,freezed,21, 0.5, 0.01, 0 `` . Zbiór testowy z kolei zawiera 26 rekordów w tym samym formacie.
Zbiór uczący znajduje się w pliku package_location_classifier/trainset/trainset.csv, a testowy package_location/testset/testset.csv.
Przygotowanie zbioru uczącego i testowego dla drzewa:
``` python
products = pd.read_csv("package_location_classifier/trainset/trainset.csv", header=0, sep=",", names=cols_names)
testset = pd.read_csv("package_location_classifier/testset/testset.csv", header=None, sep=",", names=cols_names)
products = products.round({"chance_of_survive": 1})
testset = testset.round({"chance_of_survive": 1})
products.chance_of_survive *= 10
testset.chance_of_survive *= 10
test_X = pd.get_dummies(testset[feature_cols])
test_y = testset.chance_of_survive
products = products.sample(frac=1)
X_train = pd.get_dummies(products[feature_cols])
y_train = products.chance_of_survive
```
Uczenie drzewa i ewaluacja przy pomocy zbioru testowego:
``` python
self.predictor = clf.fit(X_train, y_train)
y_pred = self.predictor.predict(test_X)
```
Graficzna reprezentacja drzewa wygenerowanego dla tego zbioru uczącego:
![Przykładowe drzewo](Drzewo.png)
Wyniki ewaluacji zestawu testowego, znajdujące się w pliku Test_results.xlsx:
![Wyniki testu](Test_Results.png)
Przewidywana wartość w zestawie testowym różni się od wartości faktycznej średnio o 0.87, jako że w raporcie wartości są pomnożone przez 10, daje to średnio
0.087 wartości różnicy w czasie działania drzewa.
##### Zastosowanie drzewa w części wspólnej projektu
Po podniesieniu paczki przez agenta odpalana jest funkcja szukająca najbliższego pasującego regału.
Przy poszukiwaniu takiego regału stosowana jest funkcja heurystyczna o następującym kodzie:
```python
def rack_heuristics(self, start, goal, can_place):
heur_can_place = not can_place
diff_x = pow(goal.x - start.x, 2)
diff_y = pow(goal.y - start.y, 2)
place_cost = 100 * float(heur_can_place)
return round(sqrt(diff_x + diff_y), 3) + float(place_cost)
```
Parametr can_place to wynik ewaluacji pola goal, przy pomocy drzewa:
```python
for rack in quarter_racks:
new_node = Node(rack.x_position, rack.y_position)
can_place = self.location_classifier.check_if_can_place(package, rack)
cost = self.rack_heuristics(start_node, new_node, can_place)
```
self.location_classifier, to obiekt klasy PackageLocationClassifier.
Klasa ta zawiera metodę check_if_can_place() :
```python
def check_if_can_place(self, package, tile):
category = package.category
cat_treshold = PACKAGE_PLACE_TRESHOLD[category]
fields = [[
tile.air_temperature,
tile.humidity,
category == "flammable",
category == "fragile",
category=="freezed" ,
category == "keep_dry",
category == "normal"
]]
quality_of_place = round(self.predictor.predict(fields)[0]/10, 2)
if quality_of_place > cat_treshold:
return True
return False
```
Self.predictor to nauczone drzewo.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 338 KiB

View File

@ -1,54 +0,0 @@
## Podprojekt: algorytm genetyczny
### Jakub Damiński
#### Opis problemu
Metodą uczenia, którą postanowiłem zaimplementować w projekcie był algorytm genetyczny. Zastosowalem go, by znaleźć najszybszą ścieżkę, którą może podążyć wózek widłowy pomiędzy paczkami, by przejechać w sumie jak najkrótszy dystans.
#### Metoda
Pierwszym krokiem jest zbudowanie grafu z wagami w którym wierzchołkami są paczki, regały na które te paczki mają trafić oraz punkt startowy wózka, a wagi krawędzi to odległości między nimi. Ponieważ środowisko opiera się na 2-wymiarowej powierzchni, gdzie nie ma odizolowanych pól jest to graf pełny. Graf zapisany jest w 2-wymiarowej tablicy.
Ponieważ wózek musi odwiedzić wszystkie paczki każde rozwiązanie tego problemu będzie permutacja zbioru tych paczek, przedstawiający, które paczki po kolei powinien wózek odwiedzić. Wartościowość takiego rozwiązania jest weryfikowana poprzez zsumowanie odległości jakie wózek musi przebyć do paczki oraz od paczki do jej wyznaczonego regału.
Wykorzystując algorytm genetyczny sprawimy, że spośród losowych permotacji zaczną wyłaniać się tej najbardziej efektywne, czyli te o najkrótszej ścieżce.
#### Zasada działania
Pierwszym krokiem jest zapełnienie populacji losowymi permutacjiami.
Następnie wykonuje się liczba iteracji w których najlepsze osobniki krzyżują się ze sobą tworzyć nowe permutacje wymianiając między sobą losową ilość elementów
```
def crossover(a, b):
new_a = copy.deepcopy(a)
new_b = copy.deepcopy(b)
for i in range(floor(len(a) / 2)):
rel = randrange(len(a))
tmp_a = new_a[rel]
tmp_b = new_b[rel]
if tmp_a == tmp_b:
continue
new_a[new_a.index(tmp_b)] = tmp_a
new_b[new_b.index(tmp_a)] = tmp_b
new_a[rel] = tmp_b
new_b[rel] = tmp_a
return new_a, new_b
```
Nowo stworzone osobniki mają następnie szansę na mutacje, która polega na zamienieniu dwóch losowych elementów ze sobą
```
def mutate(route):
new_route = copy.deepcopy(route)
for i in range(len(route) - 1):
if random() < mutation_probability:
tmp = new_route[i]
new_route[i] = new_route[i + 1]
new_route[i + 1] = tmp
return new_route
```
Następnym krokiem jest dodanie do populacji najlepszych osobników z poprzedniej populacji
```
for j in range(0, num_of_surviving):
new_population.append(population[scores[j][0]])
```
Po wykonaniu tych kroków do nowej populacji dodawane są zupelnie nowe soobniki by osiągną maksymalną ilość populacji
```
for j in range(max_population - (num_of_surviving + num_of_couples)):
new_population.append(create_new_route(packages))
```
Na koniec iteracji wszystkie permutacje są oceniane na podstawie tego ile wózkowi zajęło by przejechanie całej trasy

0
Readme.md Executable file → Normal file
View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

401
agent.py Executable file → Normal file
View File

@ -1,292 +1,159 @@
from warehouse import Coordinates, Tile, Pack
from attributes import PackStatus, TURN_LEFT_DIRECTIONS, TURN_RIGHT_DIRECTIONS
from queue import PriorityQueue
from math import sqrt, ceil
from attributes import TURN_LEFT_DIRECTIONS, TURN_RIGHT_DIRECTIONS, PackStatus
import pygame
import sys
import pdb
import numpy as np
from package_location_classifier.classifier import PackageLocationClassifier
from genetic_route import genetic_trace_route
from siec import imgSkan, imageClass
from keras.models import Sequential
class Node:
def __init__(self, coord_x, coord_y, package=None, is_rack=False):
self.x = coord_x
self.y = coord_y
self.parent = None
self.package = package
self.is_rack = is_rack
self.g_cost = 0
self.h_cost = 0
self.graph_map = None
def __eq__(self, other):
if isinstance(other, Node):
return self.x == other.x and self.y == other.y
return False
def __lt__(self, other):
return isinstance(other, Node) and self.g_cost < other.g_cost
def __repr__(self):
return "Node:{}x{}".format(self.x, self.y)
from pathfinder import Node
from math import sqrt
class Agent:
def __init__(self, start_x, start_y, assigned_warehouse, radius=5):
self.x = start_x
self.y = start_y
self.radius = radius
self.warehouse = assigned_warehouse
self.graph_map = np.zeros(((self.warehouse.no_of_packages * 2) + 1, (self.warehouse.no_of_packages * 2) + 1))
self.is_loaded = False
self.transported_package = None
self.direction = "up"
self.closed = list()
self.open = PriorityQueue()
self.path = list()
self.location_classifier = PackageLocationClassifier()
self.check_packages_locations()
self.route = []
self.destination = None
def __init__(self, start_x, start_y, assigned_warehouse, radius=5):
self.x = start_x
self.y = start_y
self.direction = 'down'
self.radius = radius
self.assigned_warehouse = assigned_warehouse
self.is_loaded = False
self.transported_package = None
def check_packages_locations(self):
for pack in self.warehouse.packages:
if pack.lays_on_field.category.name in self.warehouse.storage_types:
can_place = self.location_classifier.check_if_can_place(pack, pack.lays_on_field)
pack.status = PackStatus.STORED if (
can_place and pack.lays_on_field.capacity >= 0) else PackStatus.STORED_BAD_LOCATION
def demo_agent_move(self, demo_agent_step, demo_step_max=5):
demo_agent_sign = 0
next_coords = self.get_next_move_coordinates()
can_move = self.check_if_can_move(next_coords)
if demo_agent_step >= demo_step_max:
demo_agent_sign = -1
self.direction = 'up'
elif demo_agent_step == 0:
demo_agent_sign = 1
self.direction = 'down'
if not can_move:
alternative_move = ('left' if self.check_if_can_move(self.move_left()) else None) or ('right' if self.check_if_can_move(self.move_right()) else self.direction)
self.direction = alternative_move
else:
self.x = next_coords.x
self.y = next_coords.y
def find_path(self, *args, **kwargs):
self.closed = []
self.path = []
self.open = PriorityQueue()
if len(args) != 0:
if len(args) == 1:
start_node = Node(self.x, self.y)
else:
start_node = args[1]
self.destination = args[0]
else:
packages_to_go = [p for p in self.warehouse.packages if p.status != PackStatus.STORED]
if not packages_to_go and not self.transported_package:
return
if self.is_loaded:
print(self.transported_package)
rack = self.find_nearest_rack_for(self.transported_package)
self.destination = Node(rack.x_position, rack.y_position, is_rack=True)
else:
package = self.find_package()
self.destination = Node(package.lays_on_field.x_position, package.lays_on_field.y_position, package=package)
def turn_left(self):
new_direction = TURN_LEFT_DIRECTIONS.get(self.direction, self.direction)
self.direction = new_direction
start_node = Node(self.x, self.y)
def turn_right(self):
new_direction = TURN_RIGHT_DIRECTIONS.get(self.direction, self.direction)
self.direction = new_direction
self.open.put((0, start_node))
while self.open:
_, current_node = self.open.get()
self.closed.append(current_node)
if current_node.x == self.destination.x and current_node.y == self.destination.y:
while current_node.x != start_node.x or current_node.y != start_node.y:
self.path.append(current_node)
current_node = current_node.parent
return True
neighbour_list = self.get_neighbours(current_node)
for neighbour in neighbour_list:
cost = current_node.g_cost + self.heuristic(current_node, neighbour)
if self.check_if_closed(neighbour):
continue
if self.check_if_open(neighbour):
if neighbour.g_cost > cost:
neighbour.g_cost = cost
neighbour.parent = current_node
else:
neighbour.g_cost = cost
neighbour.h_cost = self.heuristic(neighbour, self.destination)
neighbour.parent = current_node
self.open.put((neighbour.g_cost, neighbour))
return False
def move(self):
next_coords = self.get_next_move_coordinates()
can_move = self.check_if_can_move(next_coords)
if can_move:
self.x = next_coords.x
self.y = next_coords.y
def turn_left(self):
new_direction = TURN_LEFT_DIRECTIONS.get(self.direction, self.direction)
self.direction = new_direction
def get_next_move_coordinates(self):
direction_moves = {
'up': self.move_up(),
'down': self.move_down(),
'left': self.move_left(),
'right': self.move_right()
}
next_coords = direction_moves.get(self.direction, Coordinates(self.x, self.y))
return next_coords
def turn_right(self):
new_direction = TURN_RIGHT_DIRECTIONS.get(self.direction, self.direction)
self.direction = new_direction
def check_if_can_move(self, next_coords: Coordinates):
next_tile = self.assigned_warehouse.tiles[next_coords.x][next_coords.y]
tile_passable = isinstance(next_tile, Tile) and next_tile.category.passable
tile_on_map = 0 <= next_coords.x < self.assigned_warehouse.width and 0 <= next_coords.y < self.assigned_warehouse.height
return tile_passable and tile_on_map
def heuristic(self, start: Node, goal: Node):
diff_x = pow(goal.x - start.x, 2)
diff_y = pow(goal.y - start.y, 2)
additional_cost = 0
return round(sqrt(diff_x + diff_y), 3) + float(10 * additional_cost)
def move_right(self):
pos_x = self.x + 1
if pos_x > self.assigned_warehouse.width - 1:
pos_x = self.assigned_warehouse.width - 1
return Coordinates(x=pos_x, y=self.y)
def check_if_open(self, node: Node):
return (node.x, node.y) in [(n.x, n.y) for (_, n) in self.open.queue]
def move_left(self):
pos_x = self.x - 1
if pos_x < 0:
pos_x = 0
return Coordinates(x=pos_x, y=self.y)
def check_if_closed(self, node: Node):
return (node.x, node.y) in [(n.x, n.y) for n in self.closed]
def move_down(self):
pos_y = self.y + 1
if pos_y > self.assigned_warehouse.height - 1:
pos_y = self.assigned_warehouse.height - 1
return Coordinates(x=self.x, y=pos_y)
def get_neighbours(self, node: Node):
neighbours = []
if self.check_if_can_move(Coordinates(node.x + 1, node.y)):
neighbours.append(Node(node.x + 1, node.y))
if self.check_if_can_move(Coordinates(node.x - 1, node.y)):
neighbours.append(Node(node.x - 1, node.y))
if self.check_if_can_move(Coordinates(node.x, node.y + 1)):
neighbours.append(Node(node.x, node.y + 1))
if self.check_if_can_move(Coordinates(node.x, node.y - 1)):
neighbours.append(Node(node.x, node.y - 1))
return neighbours
def move_up(self):
pos_y = self.y - 1
if pos_y < 0:
pos_y = 0
return Coordinates(x=self.x, y=pos_y)
def move(self):
if len(self.path) == 0:
self.find_path()
next_coord = self.path.pop()
star_dir = self.direction
if self.x > next_coord.x and not self.direction == 'left':
if self.direction == 'down':
self.turn_right()
else:
self.turn_left()
elif self.x < next_coord.x and not self.direction == 'right':
if self.direction == 'down':
self.turn_left()
else:
self.turn_right()
elif self.y > next_coord.y and not self.direction == 'up':
if self.direction == 'left':
self.turn_right()
else:
self.turn_left()
elif self.y < next_coord.y and not self.direction == 'down':
if self.direction == 'right':
self.turn_right()
else:
self.turn_left()
if Node(next_coord.x, next_coord.y) == self.destination or Node(self.x, self.y) == self.destination:
if self.destination.package:
self.pick_up_package(self.destination.package)
return
elif self.destination.is_rack:
self.unload_package(self.destination)
return
def package_ahead(self):
next_coords = self.get_next_move_coordinates()
potential_package = self.assigned_warehouse.tiles[next_coords.x][next_coords.y]
return isinstance(potential_package, Pack) and potential_package.status != PackStatus.STORED
if star_dir == self.direction:
self.x = next_coord.x
self.y = next_coord.y
else:
self.path.append(next_coord)
self.closed = []
def pick_up_package(self, pack):
tile = pack.lays_on_field
self.assigned_warehouse.tiles[tile.x_position][tile.y_position] = tile
self.is_loaded = True
pack.lays_on_field = None
self.transported_package = pack
def check_if_can_move(self, next_coords: Coordinates):
tile_on_map = 0 <= next_coords.x < self.warehouse.width and 0 <= next_coords.y < self.warehouse.height
tile_passable = True
if not tile_on_map:
return False
next_tile = self.warehouse.tiles[next_coords.x][next_coords.y]
if (next_coords.x, next_coords.y) != (self.destination.x, self.destination.y):
tile_passable = isinstance(next_tile, Tile) and next_tile.category.passable
return tile_passable
def find_route(self, goal):
explored = []
# tu trzeba dodać kolejkę priorytetową fringe
fringe = PriorityQueue()
current_tile = self.assigned_warehouse.tiles[self.x][self.y]
fringe.put((1, current_tile))
def find_package(self):
if len(self.route) == 0:
pygame.quit()
sys.exit()
pack_id = self.route[0]
self.route = self.route[1:]
# print("Next package ID:")
# print(pack_id)
dst_package = None
for pack in self.warehouse.packages:
if pack.id + 1 == pack_id:
dst_package = pack
break
if dst_package is not None:
return dst_package
nmodel = Sequential()
imageClass(nmodel)
nmodel.load_weights('model_weights.h5')
while True:
if len(fringe) == 0:
return False
# elem to węzeł z kolejki o najmniejszym priorytecie (najlepszy)
elem = fringe.get()
imgSkan()
def rack_heuristics(self, start, goal, can_place):
heur_can_place = not can_place
diff_x = pow(goal.x - start.x, 2)
diff_y = pow(goal.y - start.y, 2)
place_cost = 100 * float(heur_can_place)
return round(sqrt(diff_x + diff_y), 3) + float(place_cost)
# jeśli zgadzają się współrzędne x i y wybranego węzłą oraz celu
if elem.x_position == goal.x_position and elem.y_position == goal.y_position:
# tu powinna zostać zwrócona ścieżka
print("doszedl")
return True
def find_nearest_rack_for(self, package, expand_box=0):
weight = package.size
storage = "Rack"
if package.category == "freezed":
storage = "Fridge"
start_node = Node(self.x, self.y)
quarter_x = int(self.warehouse.width / 4) + expand_box
quarter_y = int(self.warehouse.height / 4) + expand_box
start_quarter_x = self.x - quarter_x if self.x - quarter_x > 0 else 0
end_quarter_x = self.x + quarter_x if self.x + quarter_x < self.warehouse.width else self.warehouse.width - 1
start_quarter_y = self.y - quarter_y if self.y - quarter_y > 0 else 0
end_quarter_y = self.y + quarter_y if self.y + quarter_y < self.warehouse.height else self.warehouse.height - 1
quarter = [row[start_quarter_y:end_quarter_y] for row in self.warehouse.tiles[start_quarter_x:end_quarter_x]]
quarter_racks = [[t for t in row if t.category.name == storage and t.capacity >= weight] for row in quarter]
quarter_racks = [t for row in quarter_racks for t in row]
racks_costs = []
for rack in quarter_racks:
new_node = Node(rack.x_position, rack.y_position)
can_place = self.location_classifier.check_if_can_place(package, rack)
cost = self.rack_heuristics(start_node, new_node, can_place)
if cost > 0:
racks_costs.append((rack, cost))
# przeniesienie wybranego węzłą z fringe do explored
explored.append(elem)
rack = self.find_nearest_rack_for(package, expand_box + 1) if not racks_costs else \
min(racks_costs, key=lambda l: l[1])[0]
return rack
# dla każdego następnika węzła elem
# trzeba napisać funkcję succ wyznaczającą następników elem
# succesor[0] - akcja
# succesor[1] - stan czyli współrzędne i zwrot
# succesor[2] - rodzic
succ = self.get_succ(elem)
def pick_up_package(self, pack):
self.warehouse.packages.remove(pack)
self.is_loaded = True
if pack.lays_on_field.category.name in ['Rack', 'Fridge']:
pack.lays_on_field.capacity += pack.size
for action, state in succ:
new_node = Node(elem, elem.x_position, elem.y_position)
# x[1] = succesor[1]
# x[2] = elem
# x[0] = akcja
# trzeba napisać funkcję f(x) liczącą priorytet danego węzła
# p = f(x)
self.destination.package = None
pack.lays_on_field = None
self.transported_package = pack
# if x[1] not in fringe and x[1] not in explored:
# fringe.append(x[1])
# nie wiem jak wyznaczyć priorytet który x już ma w kolejce
# elif x[1] in fringe and priorytet który stan x już ma w kolejce > p:
# tu chodzi o to że zmieni się akcja i rodzić, ale stan nie
# zamień w fringe stary węzeł o stanie x[1] z węzłem x
def unload_package(self, rack):
pack = self.transported_package
tile = self.warehouse.tiles[rack.x][rack.y]
self.transported_package = None
self.is_loaded = False
pack.lays_on_field = tile
pack.lays_on_field.capacity -= pack.size
pack.status = PackStatus.STORED
self.warehouse.packages.append(pack)
def h(self, start, goal):
diff_x = pow(goal.x_position - start.x_position,2)
diff_y = pow(goal.y_position - start.y_position, 2)
return round(sqrt(diff_x+diff_y), 3)
# print(tile.air_temperature, tile.humidity)
def create_graph_map(self):
for package1 in self.warehouse.packages:
rack = self.find_nearest_rack_for(package1)
for package2 in self.warehouse.packages:
self.find_path(Node(package2.x, package2.y), Node(rack.x_position, rack.y_position))
self.graph_map[package2.id + 1][package1.id + ceil((len(self.warehouse.packages) / 2)) + 1] = len(self.path)
self.graph_map[package1.id + ceil((len(self.warehouse.packages) / 2)) + 1][package2.id + 1] = len(self.path)
if package1 == package2:
continue
self.find_path(Node(package1.x, package1.y), Node(package2.x, package2.y))
self.graph_map[package1.id + 1][package2.id + 1] = len(self.path)
self.find_path(Node(package1.x, package1.y))
self.graph_map[package1.id + 1][0] = len(self.path)
self.graph_map[0][package1.id + 1] = len(self.path)
def trace_route(self):
# for packs in self.warehouse.packages:
# print(packs.id)
self.route = genetic_trace_route(self.graph_map, len(self.warehouse.packages))
# print("best route")
# print(self.route)
def get_succ(self, elem):
move = self.move
turn_left = self.turn_left
turn_right = self.turn_right
successors = [
(move, self.get_next_move_coordinates()),
(turn_right, TURN_RIGHT_DIRECTIONS.get(self.direction, self.direction)),
(turn_left, TURN_LEFT_DIRECTIONS.get(self.direction, self.direction))
]
return successors

20
attributes.py Executable file → Normal file
View File

@ -1,5 +1,11 @@
from enum import Enum
class PackSize(Enum):
ALL = 0
SMALL = 1
MEDIUM = 2
LARGE = 3
HUGE = 4
class PackStatus(Enum):
LOOSE = 0
@ -18,13 +24,10 @@ COLORS = {
'darkgray': (60, 60, 60),
'yellow': (235, 235, 0),
'lightgreen': (70, 238, 70),
'red': (255, 0, 0),
'lightblue': (120, 180, 230),
'iceblue': (186, 242, 239),
'blue': (0, 0, 255),
'orange': (255, 165, 0)
'red': (255, 0, 0)
}
TURN_LEFT_DIRECTIONS = {
"left": "down",
"down": "right",
@ -37,11 +40,4 @@ TURN_RIGHT_DIRECTIONS = {
"up": "right",
"right": "down",
"down": "left"
}
DIRECTION_ANGLES = {
"left": 0,
"up": -90,
"right": 180,
"down": 90
}

BIN
cyfra.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

0
environment.md Executable file → Normal file
View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,148 +0,0 @@
## Raport z podprojektu genetic_algorithm
#### Autorka - Magdalena Biadała
Program wykorzystuje algorytm genetyczny w celu znalezienia najlepszego dopasowania paczek do regałów, przy czym:
- każda paczka musi zostać umieszczona na jakimś regale
- waga wszystkich paczek umieszczoanych na regale nie może przekroczyć pojemności regału
- paczki umieszczane są na regałach których parametry, takie jak temperatura czy wilgotność powietrza pozwalają na bezpieczne jej przechowywanie, bez zniszczenia jej zawartości.
Algorytm jako struktury danych przyjmuje 2 listy:
Listę *packs* w której indeksy oznaczają numery paczek, a wartości oznaczają wagę poszczególnych paczek. Na przykład:
lista [2,6,2,5] to struktura, gdzie:
- paczka o nr 0 ma wagę 2
- paczka o nr 1 ma wagę 6
- paczka o nr 2 ma wagę 2
- paczka o nr 3 ma wagę 5
Listę *racks* w której indeksy oznaczają numery regałów, a wartości oznaczają pojemność poszczególnych regałów. Na przykład:
lista [15,13,20,16] to struktura, gdzie:
- regał o nr 0 ma pojemność 15
- regał o nr 1 ma pojemność 13
- regał o nr 2 ma pojemność 20
- regał o nr 3 ma pojemność 16
#### Program zawiera kilka ważnych funkcji:
```python
def first_gen():
first_generation = []
for individual in range(generation_size):
individual = []
for pack in range(number_of_packages):
r = random.randint(0,number_of_racks-1)
individual.append(r)
first_generation.append(individual)
return first_generation
```
>funkcja *first_gen()* tworzy pierwsze pokolenie osobników;
```python
def evaluation(individual):
rest_of_capacity = racks.copy()
for i in range(number_of_packages):
rest_of_capacity[individual[i]] -= packages[i]
fitness = 0
for i in range(number_of_racks):
if rest_of_capacity[i] < 0:
fitness += rest_of_capacity[i]
elif rest_of_capacity[i] == 0:
fitness += amount_of_promotion
return fitness
```
> funkcja *evaluation()* ocenia wybranego osobnika pod względem tego, czy:
- regały nie są przepełnione
>Dodatkowo delikatnie promuje ona osobniki, króre wykorzystują pojemność regałów w całości, a na koniec zwraca parametr *fitness*.
```python
def roulette(generation):
evaluations = []
for i in range(generation_size):
individual_fitness = evaluation(generation[i])
evaluations.append(individual_fitness)
maximum = min(evaluations)
normalized = [x+(-1*maximum)+1 for x in evaluations]
sum_of_normalized = sum(normalized)
roulette_tab = [x/sum_of_normalized for x in normalized]
for i in range(1,generation_size-1):
roulette_tab[i] += roulette_tab[i-1]
roulette_tab[generation_size-1] = 1
survivors = []
for individual in range(generation_size):
random_number = random.random()
interval_number = 0
while random_number > roulette_tab[interval_number]:
interval_number += 1
survivors.append(generation[interval_number])
return survivors
```
> funkcja *roulette()*:
- liczy parametr *fitness* (oznaczający dopasowanie) dla każdego osobnika w pokoleniu
- tworzy tablicę z przedziałami, przy czym im większy *fitness* osobnika tym większy jego przedział, a tym samym szansa że zostanie wylosowany
- losuje liczby z zakresu od 0 do 1 (liczb jest tyle ile osobników w pokoleniu)
-zwraca tych osobników, dla krótych wylosoana liczba wpadła w odpowiadający im przedział.
```python
def crossover(individual1, individual2):
cut = random.randint(1,number_of_packages-1)
new1 = individual1[:cut]
new2 = individual2[:cut]
new1 = new1 + individual2[cut:]
new2 = new2 + individual1[cut:]
return new1, new2
```
>funkcja *crossover()* zajmuje się krzyżowaniem osobników.
```python
def mutation(individual):
locus = random.randint(0,number_of_packages-1)
individual[locus] = random.randint(0,number_of_racks-1)
return individual
```
>funkcja *mutation()* dokonuje mutacji osobnika.
#### Inicjalizacja pierwszego pokolenia
Pierwsze pokolenie jest tworzone za pomocą funkcji *first_gen()*. Osobnikiem jest lista której indeksy oznaczają numery paczek, a wartości oznaczają numery regałów. Na przykład:
osobnik [3,0,5,5] to przyporządkowanie, gdzie:
- paczka nr 0 leży na regale nr 3
- paczka nr 1 leży na regale nr 0
- paczka nr 2 leży na regale nr 5
- paczka nr 3 leży na regale nr 5.
Dla każdego osobnika w pierwszym pokoleniu liczony jest parametr *fitness*.
#### Główna pętla programu
Dla każdego pokolenia wykonywane są kolejno funkcje:
- roulette()
>pozostawia ona tylko część osobników w pokoleniu, część z nich zostaje zmultiplikowana
- crossover()
>dla pokolenia które pozostało po ruletce
- mutation()
> ta funkcja wykonywana jest tylko z pewnym prawdopodobieństem określonym w zmiennej *mutation_prob*.
- evaluation()
>dla pokolenia które pozostawiły po sobie poprzednie funkcje znalezione zostaje maksimum (największa wartość *fitness*).
#### Wynik działania algorytmu
Algorytm zwraca osobnika (przyporządkowanie) dla którego wartość fitness była największa.
#### Przeprowadzone testy
W celu rozeznania i dobrania wstępnych wartości parametrów:
- *mutation_prob* (prawdopodobieństwo mutacji),
- *generation_size* (wielkość pojedynczego pokolenia),
- *number_of_generations* (liczba pokoleń),
został przeprowadzony test. Wykonywał on 200 razy algorytm genetyczny dla wybranych parametrów, oraz losowych list paczek i regałów, a następnie liczył średnią i medianę maksymalnej wartości *fitness* znalezionej w każdej z prób. W poniższej tabeli oprócz średniej i mediany można także odczytać czas działania algorytmu.
![Tabela wyników](wyniki_testu.PNG)
#### Zastosowanie w projekcie
Algorytm uruchamiany jest po wygenerowaniu magazynu. Zwraca on najlepsze znalezione dopasowanie, które następnie zostanie wykorzystane w kolejnych podprojektach innych osób z grupy, które zajmą się optymalizacją rozwożenia paczek na przydzielone im miejsca.
- *amount_of_promotion* (wartość jaka zostaje dodana do *fitness* osobnika, jeśli wykorzysta jakiś regał w pełni)

View File

@ -1,175 +0,0 @@
import random
import math
### prawdopodobieństwo mutacji
mutation_prob = 0.03
### ilość osobników w pokoleniu, powinna być parzysta
# generation_size = 40
### liczba pokoleń
# number_of_generations = 30
### jak bardzo promowane są osobniki wykorzystujące całą pojemność regału
amount_of_promotion = 5
def first_gen(number_of_packages, number_of_racks, generation_size):
first_generation = []
for individual in range(generation_size):
individual = []
for pack in range(number_of_packages):
r = random.randint(0,number_of_racks-1)
individual.append(r)
first_generation.append(individual)
return first_generation
# def evaluation(individual, packages, racks, number_of_packages, number_of_racks, tree_predictor):
# # im większy fitness tym lepszy osobnik
# # print("regały: ",racks)
# rest_of_capacity = [rack.capacity for rack in racks]
# # print("początkowa pojemność: ",rest_of_capacity)
# for i in range(number_of_packages):
# can_place = tree_predictor.check_if_can_place(packages[i], racks[i])
# if not can_place:
# rest_of_capacity[individual[i]] -= packages[i].size * 5
# else:
# rest_of_capacity[individual[i]] -= packages[i].size
# # print("pozostała pojemność: ",rest_of_capacity)
# # pdb.set_trace()
# fitness = 0
# for i in range(number_of_racks):
# # jak regał jest przepełniony, zmniejsza fitness osobnika
# if rest_of_capacity[i] < 0:
# fitness += rest_of_capacity[i]
# # delikane promowanie osobników wykorzystujących regały w pełni
# elif rest_of_capacity[i] == 0:
# fitness += 2
# else:
# fitness += 1
# return fitness
def evaluation(individual, packages, racks, number_of_packages, number_of_racks, tree_predictor):
# im większy fitness tym lepszy osobnik
# print("regały: ",racks)
rest_of_capacity = [rack.capacity for rack in racks]
# print("początkowa pojemność: ",rest_of_capacity)
bad_placed = 0
for i in range(number_of_packages):
rest_of_capacity[individual[i]] -= packages[i].size
can_place = tree_predictor.check_if_can_place(packages[i], racks[i])
if not can_place:
bad_placed +=1
# print("pozostała pojemność: ",rest_of_capacity)
# pdb.set_trace()
fitness = 0
for i in range(number_of_racks):
# jak regał jest przepełniony, zmniejsza fitness osobnika
if rest_of_capacity[i] < 0:
fitness += rest_of_capacity[i]
# delikane promowanie osobników wykorzystujących regały w pełni
elif rest_of_capacity[i] == 0:
fitness += amount_of_promotion
fitness -= 5*bad_placed
return fitness
def roulette(generation, packages, generation_size ,racks, number_of_packages, number_of_racks, tree_predictor):
# print('pokolenie: ', generation)
evaluations = []
for i in range(generation_size):
individual_fitness = evaluation(generation[i], packages, racks, number_of_packages, number_of_racks, tree_predictor)
evaluations.append(individual_fitness)
# print("tablica dopasowań: ", evaluations)
maximum = min(evaluations)
# dodaję tą 1 żeby nie wywalać najgorszego osobnika
normalized = [x+(-1*maximum)+1 for x in evaluations]
# print(normalized)
sum_of_normalized = sum(normalized)
roulette_tab = [x/sum_of_normalized for x in normalized]
# print(roulette_tab)
for i in range(1,generation_size-1):
roulette_tab[i] += roulette_tab[i-1]
# wpisuję 1 ręcznie, bo czasem liczby nie sumowały się idealnie do 1
#(niedokładność komputera)
roulette_tab[generation_size-1] = 1
# print("ruletka: ", roulette_tab)
survivors = []
for individual in range(generation_size):
random_number = random.random()
interval_number = 0
while random_number > roulette_tab[interval_number]:
interval_number += 1
survivors.append(generation[interval_number])
# print('przetrwali: ',survivors)
return survivors
def crossover(individual1, individual2, number_of_packages):
cut = random.randint(1,number_of_packages-1)
new1 = individual1[:cut]
new2 = individual2[:cut]
new1 = new1 + individual2[cut:]
new2 = new2 + individual1[cut:]
# print(individual1)
# print(individual2)
# print(new1)
# print(new2)
# print(cut)
return new1, new2
def mutation(individual, number_of_packages, number_of_racks):
# print(individual)
locus = random.randint(0,number_of_packages-1)
individual[locus] = random.randint(0,number_of_racks-1)
return individual
def gen_alg(packages, racks, number_of_generations, generation_size, mutation_prob, amount_of_promotion, tree_predictor):
number_of_packages = len(packages)
number_of_racks = len(racks)
### WŁAŚCIWY ALGORYTM
generation = first_gen(number_of_packages, number_of_racks, generation_size)
global_maximum = -math.inf
# pętla znajdująca najlepszy fitness w pierwszym pokoleniu
for i in range(generation_size):
evaluation_of_individual = evaluation(generation[i], packages, racks, number_of_packages, number_of_racks, tree_predictor)
if evaluation_of_individual > global_maximum:
global_maximum = evaluation_of_individual
best_individual = generation[i].copy()
#właściwa pętla programu
for generation_index in range(number_of_generations):
# print('pokolenie numer: ', generation_index)
# print(generation)
### RULETKA
survivors = roulette(generation, packages, generation_size, racks, number_of_packages, number_of_racks, tree_predictor)
# print('przetrwali: ',survivors)
### KRZYŻOWANIE
descendants = []
for individual in range(0,generation_size,2):
pair = crossover(survivors[individual],survivors[individual+1], number_of_packages)
for each in pair:
descendants.append(each)
# print('potomkowie: ', descendants)
### MUTACJA
for individual in range(generation_size):
if random.random() <= mutation_prob:
mutation(descendants[individual], number_of_packages, number_of_racks)
# print('potomkowie po mutacji: ', descendants)
### NAJLEPSZE DOPASOWANIE
local_maximum = -math.inf
for each in range(generation_size):
specific_fitness = evaluation(descendants[each], packages, racks, number_of_packages, number_of_racks, tree_predictor)
if specific_fitness > local_maximum:
local_maximum = specific_fitness
generation_best_individual = descendants[each].copy()
print('maksimum w pokoleniu: ',local_maximum)
if local_maximum > global_maximum:
global_maximum = local_maximum
best_individual = generation_best_individual.copy()
generation = descendants
print('maksimum globalne: ', global_maximum)
# print("jeśli maksimum globalne wynosi 0, każda paczka ma swój regał")
print("najlepsze dopasowanie: ", best_individual)

View File

@ -1,98 +0,0 @@
import numpy as np
from random import randrange, random
from math import floor
import copy
num_of_surviving = 6
num_of_couples = 8
mutation_probability = 0.07
max_population = 20
iterations = 50
# creates new random solution to add to population
def create_new_route(points):
route = np.random.permutation(points)
route = [x + 1 for x in route]
return route
# creates initian population
def create_population(points):
population = []
for i in range(max_population):
population.append(create_new_route(points))
return population
# gives score to a solution based on lenght
def score_route(graph_map, route):
score = graph_map[0][route[0]]
for i in range(len(route) - 2):
rack = len(route) + route[0]
score = score + graph_map[rack][route[i + 1]]
score = score + graph_map[route[i + 1]][route[i + 2]]
return score
# scores every solution in population
def score_all(graph_map, population):
scores = []
for i in range(len(population)):
tmp = [i, score_route(graph_map, population[i])]
scores.append(tmp)
return scores
# designed to create new population by mixing steps between most succesfull solutions
def crossover(a, b):
new_a = copy.deepcopy(a)
new_b = copy.deepcopy(b)
for i in range(floor(len(a) / 2)):
rel = randrange(len(a))
tmp_a = new_a[rel]
tmp_b = new_b[rel]
if tmp_a == tmp_b:
continue
new_a[new_a.index(tmp_b)] = tmp_a
new_b[new_b.index(tmp_a)] = tmp_b
new_a[rel] = tmp_b
new_b[rel] = tmp_a
return new_a, new_b
# adds randomness to newly created solutions
def mutate(route):
new_route = copy.deepcopy(route)
for i in range(len(route) - 1):
if random() < mutation_probability:
tmp = new_route[i]
new_route[i] = new_route[i + 1]
new_route[i + 1] = tmp
return new_route
# main function that iterate population until the best solutions emerge
def genetic_trace_route(graph_map, packages):
population = create_population(packages)
for i in range(iterations):
new_population = []
scores = score_all(graph_map, population)
scores.sort(key=lambda x: x[1])
# breeding
for j in range(0, num_of_couples, 2):
a, b = crossover(population[scores[j][0]], population[scores[j+1][0]])
new_population.append(a)
new_population.append(b)
# mutations
for j in range(len(new_population)):
mutate(new_population[j])
# survival
for j in range(0, num_of_surviving):
new_population.append(population[scores[j][0]])
# random new
for j in range(max_population - (num_of_surviving + num_of_couples)):
new_population.append(create_new_route(packages))
population.clear()
population = copy.deepcopy(new_population)
scores = score_all(graph_map, population)
scores.sort(key=lambda x: x[1])
# print("Best route of all population in iteration " + str(i + 1))
# print(scores[0][1])
scores = score_all(graph_map, population)
scores.sort(key=lambda x: x[1])
return population[scores[0][0]]

82
main.py Executable file → Normal file
View File

@ -1,52 +1,32 @@
import pygame
import warehouse
import agent
from genetic_algorithm import gen_alg
import random
import sys
from attributes import PackStatus, COLORS, DIRECTION_ANGLES
from attributes import PackSize, PackStatus, COLORS
WINDOW_SIZE = (640, 640)
WINDOW_SIZE = (600, 600)
COLOR_OF_FIELD = {
'Floor': 'gray',
'Rack': 'white',
'Pack': 'yellow',
'path': 'orange',
'FridgeFloor': 'lightblue',
'Fridge': 'iceblue'
'Pack': 'yellow'
}
TILE_WIDTH = 32
TILE_HEIGHT = 32
TILE_WIDTH = 30
TILE_HEIGHT = 30
CIRCLE_CENTER_X, CIRCLE_CENTER_Y = int(TILE_WIDTH/2), int(TILE_HEIGHT/2)
class MainGameFrame:
def __init__(self, mutation_prob=0.03, generation_size=30, number_of_generations=100, amount_of_promotion=0):
pygame.font.init()
def __init__(self):
self.display = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("Smart ForkLift")
agent_radius = int(TILE_WIDTH/2)
self.agent_tex = pygame.image.load('forklift.png')
self.agent_tex2 = pygame.image.load('forklift_loaded.png')
self.font = pygame.font.Font('freesansbold.ttf', 16)
self.warehouse_map = warehouse.Warehouse(20, 20, 150, 10)
self.warehouse_map = warehouse.Warehouse(20, 20, 150, 20)
starting_x, starting_y = self.set_starting_agent_position()
self.agent = agent.Agent(starting_x, starting_y, self.warehouse_map, agent_radius)
self.clock = pygame.time.Clock()
packs_coords = [(pack.lays_on_field.x_position, pack.lays_on_field.y_position) for pack in self.warehouse_map.packages]
list_of_racks = self.warehouse_map.get_all_racks(True)
racks_coords = [(line.x_position, line.y_position) for line in list_of_racks]
packs_sizes = [pack for pack in self.warehouse_map.packages]
racks_capacities = list_of_racks
# print("koordynaty paczek: ",packs_coords)
# print("koordynaty regałów: ",racks_coords)
print("wagi paczek: ",packs_sizes)
print("pojemności regałów: ",racks_capacities)
gen_alg(packs_sizes, racks_capacities, number_of_generations, generation_size, mutation_prob, amount_of_promotion, self.agent.location_classifier)
self.agent.create_graph_map()
self.agent.trace_route()
self.agent.find_path()
def run(self):
# demo_agent_step = 1
# demo_agent_sign = 1
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
@ -55,14 +35,15 @@ class MainGameFrame:
self.draw_floor()
self.draw_packages()
self.draw_agent()
self.draw_nums()
self.agent.move()
packages_to_go = [p for p in self.warehouse_map.packages if p.status != PackStatus.STORED]
if not packages_to_go and not self.agent.transported_package:
pygame.quit()
sys.exit()
# self.agent.demo_agent_move(demo_agent_step, 8) #linijka w celu zademonstrowania poruszania się agenta
# self.agent.move() #oryginalna linijka
# demo_agent_step += (1*demo_agent_sign)
# if demo_agent_step >= 8:
# demo_agent_sign = -1
# if demo_agent_step == 0:
# demo_agent_sign = 1
pygame.display.update()
self.clock.tick(6)
self.clock.tick(5)
def draw_floor(self):
for x in range(self.warehouse_map.width):
@ -71,10 +52,10 @@ class MainGameFrame:
def draw_field(self, x, y):
current_tile = self.warehouse_map.tiles[x][y]
if not isinstance(current_tile, warehouse.Tile):
current_tile = current_tile.lays_on_field if isinstance(current_tile, warehouse.Pack) else None
color = COLOR_OF_FIELD.get(current_tile.category.name, 'white')
color = COLORS[color]
if (current_tile.x_position,current_tile.y_position) in [(a.x, a.y) for a in self.agent.path]:
color = COLORS.get('orange')
pygame.draw.rect(self.display, COLORS['black'],
(x * TILE_WIDTH, y * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT))
pygame.draw.rect(self.display, color,
@ -94,28 +75,11 @@ class MainGameFrame:
package_color = get_package_color(pack)
pygame.draw.rect(self.display, package_color,
((pack_x * TILE_WIDTH) + 3, (pack_y * TILE_HEIGHT) + 3, TILE_WIDTH - 5, TILE_HEIGHT - 5))
if pack.category == "freezed":
pygame.draw.rect(self.display, COLORS['blue'],
((pack_x * TILE_WIDTH) + 2, (pack_y * TILE_HEIGHT) + 2, TILE_WIDTH - 4,
TILE_HEIGHT - 4), 3)
def draw_nums(self):
for row in self.warehouse_map.tiles:
for cell in row:
if cell.category.name in self.warehouse_map.storage_types:
text_surface = self.font.render(str(cell.capacity), True, (0, 0, 0))
self.display.blit(text_surface, ((cell.x_position * TILE_WIDTH) + 6, (cell.y_position * TILE_HEIGHT) + 6))
for package in self.warehouse_map.packages:
if package.status == PackStatus.LOOSE:
text_surface = self.font.render(str(package.id + 1), True, (0, 0, 0))
self.display.blit(text_surface, ((package.lays_on_field.x_position * TILE_WIDTH) + 6, (package.lays_on_field.y_position * TILE_HEIGHT) + 6))
def draw_agent(self):
if self.agent.is_loaded:
rotated = pygame.transform.rotate(self.agent_tex2, DIRECTION_ANGLES.get(self.agent.direction))
else:
rotated = pygame.transform.rotate(self.agent_tex, DIRECTION_ANGLES.get(self.agent.direction))
self.display.blit(rotated, (self.agent.x*TILE_WIDTH, self.agent.y*TILE_WIDTH))
agent_position_x, agent_position_y = self.agent.x, self.agent.y
agent_screen_position = ((agent_position_x*TILE_WIDTH) + CIRCLE_CENTER_X, (agent_position_y*TILE_HEIGHT) + CIRCLE_CENTER_Y)
pygame.draw.circle(self.display, COLORS['black'], agent_screen_position, self.agent.radius, int(self.agent.radius/2))
def set_starting_agent_position(self):
starting_x, starting_y = random.randrange(self.warehouse_map.width), random.randrange(self.warehouse_map.height)
@ -126,4 +90,4 @@ class MainGameFrame:
if __name__ == '__main__':
maingame = MainGameFrame()
maingame.run()
maingame.run()

Binary file not shown.

View File

@ -1,75 +0,0 @@
from sklearn.tree import DecisionTreeClassifier, plot_tree, export_graphviz, DecisionTreeRegressor
from sklearn.externals.six import StringIO
from IPython.display import Image
import pandas as pd
import numpy as np
import pydotplus
from sklearn.model_selection import train_test_split
from sklearn import metrics
PACKAGE_PLACE_TRESHOLD = {
"normal": 0.8,
"freezed": 0.85,
"fragile": 0.85,
"flammable": 0.9,
"keep_dry": 0.8
}
class PackageLocationClassifier():
def __init__(self):
data = StringIO()
cols_names = ["product", "category", "temperature", "humidity", "chance_of_survive", "place_here"]
feature_cols = ["category", "temperature", "humidity"]
products = pd.read_csv("package_location_classifier/trainset/trainset.csv", header=0, sep=",", names=cols_names)
testset = pd.read_csv("package_location_classifier/testset/testset.csv", header=None, sep=",", names=cols_names)
products = products.round({"chance_of_survive": 1})
testset = testset.round({"chance_of_survive": 1})
products.chance_of_survive *= 10
testset.chance_of_survive *= 10
test_X = pd.get_dummies(testset[feature_cols])
test_y = testset.chance_of_survive
products = products.sample(frac=1)
X_train = pd.get_dummies(products[feature_cols])
y_train = products.chance_of_survive
dummies_names = X_train.columns.tolist()
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.01, random_state=1, shuffle=True)
clf = DecisionTreeRegressor(ccp_alpha=0.02, min_samples_leaf=5, max_depth=5)
self.predictor = clf.fit(X_train, y_train)
y_pred = self.predictor.predict(test_X)
evaluation = pd.DataFrame({'category': testset.category, 'temperature': testset.temperature , 'humid': testset.humidity ,'Actual': test_y, 'Predicted': y_pred})
evaluation = evaluation.round({'Actual': 3, 'Predicted': 3})
evaluation['Prediction_diff'] = abs(evaluation['Actual'] - evaluation['Predicted'])
print("Prediction differs from actual value by average {}".format(round(evaluation['Prediction_diff'].mean(), 2)))
# export_graphviz(clf, out_file=data, filled=True, rounded=True, special_characters=True, feature_names=dummies_names)
# graph = pydotplus.graph_from_dot_data(data.getvalue())
# graph.write_png('Drzewo.png')
# Image(graph.create_png())
def check_if_can_place(self, package, tile):
category = package.category
cat_treshold = PACKAGE_PLACE_TRESHOLD[category]
fields = [[
tile.air_temperature,
tile.humidity,
category == "flammable",
category == "fragile",
category=="freezed" ,
category == "keep_dry",
category == "normal"
]]
quality_of_place = round(self.predictor.predict(fields)[0]/10, 2)
if quality_of_place > cat_treshold:
return True
return False
if __name__ == '__main__':
cfer = PackageLocationClassifier()

View File

@ -1,26 +0,0 @@
food,normal,20,0.3,0.95,1
food,normal,-15,0.3,0.2,0
metal,normal,-15,0.3,0.2,0
frozen_food,freezed,-15,0.2,1,1
frozen_food,freezed,20,0.3,0.01,0
frozen_food,freezed,30,0.5,0,0
frozen_food,freezed,28,0.5,0,0
frozen_food,freezed,28,0.3,0,0
electronic,keep_dry,22,0.3,0.99,1
electronic,keep_dry,25,0.3,0.99,1
electronic,keep_dry,25,0.7,0.4,0
electronic,keep_dry,28,0.7,0.3,0
gasoline,flammable,28,0.3,0.2,0
gasoline,flammable,28,0.7,0.2,0
gasoline,flammable,22,0.5,0.95,0
gasoline,flammable,20,0.5,1,1
gasoline,flammable,20,0.2,1,1
books,keep_dry,30,0.7,0.3,0
books,keep_dry,30,0.3,0.85,1
books,keep_dry,25,0.2,1,1
glass,fragile,-15,0.3,0.1,0
seeds,freezed,-15,0.3,1,1
seeds,freezed,20,0.3,0.1,0
metal,normal,25,0.4,0.99,1
wood,normal,26,0.3,0.99,1
wood,normal,22,0.3,1,1
1 food normal 20 0.3 0.95 1
2 food normal -15 0.3 0.2 0
3 metal normal -15 0.3 0.2 0
4 frozen_food freezed -15 0.2 1 1
5 frozen_food freezed 20 0.3 0.01 0
6 frozen_food freezed 30 0.5 0 0
7 frozen_food freezed 28 0.5 0 0
8 frozen_food freezed 28 0.3 0 0
9 electronic keep_dry 22 0.3 0.99 1
10 electronic keep_dry 25 0.3 0.99 1
11 electronic keep_dry 25 0.7 0.4 0
12 electronic keep_dry 28 0.7 0.3 0
13 gasoline flammable 28 0.3 0.2 0
14 gasoline flammable 28 0.7 0.2 0
15 gasoline flammable 22 0.5 0.95 0
16 gasoline flammable 20 0.5 1 1
17 gasoline flammable 20 0.2 1 1
18 books keep_dry 30 0.7 0.3 0
19 books keep_dry 30 0.3 0.85 1
20 books keep_dry 25 0.2 1 1
21 glass fragile -15 0.3 0.1 0
22 seeds freezed -15 0.3 1 1
23 seeds freezed 20 0.3 0.1 0
24 metal normal 25 0.4 0.99 1
25 wood normal 26 0.3 0.99 1
26 wood normal 22 0.3 1 1

View File

@ -1,376 +0,0 @@
product,category,temperature,humidity,chance_of_survive,place_here
food,normal, 20, 0.5, 0.85, 1
food,normal,25, 0.7, 0.6, 0
electronic,keep_dry,20, 0.3, 0.95, 1
wood,normal,24, 0.5, 0.9, 1
electronic,keep_dry,25, 0.7, 0.4, 0
ammo,flammable,28, 0.4, 0.2, 0
ammo,flammable,27, 0.4, 0.25, 0
ammo,flammable,27, 0.6, 0.22, 0
ammo,flammable,22, 0.5, 0.8, 1
ammo,flammable,23, 0.5, 0.7, 0
clothes,keep_dry,25, 0.6, 0.4, 0
clothes,keep_dry,25, 0.7, 0.25, 0
clothes,keep_dry,25, 0.7, 0.25, 0
electronic,keep_dry,22,0.5,0.7,0
electronic,keep_dry,22,0.7,0.45,0
electronic,keep_dry,22,0.3,0.85,1
electronic,keep_dry,22,0.2,0.99,1
clothes,keep_dry,25, 0.7, 0.25, 0
clothes,keep_dry,25, 0.7, 0.25, 0
clothes,keep_dry,24, 0.2, 0.95, 0
frozen_food,freezed,24, 0.5, 0.001, 0
frozen_food,freezed,22, 0.5, 0.001, 0
frozen_food,freezed, 20, 0.5, 0.004, 0
frozen_food,freezed,-15, 0.3, 0.999, 1
frozen_food,freezed,-15, 0.2, 0.999, 1
frozen_food,freezed,-10, 0.3, 0.995, 1
frozen_food,freezed, -15, 0.2, 1.00, 1
frozen_food,freezed,24, 0.5, 0.001, 0
frozen_food,freezed,22, 0.5, 0.001, 0
frozen_food,freezed, 20, 0.5, 0.004, 0
frozen_food,freezed,-15, 0.3, 0.999, 1
frozen_food,freezed,-15, 0.2, 0.999, 1
frozen_food,freezed,-10, 0.3, 0.995, 1
frozen_food,freezed, -15, 0.2, 1.00, 1
frozen_food,freezed,24, 0.5, 0.001, 0
frozen_food,freezed,22, 0.5, 0.001, 0
frozen_food,freezed, 20, 0.5, 0.004, 0
frozen_food,freezed,-15, 0.3, 0.999, 1
frozen_food,freezed,-15, 0.2, 0.999, 1
frozen_food,freezed,-10, 0.3, 0.995, 1
frozen_food,freezed, -15, 0.2, 1.00, 1
clothes,keep_dry,28, 0.4, 0.7, 0
clothes,keep_dry, 22, 0.4, 0.95, 1
clothes,keep_dry, 21, 0.5, 0.5, 0
metal,normal,20, 0.3, 1, 1
metal,normal, 21, 0.3, 1, 1
metal,normal, -10, 0.3, 0.2, 1
metal,normal,28, 0.7, 0.9, 1
metal,normal,30, 0.7, 0.9, 1
wood,normal,25, 0.2, 0.98, 1
wood,normal,28, 0.7, 0.65, 0
books,keep_dry, 26, 0.7, 0.4, 0
books,keep_dry, 24, 0.5, 0.7, 0
books,keep_dry, 25, 0.3, 0.99, 1
books,keep_dry, 22, 0.4, 0.78, 0
books,keep_dry, 25, 0.35, 0.85, 1
books,keep_dry, 20, 0.2, 1, 1
drugs,keep_dry, 25, 0.5, 0.8, 0
drugs,keep_dry, 20, 0.3, 0.99, 1
drugs,keep_dry, 21, 0.3, 0.99, 1
drugs,keep_dry, 22, 0.7, 0.75, 0
drugs,keep_dry, 28, 0.3, 0.81, 0
drugs,keep_dry, 23, 0.3, 0.88, 1
drugs,keep_dry, 21, 0.37, 0.90, 1
glass,fragile, 20, 0.7, 0.995, 1
glass,fragile, -15, 0.3, 0.2, 0
vials,fragile, -15, 0.3, 0.2, 0
vials,fragile, 20, 0.5, 0.95, 1
plate,fragile, 25, 0.3, 1, 1
phials,fragile, 25, 0.5, 0.999, 1
cardboard,keep_dry, 22, 0.3, 0.999, 1
cardboard,keep_dry, 23, 0.7, 0.5, 0
cardboard,keep_dry, 28, 0.7, 0.4, 0
cardboard,keep_dry, 28, 0.5, 0.55, 0
cardboard,keep_dry, 25, 0.7, 0.45, 0
cardboard,keep_dry, 27, 0.3, 0.9, 1
cardboard,keep_dry, 29, 0.3, 0.88, 1
cardboard,keep_dry, 24, 0.4, 0.8, 1
frozen food,freezed, 20, 0.4, 0.001, 0
seeds,freezed, 25, 0.5, 0.2, 0
seeds,freezed, 20, 0.8, 0.01, 0
seeds,freezed, -10, 0.3, 0.998, 1
seeds,freezed, 20, 0.3, 0.6, 0
seeds,freezed, -8, 0.3, 0.99, 1
seeds,freezed, -10, 0.5, 0.995, 1
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.4, 1, 1
frozen food,freezed,-15, 0.3, 1, 1
frozen food,freezed,-15, 0.3, 1, 1
frozen food,freezed,-15, 0.3, 1, 1
frozen food,freezed,-15, 0.3, 1, 1
frozen food,freezed,-14, 0.3, 1, 1
frozen food,freezed,-12, 0.3, 0.999, 1
frozen food,freezed,-10, 0.3, 0.99, 1
frozen food,freezed,20, 0.5, 0.01, 0
food,normal,28,0.5,0.7,0
food,normal,26,0.3,0.9,1
food,normal,22,0.3,0.99,1
gasoline,flammable, 20, 0.4, 1, 1
gasoline,flammable,-15,0.3,0.5,0
metal,normal,-15,0.3,0.1,0
metal,normal,-15,0.4,0.1,0
metal,normal,-15,0.2,0.1,0
metal,normal,-10,0.2,0.1,0
electronic,keep_dry,-15,0.3,0.1,0
lacquer,flammable,-15,0.3,0.2,0
books,keep_dry,-15,0.3,0.3,0
plate,fragile, 20, 0.7, 1, 1
plate,fragile, 24, 0.3, 1, 1
plate,fragile, -15, 0.3, 0.15, 0
plate,fragile, -10, 0.3, 0.2, 0
vials,fragile, -15, 0.3, 0.12, 0
vials,fragile, 20, 0.7, 1, 1
vials,fragile, 20, 0.2, 1, 1
books,keep_dry, 20, 0.3, 1, 1
frozen food,freezed,20, 0.3, 0.01, 0
frozen food,freezed,22, 0.5, 0.01, 0
frozen food,freezed,22, 0.2, 0.01, 0
frozen food,freezed,22, 0.4, 0.01, 0
frozen food,freezed,22, 0.7, 0.01, 0
frozen food,freezed,20, 0.5, 0.01, 0
frozen food,freezed,24, 0.3, 0.01, 0
frozen food,freezed,20, 0.5, 0.01, 0
frozen food,freezed,28, 0.3, 0.01, 0
frozen food,freezed,20, 0.5, 0.01, 0
frozen food,freezed,20, 0.3, 0.01, 0
frozen food,freezed,21, 0.5, 0.01, 0
frozen food,freezed,20, 0.3, 0.01, 0
frozen food,freezed,20, 0.5, 0.01, 0
frozen food,freezed,23, 0.3, 0.01, 0
frozen food,freezed,20, 0.5, 0.01, 0
frozen food,freezed,22, 0.3, 0.01, 0
frozen food,freezed,25, 0.5, 0.01, 0
frozen food,freezed,20, 0.3, 0.01, 0
frozen food,freezed,20, 0.7, 0.01, 0
frozen food,freezed,20, 0.2, 0.01, 0
seeds,freezed, 25, 0.5, 0.2, 0
seeds,freezed, 20, 0.8, 0.01, 0
seeds,freezed, -10, 0.3, 0.998, 1
seeds,freezed, 20, 0.3, 0.6, 0
seeds,freezed, -8, 0.3, 0.99, 1
seeds,freezed, -10, 0.5, 0.995, 1
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.4, 1, 1
frozen food,freezed,22, 0.3, 0.00001, 0
porcelain,fragile,20, 0.3, 0.99, 1
porcelain,fragile,22, 0.5, 0.999, 1
cosmetics,normal,20, 0.3, 1, 1
cosmetics,normal,28, 0.7, 0.90, 1
cosmetics,normal,22, 0.5, 0.99, 1
plastic,normal,25, 0.7, 1, 1
plastic,normal,24, 0.7, 1, 1
plastic,normal,30, 0.4, 0.99, 1
plastic,normal, 28, 0.6, 1, 1
wood,normal,28,0.5,0.96,1
wood,normal,27,0.4,1,1
plastic,normal,30, 0.7, 0.985, 1
electronic,keep_dry, 25, 0.6, 0.6, 0
metal,normal, 22, 0.7, 0.99, 1
metal,normal, 30, 0.5, 0.999, 1
metal,normal, 25, 0.3, 1, 1
metal,normal, 24, 0.4, 1, 1
seeds,freezed, 25, 0.5, 0.2, 0
seeds,freezed, 20, 0.8, 0.01, 0
seeds,freezed, -10, 0.3, 0.998, 1
seeds,freezed, 20, 0.3, 0.6, 0
seeds,freezed, -8, 0.3, 0.99, 1
seeds,freezed, -10, 0.5, 0.995, 1
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.4, 1, 1
lacquer,flammable, 30, 0.3, 0.4, 0
lacquer,flammable, 28, 0.5, 0.6, 0
lacquer,flammable, 28, 0.4, 0.6, 0
lacquer,flammable, 29, 0.3, 0.45, 0
lacquer,flammable, 25, 0.6, 0.65, 0
lacquer,flammable, 24, 0.7, 0.89, 0
lacquer,flammable, 22, 0.6, 0.95, 1
lacquer,flammable, 20, 0.4, 1, 1
lacquer,flammable, 20, 0.7, 1, 1
lacquer,flammable, 21, 0.6, 0.99, 1
lacquer,flammable, 23, 0.4, 0.9, 0
lacquer,flammable, 26, 0.2, 0.6, 0
lacquer,flammable, 30, 0.2, 0.35, 0
lacquer,flammable, 30, 0.7, 0.35, 0
gasoline,flammable, 30, 0.4, 0.1, 0
gasoline,flammable, 30, 0.7, 0.1, 0
gasoline,flammable, 26, 0.5, 0.4, 0
gasoline,flammable, 25, 0.7, 0.5, 0
gasoline,flammable, 25, 0.2, 0.5, 0
gasoline,flammable, 21, 0.7, 0.99, 1
gasoline,flammable, 22, 0.5, 0.92, 1
gasoline,flammable, 22, 0.7, 0.93, 1
gasoline,flammable, 20, 0.5, 1, 1
gasoline,flammable, 20, 0.7, 1, 1
gasoline,flammable, 20, 0.4, 1, 1
plate,fragile, 20, 0.7, 1, 1
plate,fragile, 24, 0.3, 1, 1
plate,fragile, -15, 0.3, 0.1, 0
plate,fragile, -10, 0.3, 0.2, 0
vials,fragile, -15, 0.3, 0.15, 0
vials,fragile, 20, 0.7, 1, 1
vials,fragile, 20, 0.2, 1, 1
books,keep_dry, 20, 0.3, 1, 1
books,keep_dry, 20, 0.7, 0.79, 0
books,keep_dry, 25, 0.7, 0.75, 0
books,keep_dry, 25, 0.2, 0.99, 1
books,keep_dry, 28, 0.2, 0.9, 1
books,keep_dry, 28, 0.7, 0.2, 0
books,keep_dry, 28, 0.6, 0.25, 0
books,keep_dry, 26, 0.6, 0.28, 0
books,keep_dry,26, 0.2, 0.95, 1
cardboard,keep_dry, 28, 0.7, 0.15, 0
cardboard,keep_dry, 28, 0.2, 0.9, 1
cardboard,keep_dry, 25, 0.2, 0.95, 1
cardboard,keep_dry, 25, 0.6, 0.3, 0
cardboard,keep_dry, 25, 0.7, 0.2, 0
electronics,keep_dry, 21, 0.4, 0.999, 1
electronic,keep_dry, 21, 0.7, 0.68, 0
electronic,keep_dry, 29, 0.2, 0.998, 1
electronic,keep_dry, 29, 0.6, 0.45, 0
electronic,keep_dry, 29, 0.7, 0.35, 0
electronic,keep_dry, 25, 0.4, 0.82, 1
electronic,keep_dry, 25, 0.5, 0.70, 0
electronic,keep_dry, 25, 0.7, 0.5, 0
electronic,keep_dry, 28, 0.2, 0.995, 1
electronic,keep_dry, 28, 0.4, 0.81, 1
electronic,keep_dry, 28, 0.6, 0.5, 0
electronic,keep_dry, 28, 0.7, 0.4, 0
electronic,keep_dry, 28, 0.3, 0.93, 1
clothes,keep_dry, 28, 0.3, 0.95, 1
clothes,keep_dry, 28, 0.2, 0.999, 1
clothes,keep_dry, 28, 0.7, 0.3, 0
wood,normal, 27, 0.2, 1, 1
wood,normal, 27, 0.7, 0.95, 1
wood,normal, 25, 0.7, 0.96, 1
wood,normal, 20, 0.3, 1, 1
wood,normal, 23, 0.2, 1, 1
wood,normal, 23, 0.7, 0.98, 1
electronic,keep_dry, 29, 0.6, 0.45, 0
electronic,keep_dry, 29, 0.7, 0.35, 0
electronic,keep_dry, 24, 0.4, 0.82, 1
electronic,keep_dry, 20, 0.5, 0.72, 0
electronic,keep_dry, 25, 0.7, 0.5, 0
electronic,keep_dry, 28, 0.2, 0.995, 1
electronic,keep_dry, 28, 0.4, 0.81, 1
electronic,keep_dry, 28, 0.6, 0.5, 0
electronic,keep_dry, 30, 0.7, 0.35, 0
electronic,keep_dry, 28, 0.3, 0.93, 1
clothes,keep_dry, 28, 0.3, 0.95, 1
clothes,keep_dry, 28, 0.2, 0.999, 1
clothes,keep_dry, 28, 0.7, 0.3, 0
wood,normal, 27, 0.2, 1, 1
wood,normal, 27, 0.7, 0.95, 1
wood,normal, 25, 0.7, 0.96, 1
wood,normal, 20, 0.3, 1, 1
wood,normal, 23, 0.2, 1, 1
wood,normal, 23, 0.7, 0.98, 1
wood,normal,30,0.7,0.95,1
books,keep_dry, 20, 0.7, 0.79, 0
books,keep_dry, 25, 0.7, 0.75, 0
books,keep_dry, 25, 0.2, 0.99, 1
books,keep_dry,-15,0.3,0.2,0
books,keep_dry,-15,0.2,0.2,0
cardboard,keep_dry,-10,0.2,0.2,0
cardboard,keep_dry,-15,0.3,0.2,0
books,keep_dry, 28, 0.2, 0.9, 1
books,keep_dry, 28, 0.7, 0.2, 0
books,keep_dry, 28, 0.6, 0.25, 0
books,keep_dry, 26, 0.6, 0.28, 0
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.3, 1, 1
books,keep_dry,26, 0.2, 0.95, 1
cardboard,keep_dry, 28, 0.7, 0.15, 0
cardboard,keep_dry, 28, 0.2, 0.9, 1
cardboard,keep_dry, 25, 0.2, 0.95, 1
cardboard,keep_dry, 25, 0.6, 0.3, 0
cardboard,keep_dry, 25, 0.7, 0.2, 0
electronics,keep_dry, 21, 0.4, 0.999, 1
electronic,keep_dry, 21, 0.7, 0.68, 0
electronic,keep_dry, 29, 0.2, 0.998, 1
electronic,keep_dry, 29, 0.6, 0.45, 0
cardboard,keep_dry, 30, 0.7, 0.2, 0
cardboard,keep_dry, 30, 0.6, 0.25, 0
electronic,keep_dry, 29, 0.7, 0.35, 0
electronic,keep_dry, 25, 0.4, 0.82, 1
electronic,keep_dry, 25, 0.5, 0.70, 0
electronic,keep_dry, 25, 0.7, 0.5, 0
electronic,keep_dry, 28, 0.2, 0.995, 1
electronic,keep_dry, 28, 0.4, 0.81, 1
electronic,keep_dry, 28, 0.6, 0.5, 0
electronic,keep_dry, 28, 0.7, 0.4, 0
electronic,keep_dry, 28, 0.3, 0.93, 1
clothes,keep_dry, 28, 0.3, 0.95, 1
clothes,keep_dry, 28, 0.2, 0.999, 1
clothes,keep_dry, 28, 0.7, 0.3, 0
wood,normal, 27, 0.2, 1, 1
wood,normal, 27, 0.7, 0.95, 1
wood,normal, 25, 0.7, 0.96, 1
wood,normal, 20, 0.3, 1, 1
cardboard,keep_dry, 28, 0.5, 0.55, 0
cardboard,keep_dry, 25, 0.7, 0.45, 0
cardboard,keep_dry, 27, 0.3, 0.9, 1
cardboard,keep_dry, 29, 0.3, 0.9, 1
cardboard,keep_dry, 24, 0.4, 0.8, 1
frozen food,freezed, 20, 0.4, 0.001, 0
seeds,freezed, 25, 0.5, 0.2, 0
seeds,freezed, 20, 0.8, 0.01, 0
seeds,freezed, -10, 0.3, 0.998, 1
seeds,freezed, 20, 0.3, 0.6, 0
seeds,freezed, -8, 0.3, 0.99, 1
seeds,freezed, -10, 0.5, 0.995, 1
seeds,freezed, -15, 0.3, 1, 1
seeds,freezed, -15, 0.4, 1, 1
frozen food,freezed,-15, 0.3, 1, 1
frozen food,freezed,-15, 0.3, 1, 1
frozen food,freezed,-15, 0.3, 1, 1
frozen food,freezed,-15, 0.3, 1, 1
frozen food,freezed,-14, 0.3, 1, 1
frozen food,freezed,-12, 0.3, 0.999, 1
frozen food,freezed,-2, 0.3, 0.7, 0
frozen food,freezed,2, 0.3, 0.5, 0
frozen food,freezed,5, 0.3, 0.2, 0
frozen food,freezed,-10, 0.3, 0.99, 1
frozen food,freezed,20, 0.3, 0, 0
frozen food,freezed,25, 0.3, 0, 0
frozen food,freezed,25, 0.7, 0, 0
frozen food,freezed,22, 0.4, 0, 0
frozen food,freezed,22, 0.5, 0, 0
frozen food,freezed,22, 0.2, 0, 0
seeds,freezed, 25, 0.5, 0, 0
seeds,freezed, 20, 0.8, 0.01, 0
seeds,freezed, -5, 0.3, 0.5, 1
seeds,freezed, 20, 0.3, 0.1, 0
seeds,freezed, -8, 0.3, 0.8, 1
seeds,freezed, 20, 0.5, 0.1, 0
wood,normal, 20, 0.3, 1, 1
wood,normal, 23, 0.2, 1, 1
wood,normal, 23, 0.7, 0.98, 1
electronic,keep_dry, 29, 0.6, 0.45, 0
electronic,keep_dry, 29, 0.7, 0.35, 0
electronic,keep_dry, 24, 0.4, 0.82, 1
electronic,keep_dry, 20, 0.5, 0.72, 0
electronic,keep_dry, 25, 0.7, 0.5, 0
electronic,keep_dry, 28, 0.2, 0.995, 1
electronic,keep_dry, 28, 0.4, 0.81, 1
electronic,keep_dry, 28, 0.6, 0.5, 0
electronic,keep_dry, 30, 0.7, 0.35, 0
electronic,keep_dry, 28, 0.3, 0.93, 1
clothes,keep_dry, 28, 0.3, 0.95, 1
clothes,keep_dry, 28, 0.2, 0.999, 1
clothes,keep_dry, 28, 0.7, 0.3, 0
wood,normal, 27, 0.2, 1, 1
wood,normal, 27, 0.7, 0.95, 1
wood,normal, 25, 0.7, 0.96, 1
wood,normal, 20, 0.3, 1, 1
wood,normal, 23, 0.2, 1, 1
wood,normal, 23, 0.7, 0.98, 1
wood,normal,-10,0.3,0.2,0
wood,normal,-15,0.3,0.1,0
wood,normal,-15,0.2,0.2,0
wood,normal,-15,0.3,0.1,0
wood,normal,30,0.7,0.95,1
food,normal,28,0.5,0.7,0
food,normal,26,0.3,0.9,1
food,normal,-15,0.2,0.2,0
food,normal,-12,0.2,0.3,0
electronic,keep_dry,-15,0.3,0.1,0
food,normal,-15,0.3,0.2,0
food,normal,22,0.3,0.99,1
1 product category temperature humidity chance_of_survive place_here
2 food normal 20 0.5 0.85 1
3 food normal 25 0.7 0.6 0
4 electronic keep_dry 20 0.3 0.95 1
5 wood normal 24 0.5 0.9 1
6 electronic keep_dry 25 0.7 0.4 0
7 ammo flammable 28 0.4 0.2 0
8 ammo flammable 27 0.4 0.25 0
9 ammo flammable 27 0.6 0.22 0
10 ammo flammable 22 0.5 0.8 1
11 ammo flammable 23 0.5 0.7 0
12 clothes keep_dry 25 0.6 0.4 0
13 clothes keep_dry 25 0.7 0.25 0
14 clothes keep_dry 25 0.7 0.25 0
15 electronic keep_dry 22 0.5 0.7 0
16 electronic keep_dry 22 0.7 0.45 0
17 electronic keep_dry 22 0.3 0.85 1
18 electronic keep_dry 22 0.2 0.99 1
19 clothes keep_dry 25 0.7 0.25 0
20 clothes keep_dry 25 0.7 0.25 0
21 clothes keep_dry 24 0.2 0.95 0
22 frozen_food freezed 24 0.5 0.001 0
23 frozen_food freezed 22 0.5 0.001 0
24 frozen_food freezed 20 0.5 0.004 0
25 frozen_food freezed -15 0.3 0.999 1
26 frozen_food freezed -15 0.2 0.999 1
27 frozen_food freezed -10 0.3 0.995 1
28 frozen_food freezed -15 0.2 1.00 1
29 frozen_food freezed 24 0.5 0.001 0
30 frozen_food freezed 22 0.5 0.001 0
31 frozen_food freezed 20 0.5 0.004 0
32 frozen_food freezed -15 0.3 0.999 1
33 frozen_food freezed -15 0.2 0.999 1
34 frozen_food freezed -10 0.3 0.995 1
35 frozen_food freezed -15 0.2 1.00 1
36 frozen_food freezed 24 0.5 0.001 0
37 frozen_food freezed 22 0.5 0.001 0
38 frozen_food freezed 20 0.5 0.004 0
39 frozen_food freezed -15 0.3 0.999 1
40 frozen_food freezed -15 0.2 0.999 1
41 frozen_food freezed -10 0.3 0.995 1
42 frozen_food freezed -15 0.2 1.00 1
43 clothes keep_dry 28 0.4 0.7 0
44 clothes keep_dry 22 0.4 0.95 1
45 clothes keep_dry 21 0.5 0.5 0
46 metal normal 20 0.3 1 1
47 metal normal 21 0.3 1 1
48 metal normal -10 0.3 0.2 1
49 metal normal 28 0.7 0.9 1
50 metal normal 30 0.7 0.9 1
51 wood normal 25 0.2 0.98 1
52 wood normal 28 0.7 0.65 0
53 books keep_dry 26 0.7 0.4 0
54 books keep_dry 24 0.5 0.7 0
55 books keep_dry 25 0.3 0.99 1
56 books keep_dry 22 0.4 0.78 0
57 books keep_dry 25 0.35 0.85 1
58 books keep_dry 20 0.2 1 1
59 drugs keep_dry 25 0.5 0.8 0
60 drugs keep_dry 20 0.3 0.99 1
61 drugs keep_dry 21 0.3 0.99 1
62 drugs keep_dry 22 0.7 0.75 0
63 drugs keep_dry 28 0.3 0.81 0
64 drugs keep_dry 23 0.3 0.88 1
65 drugs keep_dry 21 0.37 0.90 1
66 glass fragile 20 0.7 0.995 1
67 glass fragile -15 0.3 0.2 0
68 vials fragile -15 0.3 0.2 0
69 vials fragile 20 0.5 0.95 1
70 plate fragile 25 0.3 1 1
71 phials fragile 25 0.5 0.999 1
72 cardboard keep_dry 22 0.3 0.999 1
73 cardboard keep_dry 23 0.7 0.5 0
74 cardboard keep_dry 28 0.7 0.4 0
75 cardboard keep_dry 28 0.5 0.55 0
76 cardboard keep_dry 25 0.7 0.45 0
77 cardboard keep_dry 27 0.3 0.9 1
78 cardboard keep_dry 29 0.3 0.88 1
79 cardboard keep_dry 24 0.4 0.8 1
80 frozen food freezed 20 0.4 0.001 0
81 seeds freezed 25 0.5 0.2 0
82 seeds freezed 20 0.8 0.01 0
83 seeds freezed -10 0.3 0.998 1
84 seeds freezed 20 0.3 0.6 0
85 seeds freezed -8 0.3 0.99 1
86 seeds freezed -10 0.5 0.995 1
87 seeds freezed -15 0.3 1 1
88 seeds freezed -15 0.4 1 1
89 frozen food freezed -15 0.3 1 1
90 frozen food freezed -15 0.3 1 1
91 frozen food freezed -15 0.3 1 1
92 frozen food freezed -15 0.3 1 1
93 frozen food freezed -14 0.3 1 1
94 frozen food freezed -12 0.3 0.999 1
95 frozen food freezed -10 0.3 0.99 1
96 frozen food freezed 20 0.5 0.01 0
97 food normal 28 0.5 0.7 0
98 food normal 26 0.3 0.9 1
99 food normal 22 0.3 0.99 1
100 gasoline flammable 20 0.4 1 1
101 gasoline flammable -15 0.3 0.5 0
102 metal normal -15 0.3 0.1 0
103 metal normal -15 0.4 0.1 0
104 metal normal -15 0.2 0.1 0
105 metal normal -10 0.2 0.1 0
106 electronic keep_dry -15 0.3 0.1 0
107 lacquer flammable -15 0.3 0.2 0
108 books keep_dry -15 0.3 0.3 0
109 plate fragile 20 0.7 1 1
110 plate fragile 24 0.3 1 1
111 plate fragile -15 0.3 0.15 0
112 plate fragile -10 0.3 0.2 0
113 vials fragile -15 0.3 0.12 0
114 vials fragile 20 0.7 1 1
115 vials fragile 20 0.2 1 1
116 books keep_dry 20 0.3 1 1
117 frozen food freezed 20 0.3 0.01 0
118 frozen food freezed 22 0.5 0.01 0
119 frozen food freezed 22 0.2 0.01 0
120 frozen food freezed 22 0.4 0.01 0
121 frozen food freezed 22 0.7 0.01 0
122 frozen food freezed 20 0.5 0.01 0
123 frozen food freezed 24 0.3 0.01 0
124 frozen food freezed 20 0.5 0.01 0
125 frozen food freezed 28 0.3 0.01 0
126 frozen food freezed 20 0.5 0.01 0
127 frozen food freezed 20 0.3 0.01 0
128 frozen food freezed 21 0.5 0.01 0
129 frozen food freezed 20 0.3 0.01 0
130 frozen food freezed 20 0.5 0.01 0
131 frozen food freezed 23 0.3 0.01 0
132 frozen food freezed 20 0.5 0.01 0
133 frozen food freezed 22 0.3 0.01 0
134 frozen food freezed 25 0.5 0.01 0
135 frozen food freezed 20 0.3 0.01 0
136 frozen food freezed 20 0.7 0.01 0
137 frozen food freezed 20 0.2 0.01 0
138 seeds freezed 25 0.5 0.2 0
139 seeds freezed 20 0.8 0.01 0
140 seeds freezed -10 0.3 0.998 1
141 seeds freezed 20 0.3 0.6 0
142 seeds freezed -8 0.3 0.99 1
143 seeds freezed -10 0.5 0.995 1
144 seeds freezed -15 0.3 1 1
145 seeds freezed -15 0.4 1 1
146 frozen food freezed 22 0.3 0.00001 0
147 porcelain fragile 20 0.3 0.99 1
148 porcelain fragile 22 0.5 0.999 1
149 cosmetics normal 20 0.3 1 1
150 cosmetics normal 28 0.7 0.90 1
151 cosmetics normal 22 0.5 0.99 1
152 plastic normal 25 0.7 1 1
153 plastic normal 24 0.7 1 1
154 plastic normal 30 0.4 0.99 1
155 plastic normal 28 0.6 1 1
156 wood normal 28 0.5 0.96 1
157 wood normal 27 0.4 1 1
158 plastic normal 30 0.7 0.985 1
159 electronic keep_dry 25 0.6 0.6 0
160 metal normal 22 0.7 0.99 1
161 metal normal 30 0.5 0.999 1
162 metal normal 25 0.3 1 1
163 metal normal 24 0.4 1 1
164 seeds freezed 25 0.5 0.2 0
165 seeds freezed 20 0.8 0.01 0
166 seeds freezed -10 0.3 0.998 1
167 seeds freezed 20 0.3 0.6 0
168 seeds freezed -8 0.3 0.99 1
169 seeds freezed -10 0.5 0.995 1
170 seeds freezed -15 0.3 1 1
171 seeds freezed -15 0.4 1 1
172 lacquer flammable 30 0.3 0.4 0
173 lacquer flammable 28 0.5 0.6 0
174 lacquer flammable 28 0.4 0.6 0
175 lacquer flammable 29 0.3 0.45 0
176 lacquer flammable 25 0.6 0.65 0
177 lacquer flammable 24 0.7 0.89 0
178 lacquer flammable 22 0.6 0.95 1
179 lacquer flammable 20 0.4 1 1
180 lacquer flammable 20 0.7 1 1
181 lacquer flammable 21 0.6 0.99 1
182 lacquer flammable 23 0.4 0.9 0
183 lacquer flammable 26 0.2 0.6 0
184 lacquer flammable 30 0.2 0.35 0
185 lacquer flammable 30 0.7 0.35 0
186 gasoline flammable 30 0.4 0.1 0
187 gasoline flammable 30 0.7 0.1 0
188 gasoline flammable 26 0.5 0.4 0
189 gasoline flammable 25 0.7 0.5 0
190 gasoline flammable 25 0.2 0.5 0
191 gasoline flammable 21 0.7 0.99 1
192 gasoline flammable 22 0.5 0.92 1
193 gasoline flammable 22 0.7 0.93 1
194 gasoline flammable 20 0.5 1 1
195 gasoline flammable 20 0.7 1 1
196 gasoline flammable 20 0.4 1 1
197 plate fragile 20 0.7 1 1
198 plate fragile 24 0.3 1 1
199 plate fragile -15 0.3 0.1 0
200 plate fragile -10 0.3 0.2 0
201 vials fragile -15 0.3 0.15 0
202 vials fragile 20 0.7 1 1
203 vials fragile 20 0.2 1 1
204 books keep_dry 20 0.3 1 1
205 books keep_dry 20 0.7 0.79 0
206 books keep_dry 25 0.7 0.75 0
207 books keep_dry 25 0.2 0.99 1
208 books keep_dry 28 0.2 0.9 1
209 books keep_dry 28 0.7 0.2 0
210 books keep_dry 28 0.6 0.25 0
211 books keep_dry 26 0.6 0.28 0
212 books keep_dry 26 0.2 0.95 1
213 cardboard keep_dry 28 0.7 0.15 0
214 cardboard keep_dry 28 0.2 0.9 1
215 cardboard keep_dry 25 0.2 0.95 1
216 cardboard keep_dry 25 0.6 0.3 0
217 cardboard keep_dry 25 0.7 0.2 0
218 electronics keep_dry 21 0.4 0.999 1
219 electronic keep_dry 21 0.7 0.68 0
220 electronic keep_dry 29 0.2 0.998 1
221 electronic keep_dry 29 0.6 0.45 0
222 electronic keep_dry 29 0.7 0.35 0
223 electronic keep_dry 25 0.4 0.82 1
224 electronic keep_dry 25 0.5 0.70 0
225 electronic keep_dry 25 0.7 0.5 0
226 electronic keep_dry 28 0.2 0.995 1
227 electronic keep_dry 28 0.4 0.81 1
228 electronic keep_dry 28 0.6 0.5 0
229 electronic keep_dry 28 0.7 0.4 0
230 electronic keep_dry 28 0.3 0.93 1
231 clothes keep_dry 28 0.3 0.95 1
232 clothes keep_dry 28 0.2 0.999 1
233 clothes keep_dry 28 0.7 0.3 0
234 wood normal 27 0.2 1 1
235 wood normal 27 0.7 0.95 1
236 wood normal 25 0.7 0.96 1
237 wood normal 20 0.3 1 1
238 wood normal 23 0.2 1 1
239 wood normal 23 0.7 0.98 1
240 electronic keep_dry 29 0.6 0.45 0
241 electronic keep_dry 29 0.7 0.35 0
242 electronic keep_dry 24 0.4 0.82 1
243 electronic keep_dry 20 0.5 0.72 0
244 electronic keep_dry 25 0.7 0.5 0
245 electronic keep_dry 28 0.2 0.995 1
246 electronic keep_dry 28 0.4 0.81 1
247 electronic keep_dry 28 0.6 0.5 0
248 electronic keep_dry 30 0.7 0.35 0
249 electronic keep_dry 28 0.3 0.93 1
250 clothes keep_dry 28 0.3 0.95 1
251 clothes keep_dry 28 0.2 0.999 1
252 clothes keep_dry 28 0.7 0.3 0
253 wood normal 27 0.2 1 1
254 wood normal 27 0.7 0.95 1
255 wood normal 25 0.7 0.96 1
256 wood normal 20 0.3 1 1
257 wood normal 23 0.2 1 1
258 wood normal 23 0.7 0.98 1
259 wood normal 30 0.7 0.95 1
260 books keep_dry 20 0.7 0.79 0
261 books keep_dry 25 0.7 0.75 0
262 books keep_dry 25 0.2 0.99 1
263 books keep_dry -15 0.3 0.2 0
264 books keep_dry -15 0.2 0.2 0
265 cardboard keep_dry -10 0.2 0.2 0
266 cardboard keep_dry -15 0.3 0.2 0
267 books keep_dry 28 0.2 0.9 1
268 books keep_dry 28 0.7 0.2 0
269 books keep_dry 28 0.6 0.25 0
270 books keep_dry 26 0.6 0.28 0
271 seeds freezed -15 0.3 1 1
272 seeds freezed -15 0.3 1 1
273 seeds freezed -15 0.3 1 1
274 seeds freezed -15 0.3 1 1
275 seeds freezed -15 0.3 1 1
276 seeds freezed -15 0.3 1 1
277 books keep_dry 26 0.2 0.95 1
278 cardboard keep_dry 28 0.7 0.15 0
279 cardboard keep_dry 28 0.2 0.9 1
280 cardboard keep_dry 25 0.2 0.95 1
281 cardboard keep_dry 25 0.6 0.3 0
282 cardboard keep_dry 25 0.7 0.2 0
283 electronics keep_dry 21 0.4 0.999 1
284 electronic keep_dry 21 0.7 0.68 0
285 electronic keep_dry 29 0.2 0.998 1
286 electronic keep_dry 29 0.6 0.45 0
287 cardboard keep_dry 30 0.7 0.2 0
288 cardboard keep_dry 30 0.6 0.25 0
289 electronic keep_dry 29 0.7 0.35 0
290 electronic keep_dry 25 0.4 0.82 1
291 electronic keep_dry 25 0.5 0.70 0
292 electronic keep_dry 25 0.7 0.5 0
293 electronic keep_dry 28 0.2 0.995 1
294 electronic keep_dry 28 0.4 0.81 1
295 electronic keep_dry 28 0.6 0.5 0
296 electronic keep_dry 28 0.7 0.4 0
297 electronic keep_dry 28 0.3 0.93 1
298 clothes keep_dry 28 0.3 0.95 1
299 clothes keep_dry 28 0.2 0.999 1
300 clothes keep_dry 28 0.7 0.3 0
301 wood normal 27 0.2 1 1
302 wood normal 27 0.7 0.95 1
303 wood normal 25 0.7 0.96 1
304 wood normal 20 0.3 1 1
305 cardboard keep_dry 28 0.5 0.55 0
306 cardboard keep_dry 25 0.7 0.45 0
307 cardboard keep_dry 27 0.3 0.9 1
308 cardboard keep_dry 29 0.3 0.9 1
309 cardboard keep_dry 24 0.4 0.8 1
310 frozen food freezed 20 0.4 0.001 0
311 seeds freezed 25 0.5 0.2 0
312 seeds freezed 20 0.8 0.01 0
313 seeds freezed -10 0.3 0.998 1
314 seeds freezed 20 0.3 0.6 0
315 seeds freezed -8 0.3 0.99 1
316 seeds freezed -10 0.5 0.995 1
317 seeds freezed -15 0.3 1 1
318 seeds freezed -15 0.4 1 1
319 frozen food freezed -15 0.3 1 1
320 frozen food freezed -15 0.3 1 1
321 frozen food freezed -15 0.3 1 1
322 frozen food freezed -15 0.3 1 1
323 frozen food freezed -14 0.3 1 1
324 frozen food freezed -12 0.3 0.999 1
325 frozen food freezed -2 0.3 0.7 0
326 frozen food freezed 2 0.3 0.5 0
327 frozen food freezed 5 0.3 0.2 0
328 frozen food freezed -10 0.3 0.99 1
329 frozen food freezed 20 0.3 0 0
330 frozen food freezed 25 0.3 0 0
331 frozen food freezed 25 0.7 0 0
332 frozen food freezed 22 0.4 0 0
333 frozen food freezed 22 0.5 0 0
334 frozen food freezed 22 0.2 0 0
335 seeds freezed 25 0.5 0 0
336 seeds freezed 20 0.8 0.01 0
337 seeds freezed -5 0.3 0.5 1
338 seeds freezed 20 0.3 0.1 0
339 seeds freezed -8 0.3 0.8 1
340 seeds freezed 20 0.5 0.1 0
341 wood normal 20 0.3 1 1
342 wood normal 23 0.2 1 1
343 wood normal 23 0.7 0.98 1
344 electronic keep_dry 29 0.6 0.45 0
345 electronic keep_dry 29 0.7 0.35 0
346 electronic keep_dry 24 0.4 0.82 1
347 electronic keep_dry 20 0.5 0.72 0
348 electronic keep_dry 25 0.7 0.5 0
349 electronic keep_dry 28 0.2 0.995 1
350 electronic keep_dry 28 0.4 0.81 1
351 electronic keep_dry 28 0.6 0.5 0
352 electronic keep_dry 30 0.7 0.35 0
353 electronic keep_dry 28 0.3 0.93 1
354 clothes keep_dry 28 0.3 0.95 1
355 clothes keep_dry 28 0.2 0.999 1
356 clothes keep_dry 28 0.7 0.3 0
357 wood normal 27 0.2 1 1
358 wood normal 27 0.7 0.95 1
359 wood normal 25 0.7 0.96 1
360 wood normal 20 0.3 1 1
361 wood normal 23 0.2 1 1
362 wood normal 23 0.7 0.98 1
363 wood normal -10 0.3 0.2 0
364 wood normal -15 0.3 0.1 0
365 wood normal -15 0.2 0.2 0
366 wood normal -15 0.3 0.1 0
367 wood normal 30 0.7 0.95 1
368 food normal 28 0.5 0.7 0
369 food normal 26 0.3 0.9 1
370 food normal -15 0.2 0.2 0
371 food normal -12 0.2 0.3 0
372 electronic keep_dry -15 0.3 0.1 0
373 food normal -15 0.3 0.2 0
374 food normal 22 0.3 0.99 1

View File

@ -1,33 +0,0 @@
PRODUCT_TYPES = {
"freezed": [
"frozen food",
"seeds",
],
"fragile": [
"glass",
"porcelain",
"vials",
"phials",
"plate",
],
"keep_dry": [
"electronic",
"drugs",
"books",
"clothes",
"cardboard"
],
"normal": [
"cosmetics",
"wood",
"metal",
"plastic",
"food"
],
"flammable": [
"gasoline",
"lacquer",
"ammo"
]
}

View File

@ -1,74 +0,0 @@
absl-py==0.9.0
astroid==2.4.0
astunparse==1.6.3
backcall==0.1.0
cachetools==4.1.0
certifi==2020.4.5.2
chardet==3.0.4
cycler==0.10.0
decorator==4.4.2
et-xmlfile==1.0.1
gast==0.3.3
google-auth==1.17.2
google-auth-oauthlib==0.4.1
google-pasta==0.2.0
graphviz==0.14
grpcio==1.29.0
h5py==2.10.0
idna==2.9
importlib-metadata==1.6.1
ipython==7.14.0
ipython-genutils==0.2.0
isort==4.3.21
jdcal==1.4.1
jedi==0.17.0
joblib==0.14.1
Keras==2.3.1
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.2
kiwisolver==1.2.0
lazy-object-proxy==1.4.3
Markdown==3.2.2
matplotlib==3.2.1
mccabe==0.6.1
numpy==1.18.4
oauthlib==3.1.0
openpyxl==3.0.3
opt-einsum==3.2.1
pandas==1.0.3
parso==0.7.0
pexpect==4.8.0
pickleshare==0.7.5
prompt-toolkit==3.0.5
protobuf==3.12.2
ptyprocess==0.6.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pydotplus==2.0.2
pygame==1.9.6
Pygments==2.6.1
pylint==2.5.0
pyparsing==2.4.7
python-dateutil==2.8.1
pytz==2020.1
PyYAML==5.3.1
requests==2.23.0
requests-oauthlib==1.3.0
rsa==4.6
scikit-learn==0.22.2.post1
scipy==1.4.1
six==1.14.0
sklearn==0.0
tensorboard==2.2.2
tensorboard-plugin-wit==1.6.0.post3
tensorflow==2.2.0
tensorflow-estimator==2.2.0
termcolor==1.1.0
toml==0.10.0
traitlets==4.3.3
typed-ast==1.4.1
urllib3==1.25.9
wcwidth==0.1.9
Werkzeug==1.0.1
wrapt==1.12.1
zipp==3.1.0

View File

@ -1,95 +0,0 @@
#### Definicja pętli głównej przeszukiwania:
W algorytmie znajdowania najlepszej ścieżki wykorzystana została kolejka priorytetowa *PriorityQueue()* służąca do przechowywania wierzchołków do odwiedzenia. Dopóki nie jest ona pusta, działa pętla główna przeszukiwania. W pętli kolejno:
1. z kolejki wybierany jest wierzchołek o najniższym priorytecie
```python
while self.open:
_, current_node = self.open.get()
```
2. dodawany jest on do listy już przeszukanych wierzchołków
```python
self.closed.append(current_node)
```
3. sprawdzane jest czy aktualny wierzchołek jest jednocześnie celem, który miał zostać osiągnięty przez agenta
```python
if current_node.x == self.dest.x and current_node.y == self.dest.y:
while current_node.x != start_node.x or current_node.y != start_node.y:
self.path.append(current_node)
current_node = current_node.parent
return True
```
>(jeśli tak, od strony celu odtwarzana jest najkrótsza ścieżka prowadząca z aktualnego punktu do celu)
4. znajdowani są sąsiedzi danego wierzchołka, a następnie dla każdego z nich:
+ liczony jest koszt za pomocą funkcji heurystyki
```python
cost = current_node.g_cost + self.heuristic(current_node, neighbour)
```
+ sprawdane jest czy nie należy on do listy już przeszukanych wierzchołkow (jeśli tak, zostaje on pominięty)
```python
if self.check_if_closed(neighbour):
continue
```
+ jeśli znajduje się on już w kolejce priorytetowej ale z większym kosztem niż ten obecnie wyliczony, uaktualniony zostaje jego koszt oraz rodzic
```python
if self.check_if_open(neighbour):
if neighbour.g_cost > cost:
neighbour.g_cost = cost
neighbour.parent = current_node
```
+ w przeciwnym przypadku, zostaje on dodany do kolejki priorytetowej wraz ze swoim rodzicem oraz wyliczonym kosztem.
```python
else:
neighbour.g_cost = cost
neighbour.h_cost = self.heuristic(neighbour, self.dest)
neighbour.parent = current_node
self.open.put((neighbour.g_cost, neighbour))
```
#### Definicja funkcji następnika:
```python
def get_neighbours(self, node: Node):
neighbours = []
if self.check_if_can_move(Coordinates(node.x + 1, node.y)):
neighbours.append(Node(node.x + 1, node.y))
if self.check_if_can_move(Coordinates(node.x - 1, node.y)):
neighbours.append(Node(node.x - 1, node.y))
if self.check_if_can_move(Coordinates(node.x, node.y + 1)):
neighbours.append(Node(node.x, node.y + 1))
if self.check_if_can_move(Coordinates(node.x, node.y - 1)):
neighbours.append(Node(node.x, node.y - 1))
return neighbours
```
Funkcja zwracająca następników w naszym projekcie wykorzystuje sąsiedztwo von Neumanna. Sąsiadami danej płytki, są 4 najbliższe płytki znajdujące się od niej powyżej, poniżej, na prawo oraz na lewo.
Dla każdego z 4 potencjalnych sąsiadów sprawdzane jest najpierw czy takowy istnieje za pomocą funkcji *check_if_can_move*:
```python
def check_if_can_move(self, next_coords: Coordinates):
tile_on_map = 0 <= next_coords.x < self.warehouse.width and 0 <= next_coords.y < self.warehouse.height
if not tile_on_map:
return False
next_tile = self.warehouse.tiles[next_coords.x][next_coords.y]
tile_passable = isinstance(next_tile, Tile) and next_tile.category.passable
return tile_passable
```
Funkcja ta sprawdza czy wybrany sąsiad znajduje się w obrębie magazynu i czy jest on płytką po której może przemieszczać się agent.
#### Definicja funkcji heurystyki:
```python
def heuristic(self, start: Node, goal: Node):
diff_x = pow(goal.x - start.x, 2)
diff_y = pow(goal.y - start.y, 2)
return round(sqrt(diff_x + diff_y), 3)
```
w naszym projekcie jako heurystyki używamy funkcji liczącej odległość euklidesową pomiędzy dwoma wybranymi punktami, z których drugi jest aktualnym celem który agent ma osiągnąć.

43
siec.py
View File

@ -1,43 +0,0 @@
import numpy
from keras.datasets import mnist
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Flatten
from keras.models import Sequential
from keras.utils import np_utils
from keras_preprocessing.image import load_img, img_to_array
img_rows, img_cols = 28, 28
input_shape = (img_rows, img_cols, 1)
producent = []
def imageClass(model):
model.add(Conv2D(75, kernel_size=(5, 5),
activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(100, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(500, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
nmodel = Sequential()
imageClass(nmodel)
nmodel.load_weights('model_weights.h5')
def imgSkan():
img_width, img_height = 28, 28
new_image = load_img('cyfra.png', target_size=(img_width, img_height), color_mode = "grayscale")
new_image = img_to_array(new_image)
new_image = new_image.reshape((1,) + new_image.shape)
prediction = nmodel.predict(new_image)
prediction = numpy.argmax(prediction)
print("Producent:", prediction)
producent.append(prediction)

View File

@ -1,86 +0,0 @@
# Temat podptojektu:
Stworzenie sieci neuronowej, która rozpoznaje odręcznie napisaną na paczce liczbę, która oznacza producenta paczki.
# Uczenie modelu
## Dane wejściowe:
### Pakiet Keras MNIST:
- dwa pliki:
- Plik z obrazkami
- Plik z poprawnymi odpowiedziami
### Format obrazków:
- rozmiar 28x28
- odcienie szarości (0-biały, 255- czarny)
- obrazki w postaci binarnej są zapisane w jeden plik
## Praca z pakietem:
1. Zdefiniowano dane treningowe: tensory wejściowe i tensory wartości docelowych.
2. Zdefiniowano warstwy sieci (lub modelu) przypisującej dane wejściowe do docelowych wartości.
3. Skonfigurowano proces uczenia, wybierając funkcję straty, optymalizator i monitorowane metryki.
4. Wykonano iteracje procesu uczenia na danych treningowych, wywołując metodę
fit() zdefiniowanego modelu
# Proces uczenia
-ustawiam seed, aby powtarzać wyniki
-pobieram dane
- konwertuję wymiary obrazu
- normalizuję dane
- konwertuję etykiety w kategorie
## Inicjalizuję sieć neuronową (sieć sekwencyjna).
model = Sequential()
model.add(Conv2D(75, kernel_size=(5, 5),
activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(100, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(500, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
### Dołączam kolejno warstwy:
- Conv2D - mnoży obrazek przez macierz 2x2
- activation='relu' - zeruje negatywne wyniki (funkcja aktuwacji)
- MaxPooling2D - zmienia rozdzielczość zdjęcia
- Droupout - ogranicza nadmierne dopasowanie
- Flatten - spłaszcza macierz do wektora
- Dense(10) - decyduje o przynależności zdjęcia do kategorii (cyfry od 0 do 9)
Activation='soft-max' - zwraca rozkład prawdopodobieństwa 10 różnych klas
## Kompilacja modelu:
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
Funkcja straty - "catecorical_crossentropy"
Optymalizator - "Adam"
Monitorowanie dokładności - "accuracy"
## Trenowanie modelu:
model.fit(X_train, Y_train, batch_size=200, epochs=10, validation_split=0.2, verbose=1)
trenuję model za pomocą funkcji fit()
### Pokazuję dokładność pracy na testowanych rannych
scores = model.evaluate(X_test, Y_test, verbose=0)
print("Dokadnosc na testowanych dannych: %.2f%%" % (scores[1]*100))
# Integracja z projektem
Tworzę model i ładuję wagi nauczonego modelu.
nmodel = Sequential()
imageClass(nmodel)
nmodel.load_weights('model_weights.h5')
Po podniesieniu paczki odpalana jest funkcja imgSkan(), która z czytuje ręcznie napisaną cyfrę i wpisuje nr producenta paczki.
def imgSkan():
img_width, img_height = 28, 28
new_image = load_img('cyfra.png', target_size=(img_width, img_height), color_mode = "grayscale")
new_image = img_to_array(new_image)
new_image = new_image.reshape((1,) + new_image.shape)
prediction = nmodel.predict(new_image)
prediction = numpy.argmax(prediction)
print("Producent:", prediction)
producent.append(prediction)

View File

@ -1,51 +0,0 @@
import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.utils import np_utils
numpy.random.seed(42)
img_rows, img_cols = 28, 28
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
Y_train = np_utils.to_categorical(y_train, 10)
Y_test = np_utils.to_categorical(y_test, 10)
model = Sequential()
model.add(Conv2D(75, kernel_size=(5, 5),
activation='relu',
input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Conv2D(100, (5, 5), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(500, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.summary()
model.fit(X_train, Y_train, batch_size=200, epochs=10, validation_split=0.2, verbose=1)
scores = model.evaluate(X_test, Y_test, verbose=0)
print("Dokadnosc na testowanych dannych: %.2f%%" % (scores[1]*100))
model.save_weights('model_weights.h5')

0
srodowisko_agenta.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 92 KiB

138
warehouse.py Executable file → Normal file
View File

@ -1,68 +1,43 @@
from attributes import PackStatus
from products_types import PRODUCT_TYPES
from attributes import PackSize, PackStatus
import random
import queue
from collections import namedtuple
import itertools
Coordinates = namedtuple("Coordinates", 'x y')
Coordinates = namedtuple("Coordinates",'x y')
class CategoryData:
def __init__(self, name, passable=False, can_store=True, location='general'):
def __init__(self, name, passable=False, can_store=True, location='general', pack_size=PackSize.ALL, cost=1):
self.name = name
self.passable = passable
self.can_store = can_store
self.cost = cost
self.location = location
self.pack_size = pack_size
def __repr__(self):
return self.name
class Pack:
def __init__(self, size=5, categ='normal', lays_on_field=None):
def __init__(self, size=PackSize.MEDIUM, categ='general', lays_on_field=None):
self.size = size
self.category = categ
self.products_inside = self.set_products_inside()
assert isinstance(lays_on_field, Tile), AssertionError("Attribute lays_on_field must be a Tile object! You know, package cannot lay in void :)")
self.lays_on_field = lays_on_field
self.status = self.set_status()
def set_status(self):
status = PackStatus.LOOSE
if self.lays_on_field.category.name in ['Floor', 'FridgeFloor']:
if self.lays_on_field.category.name == 'Floor':
status = PackStatus.LOOSE
else:
elif self.lays_on_field.category.name == 'Rack':
status = PackStatus.STORED
return status
def set_products_inside(self):
seed = random.random()
products_category = None
if seed < 0.6:
products_category = "normal"
elif 0.6 <= seed < 0.75:
products_category = "keep_dry"
elif 0.75 <= seed < 0.9:
products_category = "fragile"
elif 0.9 <= seed < 0.98:
products_category = "freezed"
elif 0.96 <= seed <= 1.0:
products_category = "flammable"
products_in_category = PRODUCT_TYPES.get(products_category, ["food"])
self.category = products_category
product_inside = random.choice(products_in_category)
# print(product_inside)
return product_inside
def __repr__(self):
return "Pack {} -{}, on field {}".format(self.products_inside, self.category, self.lays_on_field)
CATEGORY = {
'floor': CategoryData('Floor', True, False), #lava
'rack': CategoryData('Rack', False, True),
'fridge_floor': CategoryData('FridgeFloor', True, False, location='cold_room'),
'fridge': CategoryData('Fridge', False, True, location='cold_room')
'floor': CategoryData('Floor', True, False, cost=1), #lava
'rack': CategoryData('Rack', False, True, cost=100000),
# 'freezer': CategoryData('Freezer', False, True, location='cold_room')
}
@ -72,16 +47,11 @@ class Warehouse:
self.height = length
self.tiles = self.generate_map()
self.no_of_racks = no_of_racks
self.storage_types = ["Rack", "Fridge"]
self.no_of_packages = no_of_packages
self.generate_racks()
self.open_isolated_areas()
self.set_temperature(20, 30)
self.set_humidity()
self.create_fridge(8)
# print([row[0].air_temperature for row in self.tiles])
self.packages = self.place_packages(no_of_packages)
self.tiles[1][1] = Tile('floor', 1, 1)
def __str__(self):
return "Magazyn {}x{}".format(self.width, self.height)
@ -99,7 +69,7 @@ class Warehouse:
node_x, node_y = random.randrange(1, self.width-1), random.randrange(1, self.height-1)
node = self.tiles[node_x][node_y]
next_node = None
self.tiles[node_x][node_y] = Tile('rack', node_x, node_y, capacity=random.randrange(15, 20), temperature=node.air_temperature, humidity=node.humidity)
self.tiles[node_x][node_y] = Tile('rack', node_x, node_y)
q.put(node)
while not q.empty():
if next_node is not None:
@ -121,51 +91,7 @@ class Warehouse:
return
node_x = next_node.x_position
node_y = next_node.y_position
self.tiles[node_x][node_y] = Tile('rack', node_x, node_y, capacity=random.randrange(15, 20), temperature=next_node.air_temperature, humidity=next_node.humidity)
def set_temperature(self, min_temperature=20, max_temperature=30):
for num, row in enumerate(self.tiles):
row_temperature = min_temperature + round(num/2)
for cell in row:
cell.air_temperature = row_temperature
def set_humidity(self, min_humidity=0.2, max_humidity=0.7):
current_humidity = min_humidity
for y in range(self.height):
current_humidity += (0.1/4)
for x in range(self.width):
self.tiles[x][y].humidity = round(current_humidity, 1)
# print(round(current_humidity, 1))
def create_fridge(self, size):
x_corner = random.choice(['left', 'right'])
y_corner = random.choice(['top', 'bottom'])
start_x = None
start_y = None
end_x = None
end_y = None
if x_corner == 'left':
start_x = 0
end_x = size
else:
start_x = (self.width-1) - size
end_x = self.width - 1
if y_corner == 'top':
start_y = 0
end_y = size
else:
start_y = (self.height-1) - size
end_y = self.height - 1
rows = self.tiles[start_x:end_x].copy()
for num, row in enumerate(rows, start_x):
for index, tile in enumerate(row[start_y:end_y], start_y):
if self.tiles[num][index].category.name == "Floor":
self.tiles[num][index] = Tile('fridge_floor', num, index, temperature=-5)
else:
self.tiles[num][index] = Tile('fridge', num, index, capacity=random.randrange(10, 12), temperature=-15)
self.tiles[node_x][node_y] = Tile('rack', node_x, node_y)
def get_not_rack_nodes(self, node_x, node_y):
adjacent_tiles = self.get_adjacent_tiles(node_x, node_y)
@ -220,40 +146,29 @@ class Warehouse:
self.tiles[bottom_left.x][bottom_left.y]
]
return diagonals
def get_all_racks(self, all_storages=False):
def get_all_racks(self):
""":return list of Tile objects"""
racks = []
for x in self.tiles:
for x in self.tiles:
# row_racks = [t for t in self.tiles[x] if t.category.name == 'Rack']
for y in x:
if all_storages:
if y.category.name in self.storage_types:
racks.append(y)
elif y.category.name == 'Rack':
if y.category.name == 'Rack':
racks.append(y)
return racks
def place_packages(self, no_of_packages: int):
def place_packages(self, no_of_packages):
packages = []
for i in range(no_of_packages):
new_package_size = random.randrange(1, 10)
pack_x, pack_y = self._set_package_position(new_package_size)
pack_x, pack_y = self._set_package_position()
package_field = self.tiles[pack_x][pack_y]
new_package = Pack(lays_on_field=package_field)
new_package.size = new_package_size
new_package.id = i
new_package.x = pack_x
new_package.y = pack_y
if package_field.category.name in self.storage_types:
package_field.capacity -= new_package.size
self.tiles[pack_x][pack_y] = new_package
packages.append(new_package)
return packages
def _set_package_position(self, pack_size: int):
def _set_package_position(self):
starting_x, starting_y = random.randrange(self.width), random.randrange(self.height)
while not isinstance(self.tiles[starting_x][starting_y], Tile) \
or self.tiles[starting_x][starting_y].capacity - pack_size < 0:
while not isinstance(self.tiles[starting_x][starting_y], Tile):
starting_x, starting_y = random.randrange(self.width), random.randrange(
self.height)
return starting_x, starting_y
@ -289,17 +204,14 @@ class Warehouse:
return wall
class Tile:
def __init__(self, category, x_position, y_position, capacity=10, temperature: int=24, humidity: float=0.3):
def __init__(self, category, x_position, y_position):
self.category = CATEGORY.get(category, CATEGORY['floor'])
self.x_position = x_position
self.y_position = y_position
self.air_temperature = temperature
self.humidity = humidity
self.capacity = capacity
def __str__(self):
return "Tile type: {} on position ({},{})".format(self.category, self.x_position, self.y_position)
def __repr__(self):
return "Tile type: {} on position ({},{})".format(self.category, self.x_position, self.y_position)
return "Tile type: {} on position ({},{})".format(self.category, self.x_position, self.y_position)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB