From 267dc616218829172af619071a555e2766c3f118 Mon Sep 17 00:00:00 2001 From: weltschmerz Date: Mon, 29 Jun 2020 10:52:52 +0200 Subject: [PATCH] xx --- DNA.py | 55 +++++++++++++++++++++++ GarbageTruck.png | Bin 0 -> 1064 bytes Home.png | Bin 0 -> 1537 bytes astar.py | 87 +++++++++++++++++++++++++++++++++++ genetic.py | 52 +++++++++++++++++++++ main.py | 115 +++++++++++++++++++++++++++++++++++++++++++++++ x.png | Bin 0 -> 661 bytes 7 files changed, 309 insertions(+) create mode 100644 DNA.py create mode 100644 GarbageTruck.png create mode 100644 Home.png create mode 100644 astar.py create mode 100644 genetic.py create mode 100644 main.py create mode 100644 x.png diff --git a/DNA.py b/DNA.py new file mode 100644 index 0000000..36c69d6 --- /dev/null +++ b/DNA.py @@ -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] + diff --git a/GarbageTruck.png b/GarbageTruck.png new file mode 100644 index 0000000000000000000000000000000000000000..5d44e1d634d74a9b3e53adc669d23d00054fd43d GIT binary patch literal 1064 zcmV+@1lRkCP)bIx8q(3aYEro7WH**V#J|7+zx zYp=awh8bqK(@_ASQ0P36H=X!4sB3I&e0w_4c$_2OrRfCOc?Q9!Js1uc=(K73VJMvx z5%~u|>h4*fZR=%?@{Vm9h#@*6idM(3;lpY>nsElwvS_`B{Bjr8kWjG1g~O$2J(J8B zV{2;_iX95!ys`SySMqwyP+DdY)9d8GoRtrq_CfdqrZu3Tr`clgUtzG%Cis+xWJF`Q zK&LXri4#!(9FmtJf2#6TqxpVQp>VCe^bI-7hw2F|BV7)sTT!`n4*oT6F4rb#J2%X^ zk7M{B&mvIiNf$N=HDRtX@(-)3PW#5)>j2Uk@Xj-E=O{#jC-5KKxtHD2PAlo4_Z5m`hg z17bsSO_IgWXOn%GfwmRe79!U)S5KwC2@~0--q+^|9`15t=57b!0a2h%lSxFyB+ z@7?OQzE+E5M5ooOkt5YZ4lPIwL6pOG&U1$I$BO_EEJh8i%1SXPw{fTmz%})j0ty^< z;hxojqM!E~^940~Y|kN`3)jbDa|*46qigXa1s%|H)4+3{TO|!!LQhKYxedG{Eh<3Q zun^bacPm`!y_Q-yI!7mcHgpeb%q&%W`S9$42VRVHdgkh40ArTj&BR-9V!)<0FNkOD z2C5@oT89JyKJBq+3O<5e`7B$nL%%hB2cC)89PpZWp4rIz$viF(N?z0c+{BG`*Y7vl zT}{dI{@IKgP{=oZHfLJqmn7f)WUnOhi#c`d$l$(StN)jnzF7X`+JTL4zC&Kc!+f@P zPyg4wb~|w5)==M#AA`0!c{VFQ_0i{F*ztJR9dlRbM=LzM~+H)ASk`Pz1F>fvTol3UsYXgZNsjeJLR$ED0Z+Y8R;c5gJ_C?rkkC iEzwLdGt4lV;2QPRAN;G zRD4ug0qd(JEvZTWu(fGYwI)ift=1S{6*jzth25QgcV<>$cTjvz@^S9HvvbdH&N*}M zMTaN5`m6Tl<4&M^0_X4Qfl4PER3uIH^91;$2e79M@cWjXJ%FtZSjgs=&jTPX2-tK8 z@Qz@on7T@BWgwaW6Pp{JCBWK2K;mIO7siecb%pvFN)c=Xq}xCNoAHn{^Yj3iZfqaU zFjw-K7uoTpyw#hxs9z{6l}r5td_`lVY)=D#=|b8{3{{g)G0Ku z^}85TAx;A)Xr@v1PXfSnD z9U^o}nFxprj{-1KI9~v~EUHPbI)}l49w{jZUcDM#zP_CvaJIFfE-w!)Sy_-;TT#og zb|}TL8Mq@cg;47Cp#bAJcx)xmcMg=0tC&O1D&@wv@XfvfOY?VSXZoo zR9`Qrf{yV6mCVc#XqHIng8(M+ZNE+e{NGo@E*IQ@ff!i28-Wui%K3lLC9w_~s;hC` zXoTa&4H-bZ#IMwHz}_SqIXfNzQyJ!iY4rQ1`qnbQh!Gf4R)$`qMm^MdM~LRLXK{Jv zOxS8_2!J3_QxyM{jr(RlKt z{4xWm-ym-sH)w`Zt*%)=9SoG_vC$LCH{NghbcB_Zz?ZpyROcNb+E@$cqoZ-VvQm!f zD^RMDYeo!Bkxun@E{>J|wi*&CG7=x|-3K3oU#AIe<>jc4iIJn@l2~tBsTNiJcI-ev zR8*(u+FNZnHg7I;6%{hXWu+c2(u4_r;dFD3n~9t&k(duG79=MndAzw)R0OGF3B2Nz z>b^Iw+NLd>BeD=Z7ccgR#M*V)s7g(dUt3(la;*p#9=xdIW9e5cr(7)@W=ocLa#EsL z@;m_S-!FlmSv%yltYDw_3gPbt02LrDHO0XN###_wvYMBU>S_&dhbz0T6JJVt@CM6_#tP*xEwRexl zA~-=C;A#$wc=C4i;Zofh0Ladf0ZJi%iT5vU0JGVcr~%MUfQF+>(LY`r;8H$6-6`7; ztO<~V^t5gQWMrC+2?-{T+ifMqupVB9mp*fwU+)dOt`{!mH=xf)ThTY#4S)nWIl0J4 zPwO5)dPb(vWHNc&Xx&+YJBOCz)unEc;dj_r$IpvLrI2Y~;Dv?J9?#}-_sq;l?;b#E zdWLZgcRcqZY}vIFw<_Wg?jB)=*lA~FbNYUfThM>OLXQaKt~#_kh@;v4qbq=1KDuU2{3_^|E`yhsSErkI4;(=Ap+rph zSR0_~8}6jjvN34ZtWM)jrxW&V+ps=A4|{?2Q2u|=1US#7YUH?}AV`6M@*3@udaP{{ppF@XchrgVqrFsEM#^a1|&##~m{(124`D`qQa!?3OZuB7uEI1I{}z@XY5 z9r^~hdjdiny;|I?`Zy0>-e8%l0gYfKzcYn6j( nL{|V}qZ)>1dtIU$T%G>`=UVh&-5N%v00000NkvXXu0mjf0xi;~ literal 0 HcmV?d00001 diff --git a/astar.py b/astar.py new file mode 100644 index 0000000..2f7d23c --- /dev/null +++ b/astar.py @@ -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 \ No newline at end of file diff --git a/genetic.py b/genetic.py new file mode 100644 index 0000000..f7cc056 --- /dev/null +++ b/genetic.py @@ -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 diff --git a/main.py b/main.py new file mode 100644 index 0000000..a4d7647 --- /dev/null +++ b/main.py @@ -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) \ No newline at end of file diff --git a/x.png b/x.png new file mode 100644 index 0000000000000000000000000000000000000000..d3ac62b7c2147063f4b060d10890384a34a03b7e GIT binary patch literal 661 zcmV;G0&4wb0&BTuB6~ZzPe9E)uVJpU4R) z-*?C+ElkbFd+)5khEkzW2h zUrgeKZd%)Ko7@ouIu=TO0yKNJL`>zC4i4ZYy@BDx94WCr@BU#j`?Axg*>Z`0^EfR; vJq;S__^5623NlUNg>HQKyd59DC``;>u``Q6b3v4Z00000NkvXXu0mjf6w)Cp literal 0 HcmV?d00001