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