I've been struggling for a long time after writing my A* Search algorithm with the fact that when the number of cities is greater than 8
, the algorithm won't return any answer (or is ridiculously slow).
The cities are stored in a 2-d array where point cityList[x][y]
is the distance between city x
and city y
(it is also the same as cityList[y][x]
).
It's slightly messy as I had to use both the city
class and the beginning of each route to remember route lengths and which routes had already been attempted.
A new route is also created for each city that is added on.
Could anyone help to optimize it or ensure it can work on an increasingly large number of cities.
class city(object):
def __init__(self, number):
self.number = number
global size
self.possibleChildren = []
for i in range(0,size):
if i != number:
self.possibleChildren.append(i)
def getNo(self):
return self.number
def getSize(self):
return len(self.possibleChildren)
def getOptions(self, i):
self.i = i
return self.possibleChildren[self.i]
def deleteNo(self, option):
self.option = option
if(self.option in self.possibleChildren):
self.possibleChildren.remove(self.option)
def addFinalStep(self, beginning):
self.beginning = beginning
self.possibleChildren.append(self.beginning)
def Astar():
routeList = []
#routeList[i][0] = distance travelled, routeList[i][1] = number of cities past
for i in range(0, size):
newRoute = []
newCity = city(i)
newRoute.append(0)
newRoute.append(1)
newRoute.append(newCity)
routeList.append(newRoute)
while True:
toUse = 0
smallest = -2
#Now search through the routeList to find the shortest route length
for i in range(0, len(routeList)):
#getSize() checks if there are any cities that can be visited by
this route that have not already been tried, this list is
stored in the city class
if routeList[i][1 + routeList[i][1]].getSize() != 0:
if routeList[i][0] < smallest or smallest == -2:
smallest = routeList[i][0]
toUse = i
elif routeList[i][1 + routeList[i][1]].getSize() == 0:
routeList.remove(i)
routeRec = []
#Creates the new route
for i in range (0, len(routeList[toUse])):
routeRec.append(routeList[toUse][i])
currentCity = routeRec[1 + routeRec[1]]
possibleChildren = []
for i in range(0, currentCity.getSize()):
possibleChildren.append(currentCity.getOptions(i))
smallest = 0
newCityNo = 2
for i in range(0, size):
if(i in possibleChildren):
#Finds the closest city
if smallest > cityList[currentCity.getNo()][i] or smallest == 0:
newCityNo = i
smallest = cityList[currentCity.getNo()][i]
#If the new city to visit is the same as the first, the algorithm
#has looped to the beginning and finished
if newCityNo == routeRec[2].getNo():
print("Tour Length")
print(routeRec[0] + smallest)
print("Route: ")
for i in range(2,len(routeRec)):
print(routeRec[i].getNo())
return(routeRec[0] + smallest)
#deletes all cities that have been tried
routeList[toUse][1 + routeRec[1]].deleteNo(newCityNo)
nextCity = city(newCityNo)
#deletes all cities that are already in the route
for i in range(2, 2 + routeRec[1]):
nextCity.deleteNo(routeRec[i].getNo())
#When the route is full, it can return to the first city
routeRec[1] = routeRec[1] + 1
print(routeRec[1])
if routeRec[1] == size:
#first city added to potential cities to visit
nextCity.addFinalStep(routeRec[2].getNo())
routeRec.append(nextCity)
routeRec[0] = routeRec[0] + smallest
routeList.append(routeRec)