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])
|
location = tuple([a_row, a_column])
|
||||||
allowed_points.add(location)
|
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
|
@staticmethod
|
||||||
def set_puddles(puddle_points):
|
def set_puddles(puddle_points):
|
||||||
temp_map = [list(item) for item in SweeperAgent.loadMap('map.txt')]
|
temp_map = [list(item) for item in SweeperAgent.loadMap('map.txt')]
|
||||||
@ -351,6 +367,34 @@ class SweeperAgent:
|
|||||||
|
|
||||||
return orientation
|
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
|
@staticmethod
|
||||||
def run(self):
|
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 pizza import *
|
||||||
from learning import *
|
from learning import *
|
||||||
from nn import *
|
from nn import *
|
||||||
|
from genetic import *
|
||||||
|
#from genetic3 import *
|
||||||
#from csv_writer import *
|
#from csv_writer import *
|
||||||
|
|
||||||
|
|
||||||
@ -153,6 +155,16 @@ class Game:
|
|||||||
player_moves = SweeperAgent.run(agent)
|
player_moves = SweeperAgent.run(agent)
|
||||||
self.graph_move(player_moves)
|
self.graph_move(player_moves)
|
||||||
self.wentyl_bezpieczenstwa = 1
|
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