genetic
Co-authored-by: Sebastian Piotrowski <sebpio@st.amu.edu.pl> Co-authored-by: Marcin Matoga <marmat35@st.amu.edu.pl> Co-authored-by: Ladislaus3III <Ladislaus3III@users.noreply.github.com>
This commit is contained in:
parent
a1a2ef6aae
commit
9429d93da9
44
astar2.py
44
astar2.py
@ -264,6 +264,22 @@ class SweeperAgent:
|
||||
location = tuple([a_row, a_column])
|
||||
allowed_points.add(location)
|
||||
|
||||
@staticmethod
|
||||
def set_allowed_for_genetic(allowed_points, map_location):
|
||||
temp_map = [list(item) for item in SweeperAgent.loadMap(map_location)]
|
||||
|
||||
a_row = 0
|
||||
a_column = 0
|
||||
|
||||
for row in range(MAP_SIZE):
|
||||
for column, pos in enumerate(temp_map[row]):
|
||||
if pos == "." or pos == 'x':
|
||||
a_row = row
|
||||
a_column = column
|
||||
location = tuple([a_row, a_column])
|
||||
allowed_points.add(location)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def set_puddles(puddle_points):
|
||||
temp_map = [list(item) for item in SweeperAgent.loadMap('map.txt')]
|
||||
@ -351,6 +367,34 @@ class SweeperAgent:
|
||||
|
||||
return orientation
|
||||
|
||||
@staticmethod
|
||||
def run_manual(self,
|
||||
given_orientation,
|
||||
given_goal_orientation,
|
||||
x_my_location,
|
||||
y_my_location,
|
||||
x_goal_location,
|
||||
y_goal_location,
|
||||
map_location
|
||||
):
|
||||
|
||||
self.orientation = given_orientation
|
||||
goal_orientation = given_goal_orientation
|
||||
|
||||
SweeperAgent.set_allowed(self.set_allowed_for_genetic(map_location))
|
||||
|
||||
x = x_my_location
|
||||
y = y_my_location
|
||||
|
||||
x1 = x_goal_location
|
||||
x2 = y_goal_location
|
||||
|
||||
agent_position = AgentPosition(x, y, self.orientation)
|
||||
goal_position = AgentPosition(x1, x2, goal_orientation)
|
||||
|
||||
return len(self.plan_route(agent_position, goal_position, self.allowed_points, self.puddle_points))
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def run(self):
|
||||
|
278
genetic.py
Normal file
278
genetic.py
Normal file
@ -0,0 +1,278 @@
|
||||
import random
|
||||
|
||||
class Genetic():
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def calc_cost(self, mines_list):
|
||||
self.mined_tile_count = len(mines_list)
|
||||
total_cost = 0
|
||||
i = 0
|
||||
while i < (self.mined_tile_count - 1):
|
||||
total_cost = total_cost + self.manhattan_cost_counter(mines_list, i)
|
||||
i = i + 1
|
||||
|
||||
return total_cost
|
||||
|
||||
def manhattan_cost_counter(self, mines_list, i):
|
||||
|
||||
|
||||
x1, y1 = mines_list[i][0], mines_list[i][1]
|
||||
x2, y2 = mines_list[i+1][0], mines_list[i+1][1]
|
||||
|
||||
|
||||
return abs(x2 - x1) + abs(y2 - y1)
|
||||
|
||||
def population_initialization(self, mines_list, i):
|
||||
first_mine = mines_list[0]
|
||||
x = len(mines_list)-1
|
||||
shuffled_coordinates = []
|
||||
while x > 0:
|
||||
shuffled_coordinates.append(mines_list[x])
|
||||
x = x - 1
|
||||
|
||||
mine_chromosome = []
|
||||
while i > 0:
|
||||
child = random.sample(shuffled_coordinates, len(shuffled_coordinates))
|
||||
child.insert(0, first_mine)
|
||||
#child.insert(x, first_mine)
|
||||
mine_chromosome.append(child)
|
||||
i = i - 1
|
||||
return mine_chromosome
|
||||
|
||||
def fitness_function(self, generations):
|
||||
total_cost = 0
|
||||
chromosome_count = 0
|
||||
chromosome_costs = []
|
||||
y = 0
|
||||
#problem - wyjście poza liste
|
||||
if len(generations) == 0:
|
||||
return
|
||||
|
||||
first_cost = self.calc_cost(generations[y])
|
||||
cheapest_chromosome = generations[y]
|
||||
lowest_cost = first_cost
|
||||
highest_cost = first_cost
|
||||
for i in generations:
|
||||
chromosome_costs.append(self.calc_cost(i))
|
||||
total_cost = total_cost + self.calc_cost(i)
|
||||
chromosome_count = chromosome_count + 1
|
||||
if self.calc_cost(i) < lowest_cost:
|
||||
lowest_cost = self.calc_cost(i)
|
||||
cheapest_chromosome = i
|
||||
if self.calc_cost(i) > highest_cost:
|
||||
highest_cost = self.calc_cost(i)
|
||||
|
||||
average_fitness = total_cost/chromosome_count
|
||||
chromosome_fitness = []
|
||||
total_chromosome_fitness = 0
|
||||
l = 0
|
||||
for i in chromosome_costs:
|
||||
chromosome_fitness.append(round(((average_fitness/chromosome_costs[l])*10), 2))
|
||||
total_chromosome_fitness += round(((average_fitness/chromosome_costs[l])*10),2)
|
||||
l = l + 1
|
||||
|
||||
return(chromosome_fitness, lowest_cost, highest_cost, average_fitness, cheapest_chromosome)
|
||||
|
||||
|
||||
def fitness_population_selection(self, first_generation, chromosome_fitness):
|
||||
x = len(chromosome_fitness)
|
||||
roulette_table = []
|
||||
average_population = []
|
||||
i = 0
|
||||
interval = 0
|
||||
while x > 0:
|
||||
interval = interval + chromosome_fitness[i]
|
||||
roulette_table.append(round(interval, 2))
|
||||
x = x - 1
|
||||
i = i + 1
|
||||
x = len(chromosome_fitness)/2
|
||||
max = roulette_table[i - 1]
|
||||
while x > 0:
|
||||
i = 0
|
||||
n = random.uniform(0, max)
|
||||
while n > roulette_table[i]:
|
||||
i = i + 1
|
||||
average_population.append(first_generation[i])
|
||||
x = x - 1
|
||||
return average_population
|
||||
|
||||
def crossover(self, average_population):
|
||||
post_crossover_population = []
|
||||
x = len(average_population) - 1
|
||||
if x <= 0:
|
||||
print("no enough chromosomes to crossover")
|
||||
return
|
||||
while x > 0:
|
||||
parent_1 = average_population[x]
|
||||
parent_2 = average_population[x-1]
|
||||
child_1 = []
|
||||
child_2 = []
|
||||
crossover_decision = random.randint(1, 100)
|
||||
if (crossover_decision < 11) and (parent_1 != parent_2):
|
||||
crossover_point = random.randint(1, (len(average_population[x])-3))
|
||||
l = 0
|
||||
k = crossover_point
|
||||
while k >= 0:
|
||||
child_1.append(parent_1[l])
|
||||
l = l + 1
|
||||
k = k - 1
|
||||
k = crossover_point
|
||||
while k < (len(parent_1) - 1):
|
||||
for i in parent_2:
|
||||
if i not in child_1:
|
||||
child_1.append(i)
|
||||
k = k + 1
|
||||
|
||||
l = 0
|
||||
k = crossover_point
|
||||
while k >= 0:
|
||||
child_2.append(parent_2[l])
|
||||
l = l + 1
|
||||
k = k - 1
|
||||
k = crossover_point
|
||||
while k >= 0:
|
||||
child_2.append(parent_2[l])
|
||||
l = l + 1
|
||||
k = k - 1
|
||||
k = crossover_point
|
||||
while k < (len(parent_1) - 1):
|
||||
for i in parent_1:
|
||||
if i not in child_2:
|
||||
child_2.append(i)
|
||||
k = k + 1
|
||||
#child_1.append(0)
|
||||
#child_2.append(0)
|
||||
else:
|
||||
child_1 = parent_1
|
||||
child_2 = parent_2
|
||||
post_crossover_population.append(child_1)
|
||||
post_crossover_population.append(child_2)
|
||||
x = x - 1
|
||||
|
||||
return post_crossover_population
|
||||
|
||||
def mutation(self, post_crossover_popualtion):
|
||||
k = len(post_crossover_popualtion) - 1
|
||||
while k >= 0:
|
||||
mutation_decision = random.randint(0, 100)
|
||||
if mutation_decision < 3:
|
||||
mutated_chromosome = post_crossover_popualtion[k]
|
||||
post_crossover_popualtion.remove(mutated_chromosome)
|
||||
l = len(mutated_chromosome) - 1
|
||||
|
||||
x = random.randint(1, l)
|
||||
y = random.randint(1, l)
|
||||
while x == y:
|
||||
y = random.randint(1, l)
|
||||
replacement = mutated_chromosome[x]
|
||||
mutated_chromosome[y] = replacement
|
||||
|
||||
post_crossover_popualtion.insert(k, mutated_chromosome)
|
||||
|
||||
k = k - 1
|
||||
post_mutation_population = post_crossover_popualtion
|
||||
|
||||
return post_mutation_population
|
||||
|
||||
def optimize(self, post_mutation_population, mine_list):
|
||||
post_optimization_population = post_mutation_population
|
||||
i = len(post_mutation_population)
|
||||
l = 1
|
||||
while l < i:
|
||||
k = 1
|
||||
while k >= 0:
|
||||
if post_mutation_population[l] == post_mutation_population[k - 1]:
|
||||
post_optimization_population.remove(post_mutation_population[k-1])
|
||||
x = len(mine_list) - 2
|
||||
shuffled_coordinates = []
|
||||
while x > 0:
|
||||
shuffled_coordinates.append(mine_list[x])
|
||||
x = x - 1
|
||||
x = len(mine_list) - 1
|
||||
new_chromosome = random.sample(shuffled_coordinates, len(shuffled_coordinates))
|
||||
new_chromosome.insert(0, mine_list[0])
|
||||
new_chromosome.insert(x, mine_list[0])
|
||||
post_optimization_population.append(new_chromosome)
|
||||
|
||||
k = k - 1
|
||||
l = l + 1
|
||||
return post_optimization_population
|
||||
|
||||
def genetic_algorythm(self, coordinates):
|
||||
self.full_cost = self.calc_cost(coordinates)
|
||||
self.first_generation = self.population_initialization(coordinates,10)
|
||||
self.fitness, self.lowest_cost, self.highest_cost, self.average_fitness_of_first_genetation, self.cheapest_individual = self.fitness_function(self.first_generation)
|
||||
self.average_population = self.fitness_population_selection(self.first_generation, self.fitness)
|
||||
self.population_after_crossover = self.crossover(self.average_population)
|
||||
|
||||
|
||||
if self.population_after_crossover == None:
|
||||
print("Finished in " + str(self.which_generation) + "generations")
|
||||
return
|
||||
|
||||
self.population_after_mutation = self.mutation(self.population_after_crossover)
|
||||
self.population_after_optimization = self.optimize(self.population_after_mutation, coordinates)
|
||||
self.max_cost = self.highest_cost
|
||||
self.min_cost = self.lowest_cost
|
||||
self.cheapest_route = self.cheapest_individual
|
||||
i = 2
|
||||
self.which_generation = 1
|
||||
while i < 41:
|
||||
print(" ")
|
||||
print("***********")
|
||||
print("Generation " + str(i))
|
||||
print("***********")
|
||||
print(" ")
|
||||
|
||||
if self.fitness_function(self.population_after_optimization) == None:
|
||||
return
|
||||
|
||||
self.fitness, self.lowest_cost, self.highest_cost, self.average_fitness_of_first_genetation, self.cheapest_individual = self.fitness_function(self.population_after_optimization)
|
||||
if self.highest_cost > self.max_cost:
|
||||
self.max_cost = self.highest_cost
|
||||
if self.lowest_cost < self.min_cost:
|
||||
self.min_cost = self.lowest_cost
|
||||
self.cheapest_route = self.cheapest_individual
|
||||
self.which_generation = i
|
||||
print("New lowest cost: " + str(self.min_cost))
|
||||
print("New cheapest route: " + str(self.cheapest_route))
|
||||
|
||||
self.average_population = self.fitness_population_selection(self.population_after_mutation, self.fitness)
|
||||
|
||||
self.population_after_crossover = self.crossover(self.average_population)
|
||||
|
||||
if self.population_after_crossover == None:
|
||||
print("Finished")
|
||||
return
|
||||
|
||||
self.population_after_mutation = self.mutation(self.population_after_crossover)
|
||||
self.population_after_optimization = self.optimize(self.population_after_mutation, coordinates)
|
||||
i = i + 1
|
||||
if(self.min_cost)/(self.average_fitness_of_first_genetation) < (0.7):
|
||||
print("Finished after " + str(i)+ " generations")
|
||||
break
|
||||
print("Average fitness of first generation: " + str(self.average_fitness_of_first_genetation))
|
||||
print("Relation of efficiency growth: " + str((self.min_cost)/(self.average_fitness_of_first_genetation)))
|
||||
print("Lowest cost is " + str(self.min_cost))
|
||||
print("Cheapest route is: " + str(self.cheapest_route))
|
||||
|
||||
def run(self):
|
||||
Mines = [[1,1],
|
||||
[2,4],
|
||||
[3,1],
|
||||
[4,7],
|
||||
[5,3],
|
||||
[7,6]]
|
||||
|
||||
self.genetic_algorythm(Mines)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
106
genetic3.py
Normal file
106
genetic3.py
Normal file
@ -0,0 +1,106 @@
|
||||
import numpy as np
|
||||
import math
|
||||
import random
|
||||
from geneticalgorithm import geneticalgorithm as ga
|
||||
from astar2 import *
|
||||
|
||||
|
||||
class Mine():
|
||||
def __init__(self, row, column):
|
||||
self.row = row
|
||||
self.columnt = column
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class GeneticalWithLib():
|
||||
|
||||
Miasta = [[0, 130, 180, 300],
|
||||
[130, 0, 320, 350],
|
||||
[180, 320, 0, 360],
|
||||
[300, 350, 360, 0]]
|
||||
#Miasta = [[0, 2, 6, 3, 7],
|
||||
# [2, 0, 6, 4, 8],
|
||||
# [6, 6, 0, 5, 8],
|
||||
# [3, 4, 5, 0, 9],
|
||||
# [7, 8, 8, 9, 0]]
|
||||
|
||||
self.mine_points = set()
|
||||
|
||||
|
||||
def getCoordinates(self):
|
||||
temp_map = [list(item) for item in SweeperAgent.loadMap('genetic_maps/map1.txt')]
|
||||
|
||||
a_row = 0
|
||||
a_column = 0
|
||||
|
||||
for row in range(MAP_SIZE):
|
||||
for column, pos in enumerate(temp_map[row]):
|
||||
if pos == "m" :
|
||||
a_row = row
|
||||
a_column = column
|
||||
location = tuple([a_row, a_column])
|
||||
self.mine_points.add(location)
|
||||
|
||||
def setDistance(self):
|
||||
pass
|
||||
|
||||
|
||||
def fillDistanceMatrix(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def f(X):
|
||||
for i in range(len(Miasta[0])):
|
||||
if X[i] not in Miasta[i]:
|
||||
return np.sum(X)+12000
|
||||
for i in range(len(Miasta[0])):
|
||||
if i == 0:
|
||||
if (X[0]-X[len(Miasta[0])-1]) == 0:
|
||||
return np.sum(X)+12000
|
||||
else:
|
||||
if abs(X[i]-X[i-1]) == 0:
|
||||
return np.sum(X)+12000
|
||||
if i != len(Miasta[0])-1:
|
||||
if abs(X[i+1]-X[i-1]) == 0:
|
||||
return np.sum(X)+12000
|
||||
var = []
|
||||
for j in range(len(Miasta[0])):
|
||||
var.append(0)
|
||||
for i in range(len(Miasta[0])):
|
||||
var[Miasta[i].index(X[i])] += 1
|
||||
for s in var:
|
||||
if s != 1:
|
||||
return np.sum(X)+9000
|
||||
return np.sum(X)
|
||||
|
||||
varbound = np.array([[130,300],
|
||||
[130,350],
|
||||
[180,360],
|
||||
[300,360]])
|
||||
|
||||
#varbound = np.array([[2,7],
|
||||
# [2,8],
|
||||
# [5,8],
|
||||
# [4,9],
|
||||
# [7,9]])
|
||||
|
||||
algorithm_param = {'max_num_iteration': 3000,\
|
||||
'population_size':100,\
|
||||
'mutation_probability':0.1,\
|
||||
'elit_ratio': 0.01,\
|
||||
'crossover_probability': 0.5,\
|
||||
'parents_portion': 0.3,\
|
||||
'crossover_type':'uniform',\
|
||||
'max_iteration_without_improv':None}
|
||||
|
||||
model=ga(function=f,\
|
||||
dimension=len(Miasta[0]),\
|
||||
variable_type='int',\
|
||||
variable_boundaries=varbound,\
|
||||
algorithm_parameters=algorithm_param)
|
||||
|
||||
model.run()
|
||||
#print(f([180, 350, 180, 350]))
|
8
genetic_maps/map1.txt
Normal file
8
genetic_maps/map1.txt
Normal file
@ -0,0 +1,8 @@
|
||||
x......
|
||||
...x...
|
||||
x......
|
||||
......x
|
||||
..x....
|
||||
.......
|
||||
.....x.
|
||||
|
12
main.py
12
main.py
@ -17,6 +17,8 @@ from astar2 import *
|
||||
from pizza import *
|
||||
from learning import *
|
||||
from nn import *
|
||||
from genetic import *
|
||||
#from genetic3 import *
|
||||
#from csv_writer import *
|
||||
|
||||
|
||||
@ -153,6 +155,16 @@ class Game:
|
||||
player_moves = SweeperAgent.run(agent)
|
||||
self.graph_move(player_moves)
|
||||
self.wentyl_bezpieczenstwa = 1
|
||||
if event.key == pg.K_F8 and self.wentyl_bezpieczenstwa == 0:
|
||||
#print("pressed")
|
||||
genetic_runner = Genetic()
|
||||
genetic_runner.run()
|
||||
self.wentyl_bezpieczenstwa = 1
|
||||
if event.key == pg.K_F9 and self.wentyl_bezpieczenstwa == 0:
|
||||
#genetic_lib_runner = GeneticalWithLib()
|
||||
#genetic_lib_runner.run()
|
||||
self.wentyl_bezpieczenstwa = 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user