Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
898d4687b4 | |||
b7402c8e49 | |||
b4eb9c22f7 | |||
91693d2b19 |
50
src/board.py
50
src/board.py
@ -7,6 +7,7 @@ import pygame
|
|||||||
import snn
|
import snn
|
||||||
import joblib
|
import joblib
|
||||||
import os
|
import os
|
||||||
|
import gen_algorithms
|
||||||
|
|
||||||
screen = []
|
screen = []
|
||||||
objectArray = []
|
objectArray = []
|
||||||
@ -176,6 +177,7 @@ def kb_listen(objectArray, gridLength, path):
|
|||||||
agent = objectArray[0]
|
agent = objectArray[0]
|
||||||
#agent.move(gridLength, path)
|
#agent.move(gridLength, path)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pygame.init() # inicjalizacja modułów, na razie niepotrzebna
|
pygame.init() # inicjalizacja modułów, na razie niepotrzebna
|
||||||
gridSize = 15
|
gridSize = 15
|
||||||
@ -203,12 +205,54 @@ if __name__ == '__main__':
|
|||||||
height = 530
|
height = 530
|
||||||
screen = pygame.display.set_mode((width, height)) # ustalanie rozmiarów okna
|
screen = pygame.display.set_mode((width, height)) # ustalanie rozmiarów okna
|
||||||
|
|
||||||
|
# od tad proboje
|
||||||
|
# parametry
|
||||||
|
num_of_houses = 8 # ilość domków
|
||||||
|
routes_num = 40 # ilość ścieżek, które będziemy generować
|
||||||
|
# rate = 0.3 # do mutacji, by liczby były ładniejsze
|
||||||
|
houses_coordinates = [[7, 4], [3, 10], [8, 10], [4, 5], [1, 2], [10, 4], [13, 14],
|
||||||
|
[6, 9]] # generowanie losowych współrzędnych między 1, a 9
|
||||||
|
names = np.array(['Dom A', 'Dom B', 'Dom C', 'Dom D', 'Dom E', 'Dom F', 'Dom G', 'Dom H']) # nazwy domów
|
||||||
|
houses_info = {x: y for x, y in
|
||||||
|
zip(names, houses_coordinates)} # zawiera nazwę domu i jego współrzędne X, Y - słownik
|
||||||
|
|
||||||
|
population_set = gen_algorithms.generate_routes(names, routes_num)
|
||||||
|
list_of_sums = gen_algorithms.sums_for_all_routes(population_set, houses_info)
|
||||||
|
progenitor_list = gen_algorithms.selection(population_set, list_of_sums)
|
||||||
|
new_population_set = gen_algorithms.population_mating(progenitor_list)
|
||||||
|
final_mutated_population = gen_algorithms.mutate_population(new_population_set)
|
||||||
|
final_route = [-1, np.inf, np.array([])] # format listy
|
||||||
|
for i in range(400):
|
||||||
|
list_of_sums = gen_algorithms.sums_for_all_routes(final_mutated_population, houses_info)
|
||||||
|
# zapisujemy najlepsze rozwiązanie
|
||||||
|
if list_of_sums.min() < final_route[1]:
|
||||||
|
final_route[0] = i
|
||||||
|
final_route[1] = list_of_sums.min()
|
||||||
|
final_route[2] = np.array(final_mutated_population)[list_of_sums.min() == list_of_sums]
|
||||||
|
|
||||||
|
progenitor_list = gen_algorithms.selection(population_set, list_of_sums)
|
||||||
|
new_population_set = gen_algorithms.population_mating(progenitor_list)
|
||||||
|
|
||||||
|
final_mutated_population = gen_algorithms.mutate_population(new_population_set)
|
||||||
|
print("Najlepsza ścieżka według algorytmu genetycznego: ")
|
||||||
|
print(final_route)
|
||||||
|
print(final_route[2][0][
|
||||||
|
0]) # żeby wyciągnąć z wyniku nazwę domu, który jest na i-tym miejscy trzeba wziąć final_route[2][0][i]
|
||||||
|
print(houses_info[final_route[2][0][0]][0]) # podstawiając jako argument nazwę domu z final_route dostajemy jego współrzędne x, y
|
||||||
|
|
||||||
|
houses_gen = [House(f'dom-{i}', pos) for i, pos in enumerate([Position(x, y) for x, y in [ # nasze współrzędne w odpowiedniej kolejności z genetycznego
|
||||||
|
(houses_info[final_route[2][0][0]][0], houses_info[final_route[2][0][0]][1]), (houses_info[final_route[2][0][1]][0], houses_info[final_route[2][0][1]][1]),
|
||||||
|
(houses_info[final_route[2][0][2]][0], houses_info[final_route[2][0][2]][1]), (houses_info[final_route[2][0][3]][0], houses_info[final_route[2][0][3]][1]),
|
||||||
|
(houses_info[final_route[2][0][4]][0], houses_info[final_route[2][0][4]][1]), (houses_info[final_route[2][0][5]][0], houses_info[final_route[2][0][5]][1]),
|
||||||
|
(houses_info[final_route[2][0][6]][0], houses_info[final_route[2][0][6]][1]), (houses_info[final_route[2][0][7]][0], houses_info[final_route[2][0][7]][1])
|
||||||
|
]])]
|
||||||
|
|
||||||
startPos = (0, 0)
|
startPos = (0, 0)
|
||||||
finalPos = (14, 14)
|
finalPos = (14, 14)
|
||||||
astarPath = astar.aStar(weightsMap, collisionsMap, startPos, finalPos)
|
astarPath = astar.aStar(weightsMap, collisionsMap, startPos, finalPos)
|
||||||
checkpoints = [startPos]
|
checkpoints = [startPos]
|
||||||
for house in houses:
|
for house in houses_gen:
|
||||||
checkpoints.append((house.pos.x, house.pos.y))
|
checkpoints.append((house.pos.x, house.pos.y)) #tutaj dodać pozycje z genetycznego???
|
||||||
checkpoints.append(finalPos)
|
checkpoints.append(finalPos)
|
||||||
astarPath = []
|
astarPath = []
|
||||||
for i in range(len(checkpoints) - 1):
|
for i in range(len(checkpoints) - 1):
|
||||||
@ -222,6 +266,8 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
pathPos = 0
|
pathPos = 0
|
||||||
nextCheckpoint = 1
|
nextCheckpoint = 1
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
agent_x, agent_y = astarPath[pathPos]
|
agent_x, agent_y = astarPath[pathPos]
|
||||||
checkpoint_x, checkpoint_y = checkpoints[nextCheckpoint]
|
checkpoint_x, checkpoint_y = checkpoints[nextCheckpoint]
|
||||||
|
122
src/gen_algorithms
Normal file
122
src/gen_algorithms
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import numpy as np
|
||||||
|
import random
|
||||||
|
|
||||||
|
# parametry
|
||||||
|
num_of_houses = 8 # ilość domków
|
||||||
|
routes_num = 40 # ilość ścieżek, które będziemy generować
|
||||||
|
# rate = 0.3 # do mutacji, by liczby były ładniejsze
|
||||||
|
houses_coordinates = [[x, y] for x, y in zip(np.random.randint(1, 9, num_of_houses), np.random.randint(1, 9,
|
||||||
|
num_of_houses))] # generowanie losowych współrzędnych między 1, a 9
|
||||||
|
names = np.array(['Dom A', 'Dom B', 'Dom C', 'Dom D', 'Dom E', 'Dom F', 'Dom G', 'Dom H']) # nazwy domów
|
||||||
|
houses_info = {x: y for x, y in zip(names, houses_coordinates)} # zawiera nazwę domu i jego współrzędne X, Y - słownik
|
||||||
|
print(houses_coordinates)
|
||||||
|
|
||||||
|
|
||||||
|
# dystans - to się wywali i użyje astara
|
||||||
|
def house_distance(a, b):
|
||||||
|
return ((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2) ** 0.5
|
||||||
|
|
||||||
|
|
||||||
|
def generate_routes(names,
|
||||||
|
routes_num): # tu się robią te zestawy domów - routes_num różnych opcji ułożenia trasy przez wszystkie domy
|
||||||
|
population_set = [] # tu zapisujemy trasy - losowe ułóżenia wszystkich domów na trasie śmieciarki - nasza populacja
|
||||||
|
for i in range(routes_num):
|
||||||
|
# losowo wygenerowane kolejności domów na trasie
|
||||||
|
single_route = names[np.random.choice(list(range(num_of_houses)), num_of_houses, replace=False)]
|
||||||
|
population_set.append(single_route)
|
||||||
|
return np.array(population_set)
|
||||||
|
|
||||||
|
|
||||||
|
def sum_up_for_route(names, houses_info): # liczymy odległości między kolejnymi miastami z listy i sumujemy
|
||||||
|
sum = 0
|
||||||
|
for i in range(num_of_houses - 1):
|
||||||
|
sum += house_distance(houses_info[names[i]],
|
||||||
|
houses_info[names[i + 1]]) # wywołana funkcja, która oblicza dystans - ma być astar
|
||||||
|
return sum
|
||||||
|
|
||||||
|
|
||||||
|
def sums_for_all_routes(population_set,
|
||||||
|
houses_info): # zapisujemy na liście finalne sumy odległości(astara) dla każdej z opcji tras
|
||||||
|
list_of_sums = np.zeros(routes_num)
|
||||||
|
|
||||||
|
for i in range(routes_num):
|
||||||
|
list_of_sums[i] = sum_up_for_route(population_set[i], houses_info) # wywołujemy dla każdej trasy na liście
|
||||||
|
|
||||||
|
return list_of_sums
|
||||||
|
|
||||||
|
|
||||||
|
def selection(population_set,
|
||||||
|
list_of_sums): # korzystamy z Roulette Wheel Selection tzn. im większy fitness tym większa szansa na zostanie wybranym
|
||||||
|
determinant = list_of_sums.sum()
|
||||||
|
probability = list_of_sums / determinant # nasza funkcja przynależności - dzielimy każdy dystans konkretnej ścieżki przez sumę wszystkich
|
||||||
|
|
||||||
|
progenitor_a = np.random.choice(list(range(len(population_set))), len(population_set), p=probability,
|
||||||
|
replace=True) # randomowa lista złożona z liczb między 0, a routes_num - 1
|
||||||
|
progenitor_b = np.random.choice(list(range(len(population_set))), len(population_set), p=probability,
|
||||||
|
replace=True) # gdzie p to prawdopodobieństwo każdego wejścia
|
||||||
|
|
||||||
|
progenitor_a = population_set[progenitor_a] # zmieniamy kolejność ułożenia tras
|
||||||
|
progenitor_b = population_set[progenitor_b] # teraz nie zawierają liczb, tylko podlisty z trasami
|
||||||
|
|
||||||
|
return np.array([progenitor_a, progenitor_b])
|
||||||
|
|
||||||
|
|
||||||
|
def mating_of_progenitors(progenitor_a, progenitor_b):
|
||||||
|
child = progenitor_a[0:5] # bierzemy 5 domów z rodzica
|
||||||
|
|
||||||
|
for house in progenitor_b:
|
||||||
|
if not house in child: # jeżeli jakiegoś domu z rodzica b nie ma w dziecku z a to łączymy
|
||||||
|
child = np.concatenate((child, [house]))
|
||||||
|
|
||||||
|
return child
|
||||||
|
|
||||||
|
|
||||||
|
def population_mating(progenitor_list):
|
||||||
|
new_population_set = []
|
||||||
|
for i in range(progenitor_list.shape[1]):
|
||||||
|
progenitor_a, progenitor_b = progenitor_list[0][i], progenitor_list[1][i]
|
||||||
|
child = mating_of_progenitors(progenitor_a, progenitor_b)
|
||||||
|
new_population_set.append(child)
|
||||||
|
|
||||||
|
return new_population_set
|
||||||
|
|
||||||
|
|
||||||
|
def mutation_of_child(child):
|
||||||
|
for i in range(num_of_houses): # dla każdego elementu dajemy losową szansę zamiany int *rate
|
||||||
|
x = np.random.randint(0, num_of_houses)
|
||||||
|
y = np.random.randint(0, num_of_houses)
|
||||||
|
|
||||||
|
child[x], child[y] = child[y], child[x] # zamiana miejscami
|
||||||
|
|
||||||
|
return child
|
||||||
|
|
||||||
|
|
||||||
|
def mutate_population(new_population_set):
|
||||||
|
final_mutated_population = []
|
||||||
|
for child in new_population_set:
|
||||||
|
final_mutated_population.append(mutation_of_child(child)) # dodajemy zmutowane dziecko do finalnej listy
|
||||||
|
return final_mutated_population
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
population_set = generate_routes(names, routes_num)
|
||||||
|
list_of_sums = sums_for_all_routes(population_set, houses_info)
|
||||||
|
progenitor_list = selection(population_set, list_of_sums)
|
||||||
|
new_population_set = population_mating(progenitor_list)
|
||||||
|
final_mutated_population = mutate_population(new_population_set)
|
||||||
|
final_route = [-1, np.inf, np.array([])] # format listy
|
||||||
|
for i in range(20):
|
||||||
|
list_of_sums = sums_for_all_routes(final_mutated_population, houses_info)
|
||||||
|
# zapisujemy najlepsze rozwiązanie
|
||||||
|
if list_of_sums.min() < final_route[1]:
|
||||||
|
final_route[0] = i
|
||||||
|
final_route[1] = list_of_sums.min()
|
||||||
|
final_route[2] = np.array(final_mutated_population)[list_of_sums.min() == list_of_sums]
|
||||||
|
|
||||||
|
progenitor_list = selection(population_set, list_of_sums)
|
||||||
|
new_population_set = population_mating(progenitor_list)
|
||||||
|
|
||||||
|
final_mutated_population = mutate_population(new_population_set)
|
||||||
|
print(final_route)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user