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:
eugenep 2021-06-19 23:55:47 +02:00
parent a1a2ef6aae
commit 9429d93da9
5 changed files with 448 additions and 0 deletions

View File

@ -263,6 +263,22 @@ class SweeperAgent:
a_column = column
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):
@ -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
View 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
View 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
View File

@ -0,0 +1,8 @@
x......
...x...
x......
......x
..x....
.......
.....x.

12
main.py
View File

@ -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