Genetics
This commit is contained in:
parent
a254e6658a
commit
8c5c5c48f0
123
genetic.py
Normal file
123
genetic.py
Normal file
@ -0,0 +1,123 @@
|
||||
import random
|
||||
|
||||
|
||||
class genetic:
|
||||
def __init__(self, chrome):
|
||||
self.chrome = chrome
|
||||
self.key = 10
|
||||
self.pop_size = 50
|
||||
self.gen_max = 20
|
||||
self.length = len(chrome) - 1
|
||||
self.div = self.length // 2
|
||||
self.rand = list(range(1, self.length + 1))
|
||||
|
||||
def create_genome(self):
|
||||
genome = "0"
|
||||
exclusive = random.sample(self.rand, self.length)
|
||||
genome += "".join(map(str, exclusive))
|
||||
return genome
|
||||
|
||||
def find_fitness(self, genome):
|
||||
fitness = 0
|
||||
for i in range(len(genome) - 1):
|
||||
fitness += self.chrome[int(genome[i])][int(genome[i + 1])]
|
||||
return fitness
|
||||
|
||||
def crossOver(self, gen1, gen2):
|
||||
gen = []
|
||||
for i in range(self.div):
|
||||
gen.append(gen1[i])
|
||||
for i in range(self.div, self.length+1):
|
||||
if gen2[i] not in gen:
|
||||
gen.append(gen2[i])
|
||||
else:
|
||||
j = 0
|
||||
while gen1[j] in gen:
|
||||
j += 1
|
||||
gen.append(gen1[j])
|
||||
return ''.join(gen)
|
||||
|
||||
def mutation(self, genome):
|
||||
genome = list(genome)
|
||||
while True:
|
||||
gen1 = random.randint(1, self.length - 1)
|
||||
gen2 = random.randint(1, self.length - 1)
|
||||
if gen1 != gen2:
|
||||
genome[gen1], genome[gen2] = genome[gen2], genome[gen1]
|
||||
break
|
||||
return ''.join(genome)
|
||||
|
||||
def search(self):
|
||||
gen = 1
|
||||
population = []
|
||||
|
||||
for i in range(self.pop_size):
|
||||
ind = individual()
|
||||
ind.genome = self.create_genome()
|
||||
ind.fitness = self.find_fitness(ind.genome)
|
||||
population.append(ind)
|
||||
|
||||
print("First population:")
|
||||
for ind in population:
|
||||
print(ind.genome, ind.fitness)
|
||||
|
||||
while gen <= self.gen_max:
|
||||
new_population = population
|
||||
|
||||
key = random.randint(0, 100)
|
||||
if key > self.key:
|
||||
for i in range(self.pop_size):
|
||||
temp1, temp2 = random.sample(population, 2)
|
||||
new_ind1 = individual()
|
||||
new_ind1.genome = self.crossOver(temp1.genome, temp2.genome)
|
||||
new_ind1.fitness = self.find_fitness(new_ind1.genome)
|
||||
new_ind2 = individual()
|
||||
new_ind2.genome = self.crossOver(temp2.genome, temp1.genome)
|
||||
new_ind2.fitness = self.find_fitness(new_ind2.genome)
|
||||
new_population.append(new_ind1)
|
||||
new_population.append(new_ind2)
|
||||
new_population.sort()
|
||||
new_population.pop()
|
||||
new_population.pop()
|
||||
else:
|
||||
print('mutation')
|
||||
for i in range(self.pop_size):
|
||||
temp1 = random.choice(population)
|
||||
new_ind = individual()
|
||||
new_ind.genome = self.mutation(temp1.genome)
|
||||
new_ind.fitness = self.find_fitness(new_ind.genome)
|
||||
new_population.append(new_ind)
|
||||
new_population.sort()
|
||||
new_population.pop()
|
||||
print("\n")
|
||||
print("New Generation # ", gen)
|
||||
print("Genome Fitness")
|
||||
|
||||
for i in range(self.pop_size):
|
||||
print(new_population[i].genome, new_population[i].fitness)
|
||||
|
||||
print("\n")
|
||||
|
||||
gen += 1
|
||||
|
||||
ans = min(population, key=lambda x: x.fitness)
|
||||
print("Final order: ", ans.genome, ans.fitness)
|
||||
return ans.genome
|
||||
|
||||
|
||||
class individual:
|
||||
def __init__(self):
|
||||
self.genome = 0
|
||||
self.fitness = 0
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.fitness < other.fitness
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.fitness > other.fitness
|
||||
|
||||
def __le__(self, other):
|
||||
return self.fitness <= other.fitness
|
||||
|
||||
def __ge__(self, other):
|
||||
return self.fitness >= other.fitness
|
50
main.py
50
main.py
@ -7,6 +7,7 @@ from rubbish import *
|
||||
from tree import evaluate_values, trash_selection
|
||||
from truck import Truck
|
||||
from surface import *
|
||||
from genetic import genetic
|
||||
|
||||
RESOLUTION = 900
|
||||
SIZE = 60
|
||||
@ -52,6 +53,11 @@ for i in range(15):
|
||||
rubbish_list.append(Rubbish(screen, j * 60, i * 60))
|
||||
|
||||
path = []
|
||||
gen = [(truck.y / 60, truck.x / 60)]
|
||||
fl = 0
|
||||
length = []
|
||||
finalLength = []
|
||||
order = []
|
||||
while True:
|
||||
pygame.time.delay(500)
|
||||
|
||||
@ -64,11 +70,40 @@ while True:
|
||||
i.draw_rubbish()
|
||||
truck.draw_truck()
|
||||
|
||||
# finding order to collect rubbish
|
||||
if fl == 0:
|
||||
for item in rubbish_list:
|
||||
print(item.y / 60, item.x / 60, end='\n')
|
||||
gen.append((item.y / 60, item.x / 60))
|
||||
for item1 in range(len(gen)):
|
||||
for item2 in range(len(gen)):
|
||||
if item1 < item2:
|
||||
length.append(len(a_star(surface_list, gen[item2]).tree_search(PriorityQueue(), gen[item1], 'R')))
|
||||
else:
|
||||
length.append(0)
|
||||
finalLength.append(length)
|
||||
length = []
|
||||
fl = 1
|
||||
for i in range(len(finalLength)):
|
||||
for j in range(len(finalLength)):
|
||||
if i > j:
|
||||
finalLength[i][j] = finalLength[j][i]
|
||||
for i in range(len(finalLength)):
|
||||
for j in range(len(finalLength)):
|
||||
print(finalLength[i][j], end=',')
|
||||
print('')
|
||||
print(finalLength)
|
||||
order = genetic(finalLength).search()
|
||||
order = list(map(int, order))
|
||||
order.pop(0)
|
||||
for j in range(len(order)):
|
||||
order[j] -= 1
|
||||
|
||||
# finding a path to rubbish
|
||||
if rubbish_list and not path:
|
||||
if order and not path:
|
||||
start = (truck.y / 60, truck.x / 60)
|
||||
direction = truck.direction
|
||||
currentRubbish = rubbish_list[0]
|
||||
currentRubbish = rubbish_list[order[0]]
|
||||
endpoint = (currentRubbish.y / 60, currentRubbish.x / 60)
|
||||
# path = bfs(surface_list, endpoint).tree_search(deque(), start, direction)
|
||||
path = a_star(surface_list, endpoint).tree_search(PriorityQueue(), start, direction)
|
||||
@ -82,8 +117,8 @@ while True:
|
||||
truck.change_direction(action)
|
||||
|
||||
# the decision that takes what to do with the garbage
|
||||
if not path and rubbish_list:
|
||||
data = rubbish_list[0].data_for_decision_tree()
|
||||
if not path and order:
|
||||
data = rubbish_list[order[0]].data_for_decision_tree()
|
||||
print(f'----------\n'
|
||||
f'Characteristics of the garbage we met:\n'
|
||||
f'Weight:{data[0]}\nDensity:{data[1]}\n'
|
||||
@ -94,12 +129,11 @@ while True:
|
||||
decision = trash_selection(evaluate_values(data))
|
||||
if decision == [0]:
|
||||
print('We refused this rubbish because of bad characteristics')
|
||||
rubbish_list[0].rubbish_refused()
|
||||
refused_rubbish_list.append(rubbish_list[0])
|
||||
rubbish_list[order[0]].rubbish_refused()
|
||||
refused_rubbish_list.append(rubbish_list[order[0]])
|
||||
else:
|
||||
print('We take this rubbish because of good characteristics')
|
||||
rubbish_list.pop(0)
|
||||
|
||||
order.pop(0)
|
||||
pygame.display.flip()
|
||||
|
||||
for event in pygame.event.get():
|
||||
|
Loading…
Reference in New Issue
Block a user