This commit is contained in:
weltschmerz 2020-06-29 10:52:52 +02:00
parent 990fba3293
commit 267dc61621
7 changed files with 309 additions and 0 deletions

55
DNA.py Normal file
View File

@ -0,0 +1,55 @@
import random
import string
from astar import Astar
from random import shuffle
import numpy as np
A = np.zeros((10, 10), dtype=int)
goals = [[0, 4], [4, 0], [4, 4]]
recordDistance = 0
class DNA:
def __init__(self, target, recordDistance):
shuffle(target)
self.genes = target.copy()
self.fitness = 1.0
self.recordDistance = recordDistance
def calcFitness(self, A):
start = [0, 0]
sum = 1
for goal in self.genes:
path = Astar(A, start, goal)
sum = sum + len(path) - 1
start = goal
self.fitness = sum
def crossover(self, partner):
child = DNA(self.genes, self.recordDistance)
start = abs(random.randint(0, len(self.genes)) - 1)
end = abs(random.randint(start - 1, len(self.genes)))
child.genes = child.genes[start:end]
for i in range(len(self.genes)):
node = partner.genes[i]
if node not in child.genes:
child.genes.append(node)
return child
def mutate(self, mutationRate):
for i in range(len(self.genes)):
if random.random() < mutationRate:
indexA = abs(random.randint(0, len(self.genes)) - 1)
indexB = (indexA + 1) % len(self.genes)
self.genes[indexA], self.genes[indexB] = self.genes[indexB], self.genes[indexA]

BIN
GarbageTruck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
Home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

87
astar.py Normal file
View File

@ -0,0 +1,87 @@
import numpy as np
class node:
def __init__(self, x, y):
self.x = x
self.y = y
self.neighbours = []
self.parent = None
self.g = 0
self.f = 0
self.h = 0
def makeNeighbours(self, matrix):
if self.x - 1 >= 0 and matrix[self.x - 1, self.y] != 3:
self.neighbours.append([self.x - 1, self.y])
if self.x + 1 < matrix.shape[0] and matrix[self.x + 1, self.y] != 3:
self.neighbours.append([self.x + 1, self.y])
if self.y + 1 < matrix.shape[1] and matrix[self.x, self.y + 1] != 3:
self.neighbours.append([self.x, self.y + 1])
if self.y - 1 >= 0 and matrix[self.x, self.y - 1] != 3:
self.neighbours.append([self.x, self.y - 1])
def calcHeuristic(self, goal):
self.h = abs(self.x - goal.x) + abs(self.y - goal.y)
def Astar(A, start, goal):
frontier = []
objects = {}
for i in range(A.shape[0]):
for j in range(A.shape[1]):
objects[i, j] = node(i, j)
objects[0, 0].visited = True
goal = objects[goal[0], goal[1]]
start = objects[start[0], start[1]]
frontier.append(start)
open = []
closed = []
open.append(start)
while open:
open.sort(key=lambda o: o.f)
current = open.pop(0)
closed.append(current)
current.makeNeighbours(A)
if current == goal:
break
for next in current.neighbours:
if objects[next[0], next[1]] in closed:
continue
if objects[next[0], next[1]] in open:
new_g = current.g + 1
if objects[next[0], next[1]].g > new_g:
objects[next[0], next[1]].g = new_g
objects[next[0], next[1]].parent = objects[current.x, current.y]
else:
objects[next[0], next[1]].g = objects[current.x, current.y].g + 1
objects[next[0], next[1]].calcHeuristic(goal)
objects[next[0], next[1]].parent = objects[current.x, current.y]
open.append(objects[next[0], next[1]])
path = []
while current.parent:
path.append([current.x, current.y])
current = current.parent
path.append([start.x, start.y])
path.reverse()
return path

52
genetic.py Normal file
View File

@ -0,0 +1,52 @@
from astar import Astar
import numpy as np
from DNA import DNA
import random
import copy
def genetic(goals, A):
recordDistance = 1000000000
#count = 0
generation = 0
totalPopulaton = 10
population = []
matingPool = []
mutationRate = 0.01
for i in range(totalPopulaton):
population.append(DNA(goals, recordDistance))
for j in range(totalPopulaton):
matingPool.clear()
generation = generation + 1
for i in range(totalPopulaton):
population[i].calcFitness(A)
if population[i].fitness < recordDistance:
recordDistance = population[i].fitness
best = copy.deepcopy(population[i])
bestGeneration = generation
for i in range(totalPopulaton):
n = population[i].fitness * 100
for j in range(int(n)):
matingPool.append(population[i])
for i in range(totalPopulaton):
if matingPool:
a = random.randint(0, len(matingPool) - 1)
b = random.randint(0, len(matingPool) - 1)
partnerA = matingPool[a]
partnerB = matingPool[b]
child = partnerA.crossover(partnerB)
child.mutate(mutationRate)
population[i] = child
return best

115
main.py Normal file
View File

@ -0,0 +1,115 @@
import pygame
from pygame.locals import *
from astar import Astar
from genetic import genetic
import numpy as np
import time
def drawGrid(w, rows, surface, goals):
sizeBtwn = w // rows
x = 0
y = 0
for l in range(rows):
x = x + sizeBtwn
y = y + sizeBtwn
pygame.draw.line(surface, (255, 0, 255), (x, 0), (x, width))
pygame.draw.line(surface, (255, 0, 255), (0, y), (width, y))
def drawHouses(houses):
for house in houses:
screen.blit(home, (13 + house[1] * 60, 15 + house[0] * 60))
def drawObstacles(obs):
for ob in obs:
screen.blit(xobstacle, (13 + ob[1] * 60, 15 + ob[0] * 60))
def findObstacles(A):
obstacles = []
for i in range(10):
for j in range(10):
if A[i][j] == 3:
obstacles.append([i, j])
return obstacles
pygame.init()
width = 600
height = 600
FPS = 60
running = True
fpsClock = pygame.time.Clock()
screen = pygame.display.set_mode((height, height), 0, 32)
pygame.display.set_caption('InteligentnaSmieciarka2000')
truck = pygame.image.load('GarbageTruck.png')
home = pygame.image.load('Home.png')
xobstacle = pygame.image.load("x.png")
w = 10
rows = 10
A = np.zeros((w, rows), dtype=int)
A[1, 0] = 3
A[0, 2] = 3
A[4, 1] = 3
rows = 10
x = 15
y = 20
sizeBtwn = width // rows
parent = [0, 0]
goals = [[0, 4], [4, 0], [4, 4], [6, 7]]
houses = goals.copy()
goals = genetic(goals, A).genes
start = [0, 0]
obsta = findObstacles(A)
while goals:
goal = goals.pop(0)
path = Astar(A, start, goal)
start = goal
while path:
screen.fill((0, 0, 0))
drawGrid(width, rows, screen, goals)
drawHouses(houses)
drawObstacles(obsta)
pygame.event.get()
if path:
destination = path.pop(0)
temp = destination
destination = [destination[0] - parent[0], destination[1] - parent[1]]
if destination[0] == 1:
y += 60
time.sleep(0.3)
elif destination[0] == -1:
y -= 60
time.sleep(0.3)
elif destination[1] == 1:
x += 60
time.sleep(0.3)
elif destination[1] == -1:
x -= 60
time.sleep(0.3)
parent = temp
screen.blit(truck, (x, y))
pygame.display.update()
#screen.blit(truck, (x, y))
#pygame.display.update()
time.sleep(5)

BIN
x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B