240 lines
6.8 KiB
Python
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 |