Advertisement
Guest User

Untitled

a guest
Oct 17th, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.92 KB | None | 0 0
  1. """
  2. Author:
  3. file:
  4. """
  5.  
  6. import random
  7. from Individual import *
  8. import sys
  9. import math
  10. import time
  11.  
  12.  
  13.  
  14. class BasicTSP:
  15. def __init__(self, _fName, _popSize, _mutationRate, _maxIterations):
  16. """
  17. Parameters and general variables
  18. """
  19.  
  20. self.population = []
  21. self.matingPool = []
  22. self.best = None
  23. self.popSize = _popSize
  24. self.genSize = None
  25. self.mutationRate = _mutationRate
  26. self.maxIterations = _maxIterations
  27. self.iteration = 0
  28. self.fName = _fName
  29. self.data = {}
  30.  
  31. self.readInstance()
  32. self.initPopulation()
  33.  
  34.  
  35. def readInstance(self):
  36. """
  37. Reading an instance from fName
  38. """
  39. file = open(self.fName, 'r')
  40. self.genSize = int(file.readline())
  41. self.data = {}
  42. for line in file:
  43. (id, x, y) = line.split()
  44. self.data[int(id)] = (int(x), int(y))
  45. file.close()
  46.  
  47. def initPopulation(self):
  48. """
  49. Creating random individuals in the population
  50. """
  51. for i in range(0, self.popSize):
  52. individual = Individual(self.genSize, self.data)
  53. individual.computeFitness()
  54. self.population.append(individual)
  55.  
  56. self.best = self.population[0].copy()
  57. for ind_i in self.population:
  58. if self.best.getFitness() > ind_i.getFitness():
  59. self.best = ind_i.copy()
  60. print ("Best initial sol: ",self.best.getFitness())
  61.  
  62. def updateBest(self, candidate):
  63. if self.best == None or candidate.getFitness() < self.best.getFitness():
  64. self.best = candidate.copy()
  65. print ("iteration: ",self.iteration, "best: ",self.best.getFitness())
  66.  
  67. def randomSelection(self):
  68. """
  69. Random (uniform) selection of two individuals
  70. """
  71.  
  72. indA = self.matingPool[ random.randint(0, self.popSize-1) ]
  73. indB = self.matingPool[ random.randint(0, self.popSize-1) ]
  74. return [indA, indB]
  75.  
  76. def rouletteWheel(self):
  77. """
  78. Your Roulette Wheel Selection Implementation
  79. """
  80. population_total = 0
  81. #Sum up fitness values of all chromosomes in population:
  82. for sol in self.population:
  83. population_total += 1/sol.getFitness()
  84.  
  85. #Generate a random number between 0 and total of fitness values, where fitness is 1/getFitness()
  86. roulette_number = random.uniform(0,population_total)
  87.  
  88. #Sum up again and select the first one that makes the sum equal or cross our roulette_number
  89. select_total = 0
  90. for sol in self.population:
  91. select_total += 1/sol.getFitness()
  92. if (select_total >= roulette_number):
  93. return sol
  94.  
  95.  
  96. pass
  97.  
  98. def uniformCrossover(self, indA, indB):
  99. """
  100. Your Uniform Crossover Implementation
  101. This function returns one child Individual
  102. """
  103. solutionSize = indA.genSize
  104. child1 = indA.copy()
  105. child2 = indA.copy()
  106. child1.genes =[None] * solutionSize
  107. child2.genes = [None] * solutionSize
  108. keep = []
  109. for i in range(0,solutionSize):
  110. keep.append(bool(random.getrandbits(1)))
  111. for i in range(0,indA.genSize):
  112. if keep[i]:
  113. child1.genes[i] = indA.genes[i]
  114. child2.genes[i] = indB.genes[i]
  115.  
  116. for i in range(0,indA.genSize):
  117. if indA.genes[i] not in child2.genes:
  118. child2.genes[child2.genes.index(None)] = indA.genes[i]
  119. if indB.genes[i] not in child1.genes:
  120. child1.genes[child1.genes.index(None)] = indB.genes[i]
  121. child1.computeFitness()
  122. child2.computeFitness()
  123.  
  124. if child1.getFitness() < child2.getFitness():
  125.  
  126. self.updateBest(child1)
  127. return child1
  128. else:
  129.  
  130. self.updateBest(child2)
  131. return child2
  132.  
  133.  
  134.  
  135. def cycleCrossover(self, indA, indB):
  136. """
  137. Your Cycle Crossover Implementation
  138. This function returns one child Individual
  139. """
  140. #List will be used to tell us that we are in a previously discovered cycle
  141. discovered = []
  142. child1 = indA.copy()
  143. child2 = indA.copy()
  144. child1.genes = [None] * self.genSize
  145. child2.genes = [None] * self.genSize
  146.  
  147. lookup = {}
  148. #Create lookup table for cycles
  149. for i in range(0,self.genSize):
  150. lookup[indA.genes[i]] = indB.genes[i]
  151.  
  152. #Stop when children are full of values that are not None
  153. while (None in child1.genes) & (None in child2.genes):
  154. current_gene = indA.genes[0]
  155. for i in range(0,self.genSize):
  156. current_gene = indA.genes[i]
  157. #Initialise list containing the new cycle
  158. new_discover=[]
  159.  
  160.  
  161. while current_gene not in discovered:
  162. #Add valuies to known cycles
  163. discovered.append(current_gene)
  164.  
  165. #Add values to be iterated over below
  166. new_discover.append(current_gene)
  167.  
  168. #Go to next item in cycle
  169. current_gene = lookup[current_gene]
  170. #On the first iteration, we indA -> child1 and indB -> child2.
  171. if i == 0:
  172. for gene in new_discover:
  173. child1.genes[indA.genes.index(gene)] = gene
  174. child2.genes[indB.genes.index(gene)] = gene
  175.  
  176. #Otherwise indA -> child2
  177. else:
  178. for gene in new_discover:
  179. child1.genes[indB.genes.index(gene)] = gene
  180. child2.genes[indA.genes.index(gene)] = gene
  181.  
  182. child1.computeFitness()
  183. child2.computeFitness()
  184. #Return the better child
  185. if child1.getFitness() < child2.getFitness():
  186. return child1
  187. else:
  188. return child2
  189.  
  190.  
  191. def reciprocalExchangeMutation(self, indA):
  192. """
  193. Your Reciprocal Exchange Mutation implementation
  194. Mutate an individual by swapping two cities with certain probability (i.e., mutation rate)
  195. """
  196. if random.random() > self.mutationRate:
  197. return
  198. indexA = random.randint(0, self.genSize-1)
  199. indexB = random.randint(0, self.genSize-1)
  200.  
  201. tmp = indA.genes[indexA]
  202. indA.genes[indexA] = indA.genes[indexB]
  203. indA.genes[indexB] = tmp
  204.  
  205. indA.computeFitness()
  206. self.updateBest(indA)
  207.  
  208. def scrambleMutation(self, indA):
  209. """
  210. Your Scramble Mutation implementation
  211. """
  212. if random.random() > self.mutationRate:
  213. return
  214. scramble = []
  215. scramble_size = random.randint(2,self.genSize)
  216. scramble_start = random.randint(0,self.genSize - scramble_size)
  217. scramble = indA.genes[scramble_start:scramble_start + scramble_size]
  218. new_scramble = scramble[:]
  219. while new_scramble == scramble:
  220. random.shuffle(new_scramble)
  221.  
  222. indA.genes[scramble_start:scramble_start + scramble_size] = new_scramble
  223.  
  224. indA.computeFitness()
  225. self.updateBest(indA)
  226.  
  227.  
  228. def crossover(self, indA, indB):
  229. """
  230. Executes a 1 order crossover and returns a new individual
  231. """
  232. child = []
  233. tmp = {}
  234.  
  235. indexA = random.randint(0, self.genSize-1)
  236. indexB = random.randint(0, self.genSize-1)
  237.  
  238. for i in range(0, self.genSize):
  239. if i >= min(indexA, indexB) and i <= max(indexA, indexB):
  240. tmp[indA.genes[i]] = False
  241. else:
  242. tmp[indA.genes[i]] = True
  243. aux = []
  244. for i in range(0, self.genSize):
  245. if not tmp[indB.genes[i]]:
  246. child.append(indB.genes[i])
  247. else:
  248. aux.append(indB.genes[i])
  249. child += aux
  250. return child
  251.  
  252. def mutation(self, ind):
  253. """
  254. Mutate an individual by swapping two cities with certain probability (i.e., mutation rate)
  255. """
  256. if random.random() > self.mutationRate:
  257. return
  258. indexA = random.randint(0, self.genSize-1)
  259. indexB = random.randint(0, self.genSize-1)
  260.  
  261. tmp = ind.genes[indexA]
  262. ind.genes[indexA] = ind.genes[indexB]
  263. ind.genes[indexB] = tmp
  264.  
  265. ind.computeFitness()
  266. self.updateBest(ind)
  267.  
  268. def updateMatingPool(self):
  269. """
  270. Updating the mating pool before creating a new generation
  271. """
  272. self.matingPool = []
  273. for i in range(0,self.popSize):
  274. self.matingPool.append( random.choice(self.population) )
  275.  
  276.  
  277.  
  278. def newGeneration(self):
  279. """
  280. Creating a new generation
  281. 1. Selection
  282. 2. Crossover
  283. 3. Mutation
  284. """
  285. self.population =[]
  286. for i in range(0,self.popSize):
  287. """
  288. Depending of your experiment you need to use the most suitable algorithms for:
  289. 1. Select two candidates
  290. 2. Apply Crossover
  291. 3. Apply Mutation
  292. """
  293. indA,indB = self.randomSelection()
  294. newind = self.uniformCrossover(indA,indB)
  295. self.reciprocalExchangeMutation(newind)
  296. self.population.append(newind)
  297.  
  298.  
  299.  
  300. def GAStep(self):
  301. """
  302. One step in the GA main algorithm
  303. 1. Updating mating pool with current population
  304. 2. Creating a new Generation
  305. """
  306.  
  307. self.updateMatingPool()
  308. self.newGeneration()
  309.  
  310. def search(self):
  311. """
  312. General search template.
  313. Iterates for a given number of steps
  314. """
  315. self.iteration = 0
  316. while self.iteration < self.maxIterations:
  317. self.GAStep()
  318. self.iteration += 1
  319.  
  320. print ("Total iterations: ",self.iteration)
  321. print ("Best Solution: ", self.best.getFitness())
  322.  
  323. def config1(self):
  324. self.iteration = 0
  325. while self.iteration < self.maxIterations:
  326. self.GAStep()
  327. print("Iteration:",self.iteration)
  328. self.iteration += 1
  329.  
  330. print ("Total iterations: ",self.iteration)
  331. print ("Best Solution: ", self.best.getFitness())
  332.  
  333.  
  334.  
  335. if len(sys.argv) < 2:
  336. print ("Error - Incorrect input")
  337. print ("Expecting python BasicTSP.py [instance] ")
  338. sys.exit(0)
  339.  
  340.  
  341. problem_file = sys.argv[1]
  342.  
  343. ga = BasicTSP(sys.argv[1], 300, 0.1, 300)
  344.  
  345. ga.config1()
  346. #start_time = time.time()
  347. #print("--- %s seconds ---" % (time.time() - start_time))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement