tsp v4.1a, getting distance from astar not from pythagoras
This commit is contained in:
parent
75746f077e
commit
65f469465a
@ -4,12 +4,12 @@
|
|||||||
| | | |--- class: 0
|
| | | |--- class: 0
|
||||||
| | |--- feature_0 > 1.50
|
| | |--- feature_0 > 1.50
|
||||||
| | | |--- feature_3 <= 3.50
|
| | | |--- feature_3 <= 3.50
|
||||||
| | | | |--- feature_4 <= 2.50
|
| | | | |--- feature_2 <= 2.50
|
||||||
| | | | | |--- class: 1
|
| | | | | |--- class: 1
|
||||||
| | | | |--- feature_4 > 2.50
|
| | | | |--- feature_2 > 2.50
|
||||||
| | | | | |--- feature_2 <= 2.50
|
| | | | | |--- feature_4 <= 2.50
|
||||||
| | | | | | |--- class: 1
|
| | | | | | |--- class: 1
|
||||||
| | | | | |--- feature_2 > 2.50
|
| | | | | |--- feature_4 > 2.50
|
||||||
| | | | | | |--- class: 0
|
| | | | | | |--- class: 0
|
||||||
| | | |--- feature_3 > 3.50
|
| | | |--- feature_3 > 3.50
|
||||||
| | | | |--- feature_3 <= 4.50
|
| | | | |--- feature_3 <= 4.50
|
||||||
@ -26,18 +26,18 @@
|
|||||||
| | | | | | | |--- feature_1 > 1.50
|
| | | | | | | |--- feature_1 > 1.50
|
||||||
| | | | | | | | |--- class: 0
|
| | | | | | | | |--- class: 0
|
||||||
| | | | | | |--- feature_0 > 2.50
|
| | | | | | |--- feature_0 > 2.50
|
||||||
| | | | | | | |--- feature_2 <= 2.50
|
| | | | | | | |--- feature_4 <= 2.50
|
||||||
| | | | | | | | |--- class: 1
|
| | | | | | | | |--- class: 1
|
||||||
| | | | | | | |--- feature_2 > 2.50
|
| | | | | | | |--- feature_4 > 2.50
|
||||||
| | | | | | | | |--- feature_4 <= 2.50
|
| | | | | | | | |--- feature_2 <= 2.50
|
||||||
| | | | | | | | | |--- class: 1
|
| | | | | | | | | |--- class: 1
|
||||||
| | | | | | | | |--- feature_4 > 2.50
|
| | | | | | | | |--- feature_2 > 2.50
|
||||||
| | | | | | | | | |--- class: 0
|
| | | | | | | | | |--- class: 0
|
||||||
| | | | | |--- feature_1 > 2.50
|
| | | | | |--- feature_1 > 2.50
|
||||||
| | | | | | |--- feature_1 <= 3.50
|
| | | | | | |--- feature_0 <= 3.50
|
||||||
| | | | | | | |--- feature_0 <= 3.50
|
| | | | | | | |--- class: 0
|
||||||
| | | | | | | | |--- class: 0
|
| | | | | | |--- feature_0 > 3.50
|
||||||
| | | | | | | |--- feature_0 > 3.50
|
| | | | | | | |--- feature_1 <= 3.50
|
||||||
| | | | | | | | |--- feature_2 <= 2.50
|
| | | | | | | | |--- feature_2 <= 2.50
|
||||||
| | | | | | | | | |--- class: 1
|
| | | | | | | | | |--- class: 1
|
||||||
| | | | | | | | |--- feature_2 > 2.50
|
| | | | | | | | |--- feature_2 > 2.50
|
||||||
@ -45,8 +45,8 @@
|
|||||||
| | | | | | | | | | |--- class: 1
|
| | | | | | | | | | |--- class: 1
|
||||||
| | | | | | | | | |--- feature_4 > 2.00
|
| | | | | | | | | |--- feature_4 > 2.00
|
||||||
| | | | | | | | | | |--- class: 0
|
| | | | | | | | | | |--- class: 0
|
||||||
| | | | | | |--- feature_1 > 3.50
|
| | | | | | | |--- feature_1 > 3.50
|
||||||
| | | | | | | |--- class: 0
|
| | | | | | | | |--- class: 0
|
||||||
| | | | |--- feature_3 > 4.50
|
| | | | |--- feature_3 > 4.50
|
||||||
| | | | | |--- class: 0
|
| | | | | |--- class: 0
|
||||||
| |--- feature_4 > 3.50
|
| |--- feature_4 > 3.50
|
||||||
@ -59,13 +59,13 @@
|
|||||||
| | | | | | |--- class: 1
|
| | | | | | |--- class: 1
|
||||||
| | | | |--- feature_3 > 3.50
|
| | | | |--- feature_3 > 3.50
|
||||||
| | | | | |--- feature_1 <= 2.50
|
| | | | | |--- feature_1 <= 2.50
|
||||||
| | | | | | |--- feature_3 <= 4.50
|
| | | | | | |--- feature_0 <= 2.50
|
||||||
| | | | | | | |--- feature_0 <= 2.50
|
|
||||||
| | | | | | | | |--- class: 0
|
|
||||||
| | | | | | | |--- feature_0 > 2.50
|
|
||||||
| | | | | | | | |--- class: 1
|
|
||||||
| | | | | | |--- feature_3 > 4.50
|
|
||||||
| | | | | | | |--- class: 0
|
| | | | | | | |--- class: 0
|
||||||
|
| | | | | | |--- feature_0 > 2.50
|
||||||
|
| | | | | | | |--- feature_3 <= 4.50
|
||||||
|
| | | | | | | | |--- class: 1
|
||||||
|
| | | | | | | |--- feature_3 > 4.50
|
||||||
|
| | | | | | | | |--- class: 0
|
||||||
| | | | | |--- feature_1 > 2.50
|
| | | | | |--- feature_1 > 2.50
|
||||||
| | | | | | |--- class: 0
|
| | | | | | |--- class: 0
|
||||||
| | | |--- feature_4 > 4.50
|
| | | |--- feature_4 > 4.50
|
||||||
@ -73,19 +73,19 @@
|
|||||||
| | |--- feature_2 > 1.50
|
| | |--- feature_2 > 1.50
|
||||||
| | | |--- class: 0
|
| | | |--- class: 0
|
||||||
|--- feature_2 > 3.50
|
|--- feature_2 > 3.50
|
||||||
| |--- feature_1 <= 1.50
|
| |--- feature_4 <= 1.50
|
||||||
| | |--- feature_4 <= 1.50
|
| | |--- feature_1 <= 1.50
|
||||||
| | | |--- feature_2 <= 4.50
|
| | | |--- feature_2 <= 4.50
|
||||||
| | | | |--- feature_3 <= 4.50
|
| | | | |--- feature_0 <= 1.50
|
||||||
| | | | | |--- feature_0 <= 1.50
|
|
||||||
| | | | | | |--- class: 0
|
|
||||||
| | | | | |--- feature_0 > 1.50
|
|
||||||
| | | | | | |--- class: 1
|
|
||||||
| | | | |--- feature_3 > 4.50
|
|
||||||
| | | | | |--- class: 0
|
| | | | | |--- class: 0
|
||||||
|
| | | | |--- feature_0 > 1.50
|
||||||
|
| | | | | |--- feature_3 <= 4.50
|
||||||
|
| | | | | | |--- class: 1
|
||||||
|
| | | | | |--- feature_3 > 4.50
|
||||||
|
| | | | | | |--- class: 0
|
||||||
| | | |--- feature_2 > 4.50
|
| | | |--- feature_2 > 4.50
|
||||||
| | | | |--- class: 0
|
| | | | |--- class: 0
|
||||||
| | |--- feature_4 > 1.50
|
| | |--- feature_1 > 1.50
|
||||||
| | | |--- class: 0
|
| | | |--- class: 0
|
||||||
| |--- feature_1 > 1.50
|
| |--- feature_4 > 1.50
|
||||||
| | |--- class: 0
|
| | |--- class: 0
|
||||||
|
Binary file not shown.
@ -1,15 +1,22 @@
|
|||||||
import numpy as np, random, operator, pandas as pd, matplotlib.pyplot as plt
|
import numpy as np, random, operator, pandas as pd, matplotlib.pyplot as plt
|
||||||
from path_search_algorthms import a_star
|
from path_search_algorthms.a_star import get_cost
|
||||||
from decision_tree import decisionTree
|
from decision_tree import decisionTree
|
||||||
|
from settings import *
|
||||||
|
import math
|
||||||
|
|
||||||
# klasa tworząca miasta czy też śmietniki
|
# klasa tworząca miasta czy też śmietniki
|
||||||
class City:
|
class City:
|
||||||
def __init__(self, x, y):
|
def __init__(self, x, y):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
|
#self.array = array
|
||||||
# self.dist = distance
|
# self.dist = distance
|
||||||
|
|
||||||
|
#dystans to d = sqrt(x^2 + y^2)
|
||||||
def distance(self, city):
|
def distance(self, city):
|
||||||
|
|
||||||
|
#getting distance by astar gives wrong final distance (intial = final)
|
||||||
|
#return get_cost(math.floor(self.x / TILESIZE), math.floor(self.y / TILESIZE), math.floor(city.x / TILESIZE), math.floor(city.y / TILESIZE), self.array)
|
||||||
xDis = abs(self.x - city.x)
|
xDis = abs(self.x - city.x)
|
||||||
yDis = abs(self.y - city.y)
|
yDis = abs(self.y - city.y)
|
||||||
distance = np.sqrt((xDis ** 2) + (yDis ** 2))
|
distance = np.sqrt((xDis ** 2) + (yDis ** 2))
|
||||||
@ -18,6 +25,7 @@ class City:
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "(" + str(self.x) + "," + str(self.y) + ")"
|
return "(" + str(self.x) + "," + str(self.y) + ")"
|
||||||
|
|
||||||
|
|
||||||
# fitness function,
|
# fitness function,
|
||||||
# inverse of route distance
|
# inverse of route distance
|
||||||
# we want to minimize distance so the larger the fitness the better
|
# we want to minimize distance so the larger the fitness the better
|
||||||
@ -25,10 +33,10 @@ class Fitness:
|
|||||||
def __init__(self, route):
|
def __init__(self, route):
|
||||||
self.route = route
|
self.route = route
|
||||||
self.distance = 0
|
self.distance = 0
|
||||||
self.fitness= 0.0
|
self.fitness = 0.0
|
||||||
|
|
||||||
def routeDistance(self):
|
def routeDistance(self):
|
||||||
if self.distance ==0:
|
if self.distance == 0:
|
||||||
pathDistance = 0
|
pathDistance = 0
|
||||||
for i in range(0, len(self.route)):
|
for i in range(0, len(self.route)):
|
||||||
fromCity = self.route[i]
|
fromCity = self.route[i]
|
||||||
@ -46,11 +54,13 @@ class Fitness:
|
|||||||
self.fitness = 1 / float(self.routeDistance())
|
self.fitness = 1 / float(self.routeDistance())
|
||||||
return self.fitness
|
return self.fitness
|
||||||
|
|
||||||
|
|
||||||
# creating one individual - single route from city to city (trash to trash)
|
# creating one individual - single route from city to city (trash to trash)
|
||||||
def createRoute(cityList):
|
def createRoute(cityList):
|
||||||
route = random.sample(cityList, len(cityList))
|
route = random.sample(cityList, len(cityList))
|
||||||
return route
|
return route
|
||||||
|
|
||||||
|
|
||||||
# creating initial population of given size
|
# creating initial population of given size
|
||||||
def initialPopulation(popSize, cityList):
|
def initialPopulation(popSize, cityList):
|
||||||
population = []
|
population = []
|
||||||
@ -59,12 +69,14 @@ def initialPopulation(popSize, cityList):
|
|||||||
population.append(createRoute(cityList))
|
population.append(createRoute(cityList))
|
||||||
return population
|
return population
|
||||||
|
|
||||||
|
|
||||||
# ranking fitness of given route, output is ordered list with route id and its fitness score
|
# ranking fitness of given route, output is ordered list with route id and its fitness score
|
||||||
def rankRoutes(population):
|
def rankRoutes(population):
|
||||||
fitnessResults = {}
|
fitnessResults = {}
|
||||||
for i in range(0,len(population)):
|
for i in range(0, len(population)):
|
||||||
fitnessResults[i] = Fitness(population[i]).routeFitness()
|
fitnessResults[i] = Fitness(population[i]).routeFitness()
|
||||||
return sorted(fitnessResults.items(), key = operator.itemgetter(1), reverse = True)
|
return sorted(fitnessResults.items(), key=operator.itemgetter(1), reverse=True)
|
||||||
|
|
||||||
|
|
||||||
# selecting "mating pool"
|
# selecting "mating pool"
|
||||||
# we are using here "Firness proportionate selection", its fitness-weighted probability of being selected
|
# we are using here "Firness proportionate selection", its fitness-weighted probability of being selected
|
||||||
@ -73,20 +85,22 @@ def rankRoutes(population):
|
|||||||
def selection(popRanked, eliteSize):
|
def selection(popRanked, eliteSize):
|
||||||
selectionResults = []
|
selectionResults = []
|
||||||
# roulette wheel
|
# roulette wheel
|
||||||
df = pd.DataFrame(np.array(popRanked), columns=["Index","Fitness"])
|
df = pd.DataFrame(np.array(popRanked), columns=["Index", "Fitness"])
|
||||||
df['cum_sum'] = df.Fitness.cumsum()
|
df['cum_sum'] = df.Fitness.cumsum()
|
||||||
df['cum_perc'] = 100*df.cum_sum/df.Fitness.sum()
|
df['cum_perc'] = 100 * df.cum_sum / df.Fitness.sum()
|
||||||
|
|
||||||
for i in range(0, eliteSize): # elitism
|
for i in range(0, eliteSize): # elitism
|
||||||
selectionResults.append(popRanked[i][0])
|
selectionResults.append(popRanked[i][0])
|
||||||
for i in range(0, len(popRanked) - eliteSize): # comparing randomly drawn number to weights for selection for mating pool
|
for i in range(0,
|
||||||
pick = 100*random.random()
|
len(popRanked) - eliteSize): # comparing randomly drawn number to weights for selection for mating pool
|
||||||
|
pick = 100 * random.random()
|
||||||
for i in range(0, len(popRanked)):
|
for i in range(0, len(popRanked)):
|
||||||
if pick <= df.iat[i,3]:
|
if pick <= df.iat[i, 3]:
|
||||||
selectionResults.append(popRanked[i][0])
|
selectionResults.append(popRanked[i][0])
|
||||||
break
|
break
|
||||||
return selectionResults # returns list of route IDs
|
return selectionResults # returns list of route IDs
|
||||||
|
|
||||||
|
|
||||||
# creating mating pool from list of routes IDs from "selection"
|
# creating mating pool from list of routes IDs from "selection"
|
||||||
def matingPool(population, selectionResults):
|
def matingPool(population, selectionResults):
|
||||||
matingpool = []
|
matingpool = []
|
||||||
@ -95,6 +109,7 @@ def matingPool(population, selectionResults):
|
|||||||
matingpool.append(population[index])
|
matingpool.append(population[index])
|
||||||
return matingpool
|
return matingpool
|
||||||
|
|
||||||
|
|
||||||
# creating new generation
|
# creating new generation
|
||||||
# ordered crossover bc we need to include all locations exactly one time
|
# ordered crossover bc we need to include all locations exactly one time
|
||||||
# randomly selecting a subset of the first parent string and then filling the remainder of route
|
# randomly selecting a subset of the first parent string and then filling the remainder of route
|
||||||
@ -118,6 +133,7 @@ def breed(parent1, parent2):
|
|||||||
child = childP1 + childP2
|
child = childP1 + childP2
|
||||||
return child
|
return child
|
||||||
|
|
||||||
|
|
||||||
# creating whole offspring population
|
# creating whole offspring population
|
||||||
def breedPopulation(matingpool, eliteSize):
|
def breedPopulation(matingpool, eliteSize):
|
||||||
children = []
|
children = []
|
||||||
@ -125,20 +141,21 @@ def breedPopulation(matingpool, eliteSize):
|
|||||||
pool = random.sample(matingpool, len(matingpool))
|
pool = random.sample(matingpool, len(matingpool))
|
||||||
|
|
||||||
# using elitism to retain best genes (routes)
|
# using elitism to retain best genes (routes)
|
||||||
for i in range(0,eliteSize):
|
for i in range(0, eliteSize):
|
||||||
children.append(matingpool[i])
|
children.append(matingpool[i])
|
||||||
|
|
||||||
# filling rest generation
|
# filling rest generation
|
||||||
for i in range(0, length):
|
for i in range(0, length):
|
||||||
child = breed(pool[i], pool[len(matingpool)-i-1])
|
child = breed(pool[i], pool[len(matingpool) - i - 1])
|
||||||
children.append(child)
|
children.append(child)
|
||||||
return children
|
return children
|
||||||
|
|
||||||
|
|
||||||
# using swap mutation
|
# using swap mutation
|
||||||
# with specified low prob we swap two cities in route
|
# with specified low prob we swap two cities in route
|
||||||
def mutate(individual, mutationRate):
|
def mutate(individual, mutationRate):
|
||||||
for swapped in range(len(individual)):
|
for swapped in range(len(individual)):
|
||||||
if(random.random() < mutationRate):
|
if (random.random() < mutationRate):
|
||||||
swapWith = int(random.random() * len(individual))
|
swapWith = int(random.random() * len(individual))
|
||||||
|
|
||||||
city1 = individual[swapped]
|
city1 = individual[swapped]
|
||||||
@ -148,6 +165,7 @@ def mutate(individual, mutationRate):
|
|||||||
individual[swapWith] = city1
|
individual[swapWith] = city1
|
||||||
return individual
|
return individual
|
||||||
|
|
||||||
|
|
||||||
# extending mutate function to run through new pop
|
# extending mutate function to run through new pop
|
||||||
def mutatePopulation(population, mutationRate):
|
def mutatePopulation(population, mutationRate):
|
||||||
mutatedPop = []
|
mutatedPop = []
|
||||||
@ -157,6 +175,7 @@ def mutatePopulation(population, mutationRate):
|
|||||||
mutatedPop.append(mutatedInd)
|
mutatedPop.append(mutatedInd)
|
||||||
return mutatedPop
|
return mutatedPop
|
||||||
|
|
||||||
|
|
||||||
# creating new generation
|
# creating new generation
|
||||||
def nextGeneration(currentGen, eliteSize, mutationRate):
|
def nextGeneration(currentGen, eliteSize, mutationRate):
|
||||||
popRanked = rankRoutes(currentGen) # rank routes in current gen
|
popRanked = rankRoutes(currentGen) # rank routes in current gen
|
||||||
@ -179,18 +198,18 @@ def geneticAlgorithm(population, popSize, eliteSize, mutationRate, generations):
|
|||||||
bestRoute = pop[bestRouteIndex]
|
bestRoute = pop[bestRouteIndex]
|
||||||
return bestRoute
|
return bestRoute
|
||||||
|
|
||||||
|
|
||||||
# tutaj ma być lista kordów potencjalnych śmietników z drzewa decyzyjnego
|
# tutaj ma być lista kordów potencjalnych śmietników z drzewa decyzyjnego
|
||||||
|
|
||||||
cityList = []
|
cityList = []
|
||||||
|
|
||||||
|
|
||||||
# for i in range(0,25):
|
# for i in range(0,25):
|
||||||
# cityList.append(City(x=int(random.random() * 200), y=int(random.random() * 200)))
|
# cityList.append(City(x=int(random.random() * 200), y=int(random.random() * 200)))
|
||||||
|
|
||||||
# geneticAlgorithm(population=cityList, popSize=100, eliteSize=20, mutationRate=0.01, generations=1000)
|
# geneticAlgorithm(population=cityList, popSize=100, eliteSize=20, mutationRate=0.01, generations=1000)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# plotting the progress
|
# plotting the progress
|
||||||
|
|
||||||
def geneticAlgorithmPlot(population, popSize, eliteSize, mutationRate, generations):
|
def geneticAlgorithmPlot(population, popSize, eliteSize, mutationRate, generations):
|
||||||
|
BIN
last_map.nparr
BIN
last_map.nparr
Binary file not shown.
1
main.py
1
main.py
@ -166,6 +166,7 @@ class Game():
|
|||||||
|
|
||||||
for i in self.positive_decision:
|
for i in self.positive_decision:
|
||||||
trash_x, trash_y = i.get_coords()
|
trash_x, trash_y = i.get_coords()
|
||||||
|
# city_list.append(TSP.City(x=int(trash_x), y=int(trash_y), array=self.mapArray))
|
||||||
city_list.append(TSP.City(x=int(trash_x), y=int(trash_y)))
|
city_list.append(TSP.City(x=int(trash_x), y=int(trash_y)))
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ from path_search_algorthms import a_star_utils as utils
|
|||||||
|
|
||||||
def get_cost(start_x: int, start_y: int, target_x: int, target_y: int, array):
|
def get_cost(start_x: int, start_y: int, target_x: int, target_y: int, array):
|
||||||
actions = search_path(start_x, start_y, utils.Rotation.NONE, target_x, target_y, array)
|
actions = search_path(start_x, start_y, utils.Rotation.NONE, target_x, target_y, array)
|
||||||
|
if actions is None:
|
||||||
|
return 1
|
||||||
return len(actions)
|
return len(actions)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user