AI/genetyczny/funkcje.py

240 lines
6.8 KiB
Python

from Mapa.unboxOnTheFloor import UnboxOnTheFloor
from genetyczny.Gene import Gene
from Mapa.box import Box
from AStar import AStar
import random
import numpy
def generateGeny(data):
geny = []
zajeteRegaly = data.zajeteRegaly[:]
for r in zajeteRegaly:
g = Gene()
g.kordy = r
g.unbox1 = policzCost(data.astarMap,r,data.unbox[0])
if(len(data.unbox) > 1):
g.unbox2 = policzCost(data.astarMap,r,data.unbox[1])
geny.append(g)
return geny
def znajdzUnbox(data,mapa):
unboxy = []
iterator = 0
ostatniWiersz = len(mapa) -1
for x in mapa[ostatniWiersz]:
if (isinstance(x, UnboxOnTheFloor)):
unboxy.append((ostatniWiersz, iterator))
iterator += 1
data.unbox = unboxy
def policzCost(mapaBoxy, poczatek, koniec):
astar = AStar()
koszt = astar.search(poczatek, koniec, mapaBoxy, 1, 0)
return koszt
def genRandomChromosome(data):
chromosome = generateGeny(data)
random.shuffle(chromosome)
unboxLastGen = None
for gen in chromosome:
gen.unboxWczesniejszegoGenu = unboxLastGen
krotkaKosztJakiUnbox = wybierzUnbox(gen, data.jakLiczycKoszt)
unboxLastGen = krotkaKosztJakiUnbox[1]
gen.kordyUnboxa = data.unbox[krotkaKosztJakiUnbox[1]]
return chromosome
def genRandomPopulation(data, ileWPopulacji):
populacja = []
for i in range(ileWPopulacji):
populacja.append(genRandomChromosome(data))
return populacja
def fitness(chromosome, data):
koszt = 0
unboxPoprzedniegoGenu = None
for item, gen in enumerate(chromosome):
if(item == 0):
koszt += policzCost(data.astarMap, data.kordyWozka, gen.kordy)
krotkaKosztJakiUnbox = wybierzUnbox(gen, data.jakLiczycKoszt)
koszt += krotkaKosztJakiUnbox[0]
unboxPoprzedniegoGenu = krotkaKosztJakiUnbox[1]
else:
if unboxPoprzedniegoGenu == 0:
koszt += gen.unbox1
elif unboxPoprzedniegoGenu == 1:
koszt += gen.unbox2
krotkaKosztJakiUnbox = wybierzUnbox(gen, data.jakLiczycKoszt)
koszt += krotkaKosztJakiUnbox[0]
unboxPoprzedniegoGenu = krotkaKosztJakiUnbox[1]
return koszt
def wybierzUnbox(gen, jakLiczycKoszt): #funkcja ustawiajaca jaki unbox
if(jakLiczycKoszt == 0):
x = random.choice([gen.unbox1, gen.unbox2])
if(x == gen.unbox1):
y = 0
else:
y= 1
return (x,y)
elif(jakLiczycKoszt == 1):
return (gen.unbox1,0)
elif(jakLiczycKoszt == 2):
return (gen.unbox2,1)
elif(jakLiczycKoszt == 3):
x = min(gen.unbox1,gen.unbox2)
if(x == gen.unbox1):
y = 0
else:
y = 1
return (x,y)
def randomBox(mapa, regals, ile):
regals = regals
mapa = mapa
tupleList = []
ileRegalow = len(regals)
iteration = 0
while iteration < ileRegalow and iteration < ile:
regal = random.choice(regals)
if regal in tupleList:
continue
else:
tupleList.append(regal)
iteration+=1
for (i,j,x) in tupleList:
box = Box()
mapa[i][j].put(box)
"""
for t in tupleList:
listaRegalow.append((t[0],t[1]))
data.zajeteRegaly = listaRegalow
"""
return mapa
def znajdzBox(mapa, regals):
zajeteRegaly = []
for (x,y,z) in regals:
shelf = mapa[x][y]
tmp = shelf.occupied
if(tmp == True):
zajeteRegaly.append((x,y))
return zajeteRegaly
#wybiera z populacji dwa najlepsze chromosomy
def dwieNajlepsze(populacja, data):
tmpPopulacja = populacja[:]
chromFitness = []
for chrom in populacja:
chromFitness.append(fitness(chrom,data))
bestValue = min(chromFitness)
bestChromIndex = chromFitness.index(bestValue)
pierwsza = tmpPopulacja[bestChromIndex]
if (data.best == None):
data.best = (pierwsza[:],bestValue)
elif(data.best[1] > bestValue):
data.best = (pierwsza[:],bestValue)
data.doWykresu.append(bestValue)
tmpPopulacja.pop(bestChromIndex)
chromFitness.pop(bestChromIndex)
bestValue = min(chromFitness)
bestChromIndex = chromFitness.index(bestValue)
druga = tmpPopulacja[bestChromIndex]
tmpPopulacja.pop(bestChromIndex)
chromFitness.pop(bestChromIndex)
return (pierwsza, druga)
def genPopulacje(data,pierwszy, drugi, ileWPopulacji, fragmentLiczba, wspMutacji):
ileWChrom = len(pierwszy)
fragment = round(fragmentLiczba*ileWChrom)
if(fragment == 1):
fragment +=1
nowaPopulacja = []
for i in range(ileWPopulacji):
nowaPopulacja.append(crossover(data,pierwszy,drugi,fragment, wspMutacji))
return nowaPopulacja
def crossover(data,pierwszy, drugi, fragmentLiczba, wspMutacji):
ileWChrom = len(pierwszy)
tmp = random.randint(0, ileWChrom-fragmentLiczba)
kordyFragment = (tmp,tmp+fragmentLiczba)
nowyChrom = [Gene() for q in range(ileWChrom)]
iterator = kordyFragment[1]
pomIterator = kordyFragment[1]
usedKordy = []
for i in range(kordyFragment[0],kordyFragment[1]):
nowyChrom[i].kordy = pierwszy[i].kordy
nowyChrom[i].unbox1 = pierwszy[i].unbox1
nowyChrom[i].unbox2 = pierwszy[i].unbox2
usedKordy.append(pierwszy[i].kordy)
for x in range(ileWChrom):
if(iterator > ileWChrom - 1):
iterator = 0
if(pomIterator > ileWChrom - 1):
pomIterator = 0
if(nowyChrom[iterator].kordy == None and drugi[pomIterator].kordy not in usedKordy):
nowyChrom[iterator].kordy = drugi[pomIterator].kordy
nowyChrom[iterator].kordy = drugi[pomIterator].kordy
nowyChrom[iterator].unbox1 = drugi[pomIterator].unbox1
nowyChrom[iterator].unbox2 = drugi[pomIterator].unbox2
iterator += 1
pomIterator += 1
else:
pomIterator +=1
nowyChrom = mutate(wspMutacji, nowyChrom)
unboxLastGen = None
for gen in nowyChrom:
gen.unboxWczesniejszegoGenu = unboxLastGen
krotkaKosztJakiUnbox = wybierzUnbox(gen, data.jakLiczycKoszt)
unboxLastGen = krotkaKosztJakiUnbox[1]
gen.kordyUnboxa = data.unbox[krotkaKosztJakiUnbox[1]]
return nowyChrom
def updateMap(data, map, mapForAstar, regals):
data.mapa = map
znajdzUnbox(data, map)
data.zajeteRegaly = znajdzBox(map, regals)
data.astarMap = data.genMap(mapForAstar)
def mutate(wspMutacji, chrom): #w zaleznosci od tego jak wiele mutwac wybierz pary i zamien miejscami
ileWChrom = len(chrom)
ileZmian = round(ileWChrom * wspMutacji)
for i in range(ileZmian):
pom = None
pierw = random.randint(0,ileWChrom - 1)
drug = random.randint(0,ileWChrom - 1)
pom = chrom[pierw]
chrom[pierw] = chrom[drug]
chrom[drug] = pom
return chrom