2020-05-19 13:59:22 +02:00
|
|
|
from funkcje import *
|
|
|
|
from Gene import Gene
|
2020-05-18 12:53:51 +02:00
|
|
|
|
2020-05-19 13:59:22 +02:00
|
|
|
def start(data, wheel):
|
|
|
|
|
|
|
|
ileGeneracji = 20
|
|
|
|
ileWPopulacji = 16
|
|
|
|
fragment = 0.5
|
|
|
|
mutacja = 0.05
|
|
|
|
unbox = 3
|
|
|
|
|
|
|
|
data.kordyWozka = (wheel.ns, wheel.we)
|
|
|
|
data.jakLiczycKoszt = unbox
|
|
|
|
|
|
|
|
randomPopulation = genRandomPopulation(data, ileWPopulacji)
|
|
|
|
for i in range(ileGeneracji):
|
|
|
|
if i == 0:
|
|
|
|
best2 = dwieNajlepsze(randomPopulation, data)
|
|
|
|
else:
|
|
|
|
x = genPopulacje(data,best2[0], best2[1], ileWPopulacji, fragment, mutacja)
|
|
|
|
best2 = dwieNajlepsze(x, data)
|
|
|
|
del x
|
|
|
|
|
|
|
|
data.histZmian.append(data.best[1])
|
|
|
|
|
|
|
|
|
|
|
|
rysujWykres(data, ileGeneracji, 0, 2000)
|
2020-05-18 12:53:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def generateGeny(data):
|
2020-05-19 13:01:21 +02:00
|
|
|
geny = []
|
2020-05-18 12:53:51 +02:00
|
|
|
zajeteRegaly = data.zajeteRegaly[:]
|
|
|
|
for r in zajeteRegaly:
|
2020-05-19 13:01:21 +02:00
|
|
|
g = Gene()
|
|
|
|
g.kordy = r
|
2020-05-18 12:53:51 +02:00
|
|
|
g.unbox1 = policzCost(data.astarMap,r,data.unbox[0])
|
|
|
|
if(len(data.unbox) > 1):
|
|
|
|
g.unbox2 = policzCost(data.astarMap,r,data.unbox[1])
|
2020-05-19 13:01:21 +02:00
|
|
|
geny.append(g)
|
|
|
|
return geny
|
2020-05-17 15:23:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-18 12:53:51 +02:00
|
|
|
def genRandomChromosome(data):
|
2020-05-19 13:01:21 +02:00
|
|
|
chromosome = generateGeny(data)
|
2020-05-18 12:53:51 +02:00
|
|
|
random.shuffle(chromosome)
|
|
|
|
unboxLastGen = None
|
2020-05-17 15:23:06 +02:00
|
|
|
|
2020-05-18 12:53:51 +02:00
|
|
|
for gen in chromosome:
|
2020-05-19 13:01:21 +02:00
|
|
|
gen.unboxWczesniejszegoGenu = unboxLastGen
|
2020-05-18 12:53:51 +02:00
|
|
|
krotkaKosztJakiUnbox = wybierzUnbox(gen, data.jakLiczycKoszt)
|
|
|
|
unboxLastGen = krotkaKosztJakiUnbox[1]
|
2020-05-19 13:01:21 +02:00
|
|
|
gen.kordyUnboxa = data.unbox[krotkaKosztJakiUnbox[1]]
|
2020-05-17 15:23:06 +02:00
|
|
|
return chromosome
|
|
|
|
|
2020-05-18 12:53:51 +02:00
|
|
|
def genRandomPopulation(data, ileWPopulacji):
|
2020-05-17 15:23:06 +02:00
|
|
|
populacja = []
|
|
|
|
for i in range(ileWPopulacji):
|
2020-05-18 12:53:51 +02:00
|
|
|
populacja.append(genRandomChromosome(data))
|
2020-05-17 15:23:06 +02:00
|
|
|
return populacja
|
|
|
|
|
2020-05-18 12:53:51 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2020-05-17 15:23:06 +02:00
|
|
|
|
2020-05-18 12:53:51 +02:00
|
|
|
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)
|
2020-05-18 18:55:18 +02:00
|
|
|
data.doWykresu.append(bestValue)
|
2020-05-18 12:53:51 +02:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2020-05-19 13:01:21 +02:00
|
|
|
def crossover(data,pierwszy, drugi, fragmentLiczba, wspMutacji):
|
2020-05-18 12:53:51 +02:00
|
|
|
ileWChrom = len(pierwszy)
|
|
|
|
tmp = random.randint(0, ileWChrom-fragmentLiczba)
|
|
|
|
kordyFragment = (tmp,tmp+fragmentLiczba)
|
2020-05-19 13:01:21 +02:00
|
|
|
nowyChrom = [Gene() for q in range(ileWChrom)]
|
2020-05-18 12:53:51 +02:00
|
|
|
iterator = kordyFragment[1]
|
|
|
|
pomIterator = kordyFragment[1]
|
2020-05-19 13:01:21 +02:00
|
|
|
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):
|
2020-05-18 12:53:51 +02:00
|
|
|
if(iterator > ileWChrom - 1):
|
|
|
|
iterator = 0
|
|
|
|
if(pomIterator > ileWChrom - 1):
|
|
|
|
pomIterator = 0
|
2020-05-19 13:01:21 +02:00
|
|
|
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
|
2020-05-18 12:53:51 +02:00
|
|
|
iterator += 1
|
|
|
|
pomIterator += 1
|
2020-05-19 13:01:21 +02:00
|
|
|
else:
|
2020-05-18 12:53:51 +02:00
|
|
|
pomIterator +=1
|
2020-05-19 13:01:21 +02:00
|
|
|
|
2020-05-18 12:53:51 +02:00
|
|
|
nowyChrom = mutate(wspMutacji, nowyChrom)
|
2020-05-19 13:01:21 +02:00
|
|
|
unboxLastGen = None
|
|
|
|
|
2020-05-19 19:26:12 +02:00
|
|
|
|
|
|
|
|
2020-05-19 13:01:21 +02:00
|
|
|
for gen in nowyChrom:
|
|
|
|
gen.unboxWczesniejszegoGenu = unboxLastGen
|
|
|
|
krotkaKosztJakiUnbox = wybierzUnbox(gen, data.jakLiczycKoszt)
|
|
|
|
unboxLastGen = krotkaKosztJakiUnbox[1]
|
|
|
|
gen.kordyUnboxa = data.unbox[krotkaKosztJakiUnbox[1]]
|
|
|
|
|
2020-05-18 12:53:51 +02:00
|
|
|
return nowyChrom
|
|
|
|
|
|
|
|
|
2020-05-19 13:59:22 +02:00
|
|
|
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))
|
|
|
|
|
2020-05-19 19:26:12 +02:00
|
|
|
return nowaPopulacja
|
|
|
|
|
|
|
|
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
|