Merge branch 'master' into genetic_algorithm

This commit is contained in:
Kacper Kalinowski 2022-06-10 11:20:51 +02:00
commit 03f983f35b
9 changed files with 270 additions and 88 deletions

View File

View File

@ -1,3 +1,96 @@
<<<<<<< HEAD
|--- feature_2 <= 3.50
| |--- feature_4 <= 3.50
| | |--- feature_0 <= 1.50
| | | |--- class: 0
| | |--- feature_0 > 1.50
| | | |--- feature_3 <= 3.50
| | | | |--- feature_4 <= 2.50
| | | | | |--- class: 1
| | | | |--- feature_4 > 2.50
| | | | | |--- feature_2 <= 2.50
| | | | | | |--- class: 1
| | | | | |--- feature_2 > 2.50
| | | | | | |--- class: 0
| | | |--- feature_3 > 3.50
| | | | |--- feature_3 <= 4.50
| | | | | |--- feature_1 <= 2.50
| | | | | | |--- feature_0 <= 2.50
| | | | | | | |--- feature_1 <= 1.50
| | | | | | | | |--- feature_4 <= 2.50
| | | | | | | | | |--- class: 1
| | | | | | | | |--- feature_4 > 2.50
| | | | | | | | | |--- feature_2 <= 2.00
| | | | | | | | | | |--- class: 1
| | | | | | | | | |--- feature_2 > 2.00
| | | | | | | | | | |--- class: 0
| | | | | | | |--- feature_1 > 1.50
| | | | | | | | |--- class: 0
| | | | | | |--- feature_0 > 2.50
| | | | | | | |--- feature_2 <= 2.50
| | | | | | | | |--- class: 1
| | | | | | | |--- feature_2 > 2.50
| | | | | | | | |--- feature_4 <= 2.50
| | | | | | | | | |--- class: 1
| | | | | | | | |--- feature_4 > 2.50
| | | | | | | | | |--- class: 0
| | | | | |--- feature_1 > 2.50
| | | | | | |--- feature_1 <= 3.50
| | | | | | | |--- feature_0 <= 3.50
| | | | | | | | |--- class: 0
| | | | | | | |--- feature_0 > 3.50
| | | | | | | | |--- feature_4 <= 2.50
| | | | | | | | | |--- class: 1
| | | | | | | | |--- feature_4 > 2.50
| | | | | | | | | |--- feature_2 <= 2.00
| | | | | | | | | | |--- class: 1
| | | | | | | | | |--- feature_2 > 2.00
| | | | | | | | | | |--- class: 0
| | | | | | |--- feature_1 > 3.50
| | | | | | | |--- class: 0
| | | | |--- feature_3 > 4.50
| | | | | |--- class: 0
| |--- feature_4 > 3.50
| | |--- feature_2 <= 1.50
| | | |--- feature_4 <= 4.50
| | | | |--- feature_3 <= 3.50
| | | | | |--- feature_0 <= 1.50
| | | | | | |--- class: 0
| | | | | |--- feature_0 > 1.50
| | | | | | |--- class: 1
| | | | |--- feature_3 > 3.50
| | | | | |--- feature_1 <= 2.50
| | | | | | |--- feature_0 <= 2.50
| | | | | | | |--- class: 0
| | | | | | |--- feature_0 > 2.50
| | | | | | | |--- feature_3 <= 4.50
| | | | | | | | |--- class: 1
| | | | | | | |--- feature_3 > 4.50
| | | | | | | | |--- class: 0
| | | | | |--- feature_1 > 2.50
| | | | | | |--- class: 0
| | | |--- feature_4 > 4.50
| | | | |--- class: 0
| | |--- feature_2 > 1.50
| | | |--- class: 0
|--- feature_2 > 3.50
| |--- feature_1 <= 1.50
| | |--- feature_4 <= 1.50
| | | |--- feature_2 <= 4.50
| | | | |--- feature_0 <= 1.50
| | | | | |--- class: 0
| | | | |--- feature_0 > 1.50
| | | | | |--- feature_3 <= 4.50
| | | | | | |--- class: 1
| | | | | |--- feature_3 > 4.50
| | | | | | |--- class: 0
| | | |--- feature_2 > 4.50
| | | | |--- class: 0
| | |--- feature_4 > 1.50
| | | |--- class: 0
| |--- feature_1 > 1.50
| | |--- class: 0
=======
|--- feature_2 <= 3.50
| |--- feature_4 <= 3.50
| | |--- feature_0 <= 1.50
@ -89,3 +182,4 @@
| | | |--- class: 0
| |--- feature_1 > 1.50
| | |--- class: 0
>>>>>>> genetic_algorithm

Binary file not shown.

Binary file not shown.

10
main_test.py Normal file
View File

@ -0,0 +1,10 @@
from map import map_utils
from path_search_algorthms import a_star, a_star_utils
import numpy
file = open('last_map.nparr', 'rb')
array = numpy.load(file)
file.close
actions = a_star.search_path(12, 0, a_star_utils.Rotation.UP, 1, 5, array)
print(actions)

71
neurone/main.py Normal file
View File

@ -0,0 +1,71 @@
import pybrain3
import pickle
import matplotlib.pylab as plt
from numpy import ravel
from pybrain3.tools.shortcuts import buildNetwork
from pybrain3.datasets import SupervisedDataSet
from pybrain3.supervised.trainers import BackpropTrainer
from pybrain3.tools.xml.networkwriter import NetworkWriter
from pybrain3.tools.xml.networkreader import NetworkReader
# https://www.machinelearningmastery.ru/how-to-configure-the-number-of-layers-and-nodes-in-a-neural-network/
class SupervisedDataSetModel():
def __init__(self, metrics:int = 4,
predictions:int = 1,
input_layer:int = 4,
hidden_layer:int = 3,
output_layer:int = 1):
# 4 метрики, 1 предикшн
self.metrics = metrics
self.predictions = predictions
self.input_layer = input_layer
self.hidden_layer = hidden_layer
self.output_layer = output_layer
self.ds = SupervisedDataSet(metrics, predictions)
def activateModel(self):
self.net = buildNetwork(self.input_layer, self.hidden_layer, self.output_layer, bias=True)
self.trainer = BackpropTrainer(self.net, dataset=self.ds, momentum=0.1, learningrate=0.01, verbose=True, weightdecay=0.01)
self.trnerr, self.valerr = self.trainer.trainUntilConvergence()
plt.plot(self.trnerr, 'b', self.valerr, 'r')
plt.show()
def addDataToModel(self, input:list, target:list):
self.ds.addSample(inp=input, target=target)
def predict(self, data:list):
y = self.net.activate(data)
print(y)
return y
def saveModel(self):
fileObject = open('model.txt', 'wb')
pickle.dump(self.net, fileObject)
fileObject.close()
def getModel():
fileObject = open('model.txt', 'rb')
net2 = pickle.load(fileObject)
fileObject.close()
return net2
model = SupervisedDataSetModel()
# model.addDataToModel([2, 3, 80, 1], [5])
# model.addDataToModel([5, 5, 50, 2], [4])
# model.addDataToModel([10, 7, 40, 3], [3])
# model.addDataToModel([15, 9, 20, 4], [2])
# model.addDataToModel([20, 11, 10, 5], [1])
# model.activateModel()
# model.saveModel()
# USE MODEL - >
model = getModel()
print(model.activate([2, 3, 80, 1]))

BIN
neurone/model.txt Normal file

Binary file not shown.

View File

@ -1,76 +1,76 @@
from data_structures.heap import Heap
from path_search_algorthms import a_star_utils as utils
def get_cost(start_x: int, start_y: int, target_x: int, target_y: int, array):
actions = search_path(start_x, start_y, utils.Rotation.NONE, target_x, target_y, array)
if actions is None:
return 1
return len(actions)
def search_path(start_x: int, start_y: int, agent_rotation: utils.Rotation, target_x: int, target_y: int, array):
start_node = utils.Node(start_x, start_y, agent_rotation)
target_node = utils.Node(target_x, target_y, utils.Rotation.NONE)
# heap version
# nodes for check
search_list = Heap()
search_list.append(start_node, 0)
# checked nodes
searched_list: list[(int, int)] = []
while (search_list.length() > 0):
node: utils.Node = search_list.take_first()
searched_list.append((node.x, node.y))
# check for target node
if ((node.x, node.y) == (target_x, target_y)):
return trace_path(node)
# neightbours processing
neighbours = utils.get_neighbours(node, searched_list, array)
for neighbour in neighbours:
# calculate new g cost for neightbour (start -> node -> neightbour)
new_neighbour_cost = node.g_cost + utils.get_neighbour_cost(node, neighbour)
if (new_neighbour_cost < neighbour.g_cost or not search_list.contains(neighbour)):
# replace cost and set parent node
neighbour.g_cost = new_neighbour_cost
neighbour.h_cost = utils.get_h_cost(neighbour, target_node)
neighbour.parent = node
# add to search
if (not search_list.contains(neighbour)):
search_list.append(neighbour, neighbour.f_cost())
def trace_path(end_node: utils.Node):
path = []
node = end_node
# set final rotation of end_node because we don't do it before
node.rotation = utils.get_needed_rotation(node.parent, node)
while (node.parent != False):
if (node.parent == utils.Rotation.NONE):
path += "forward"
else:
path += utils.get_move(node.parent, node)
node = node.parent
# delete move on initial tile
path.pop()
# we found path from end, so we need to reverse it (get_move reverse move words)
path.reverse()
# last forward to destination
path.append("forward")
return path
from data_structures.heap import Heap
from path_search_algorthms import a_star_utils as utils
def get_cost(start_x: int, start_y: int, target_x: int, target_y: int, array):
actions = search_path(start_x, start_y, utils.Rotation.NONE, target_x, target_y, array)
if actions is None:
return 1
return len(actions)
def search_path(start_x: int, start_y: int, agent_rotation: utils.Rotation, target_x: int, target_y: int, array):
start_node = utils.Node(start_x, start_y, agent_rotation)
target_node = utils.Node(target_x, target_y, utils.Rotation.NONE)
# heap version
# nodes for check
search_list = Heap()
search_list.append(start_node, 0)
# checked nodes
searched_list: list[(int, int)] = []
while (search_list.length() > 0):
node: utils.Node = search_list.take_first()
searched_list.append((node.x, node.y))
# check for target node
if ((node.x, node.y) == (target_x, target_y)):
return trace_path(node)
# neightbours processing
neighbours = utils.get_neighbours(node, searched_list, array)
for neighbour in neighbours:
# calculate new g cost for neightbour (start -> node -> neightbour)
new_neighbour_cost = node.g_cost + utils.get_neighbour_cost(node, neighbour)
if (new_neighbour_cost < neighbour.g_cost or not search_list.contains(neighbour)):
# replace cost and set parent node
neighbour.g_cost = new_neighbour_cost
neighbour.h_cost = utils.get_h_cost(neighbour, target_node)
neighbour.parent = node
# add to search
if (not search_list.contains(neighbour)):
search_list.append(neighbour, neighbour.f_cost())
def trace_path(end_node: utils.Node):
path = []
node = end_node
# set final rotation of end_node because we don't do it before
node.rotation = utils.get_needed_rotation(node.parent, node)
while (node.parent != False):
if (node.parent == utils.Rotation.NONE):
path += "forward"
else:
path += utils.get_move(node.parent, node)
node = node.parent
# delete move on initial tile
path.pop()
# we found path from end, so we need to reverse it (get_move reverse move words)
path.reverse()
# last forward to destination
path.append("forward")
return path

View File

@ -3,6 +3,7 @@ from enum import Enum
from map import map_utils
from settings import *
class Rotation(Enum):
UP = 0
RIGHT = 1
@ -13,34 +14,37 @@ class Rotation(Enum):
def __int__(self):
return self.value
class Node:
def __init__(self, x: int, y: int, rotation: Rotation):
self.x = x
self.y = y
self.g_cost = 0
self.h_cost = 0
self.parent = 0
self.rotation = rotation
self.parent: Node | bool = False
self.rotation: Rotation = rotation
def f_cost(self):
return self.g_cost + self.h_cost
def get_neighbours(node, searched_list, array):
neighbours = []
for offset_x in range (-1, 2):
for offset_y in range (-1, 2):
for offset_x in range(-1, 2):
for offset_y in range(-1, 2):
# don't look for cross neighbours
if(abs(offset_x) + abs(offset_y) == 1):
if (abs(offset_x) + abs(offset_y) == 1):
x = node.x + offset_x
y = node.y + offset_y
# prevent out of map coords
if (x >= 0 and x < MAP_WIDTH and y >= 0 and y < MAP_HEIGHT):
if(map_utils.isRoadTile(array[y][x]) and (x, y) not in searched_list):
if (map_utils.isRoadTile(array[y][x]) and (x, y) not in searched_list):
neighbour = Node(x, y, Rotation.NONE)
neighbour.rotation = get_needed_rotation(node, neighbour)
neighbours.append(neighbour)
return neighbours
# move cost schema:
# - move from tile to tile: 10
# - add extra 10 (1 rotation) if it exists
@ -49,11 +53,12 @@ def get_h_cost(start_node: Node, target_node: Node):
distance_y = abs(start_node.y - target_node.y)
cost = (distance_x + distance_y) * 10
if(distance_x > 0 and distance_y > 0):
if (distance_x > 0 and distance_y > 0):
cost += 10
return cost
# move cost schema:
# - move from tile to tile: 10
# - every rotation 90*: 10
@ -67,6 +72,7 @@ def get_neighbour_cost(start_node: Node, target_node: Node) -> int:
else:
return 30
# translate rotation change to move
def get_move(start_node: Node, target_node: Node):
rotate_change = get_rotate_change(start_node.rotation, target_node.rotation)
@ -79,10 +85,12 @@ def get_move(start_node: Node, target_node: Node):
else:
return ["left", "forward"]
# simple calc func
def get_rotate_change(rotationA: Rotation, rotationB: Rotation) -> int:
return int(rotationA) - int(rotationB)
# get new rotation for target_node as neighbour of start_node
def get_needed_rotation(start_node: Node or bool, target_node: Node) -> Rotation:
if(start_node == False):
@ -94,10 +102,9 @@ def get_needed_rotation(start_node: Node or bool, target_node: Node) -> Rotation
if (start_node.y - target_node.y > 0):
return Rotation.UP
if (start_node.y - target_node.y < 0):
return Rotation.DOWN
return Rotation.DOWN