def test_Genetic_SelectionVals(self): ''' Testing that all the values are as expected, a percentage of their value vs the total value, and that they are in increasing order ''' selectVals = RouteCalc.Wrap_CalcRelativeFitness(self.Population) self.assertEqual(self.Pop_Size, len(selectVals)) selectMult = RouteCalc.GetSelectionMult() lastVal = selectMult * self.Pop_Size self.assertAlmostEqual(lastVal, selectVals[-1]) popSum = sum([route.Fitness for route in self.Population]) firstVal = self.Population[0].Fitness / popSum * lastVal self.assertEqual(firstVal, selectVals[0]) for i in range(500): with self.subTest(i=i): index = random.randrange(1, self.Pop_Size - 1) randSelectVal = selectVals[index] randRoute = self.Population[index] sumToIndex = sum( [route.Fitness for route in self.Population[:index + 1]]) calcVal = (sumToIndex / popSum) * lastVal self.assertAlmostEqual(calcVal, randSelectVal) self.assertListEqual(selectVals, sorted(selectVals))
def test_Genetic_StartBadRoutelength(self): #Assert passing a route length 3 or over 15 raises exception for fittype.EvenSplit for routeLen in range(3): with self.subTest(routeLen=routeLen): with self.assertRaises(Exception): RouteCalc.StartGeneticSolver(self.Pop_Size, self.All_Systems, routeLen, True, FitnessType.EvenSplit) for routeLen in range(16, 19): with self.subTest(routeLen=routeLen): with self.assertRaises(Exception): RouteCalc.StartGeneticSolver(self.Pop_Size, self.All_Systems, routeLen, True, FitnessType.EvenSplit) #FirstOver should throw exception on routes under len 6 and over 35 for routeLen in range(6): with self.subTest(routeLen=routeLen): with self.assertRaises(Exception): RouteCalc.StartGeneticSolver(self.Pop_Size, self.All_Systems, routeLen, True, FitnessType.FirstOver) for routeLen in range(36, 39): with self.subTest(routeLen=routeLen): with self.assertRaises(Exception): RouteCalc.StartGeneticSolver(self.Pop_Size, self.All_Systems, routeLen, True, FitnessType.FirstOver)
def test_Genetic_MutateSpecial(self): ''' Test the special case where number of valid systems is equal to route length ''' tempValidSystems = self.All_Systems[:self.Route_Length] RouteCalc.SetValidSystems(tempValidSystems) systemLists = routecalc.GenerateSystemLists(self.Pop_Size, self.Route_Length, tempValidSystems) for systemList in systemLists: with self.subTest(systemList=systemList): mutatedList = RouteCalc.Wrap_Mutate(systemList) self.failIfEqual(systemList, mutatedList)
def test_Genetic_Reproduce(self): ''' Test that children generated by the reproduce function are not the same. ''' #TODO: Will still fail sometimes if reproduce function shuffles the same way twice selectVals = RouteCalc.Wrap_CalcRelativeFitness(self.Population) for reproNum in range(self.Pop_Size): with self.subTest(reproNum=reproNum): children = RouteCalc.Wrap_Reproduce(self.Population, selectVals) self.assertEqual(len(children), 2, "RouteCalc.Repro must create 2 children") self.failIfEqual(children[0], children[1], "Generated children must be different")
def CheckPerformance(cls, systemsList: list, fitType: FitnessType): maxTests = 10 minPopSize = 300 maxPopSize = 300 popSizeStep = 50 popSizes = range(minPopSize, maxPopSize + 1, popSizeStep) minLength = 8 maxLength = 8 lengths = range(minLength, maxLength + 1, 1) print("\nFitness Type: {0}".format(fitType.name)) for routeLength in lengths: for popSize in popSizes: stats = PerformanceMetrics(routeLength, popSize) for testNum in range(maxTests): solved = False startTime = time.time() bestRoute, numGenerations = RouteCalc.StartGeneticSolver( systemsList, routeLength, True, fitType) endTime = time.time() elapsed = endTime - startTime if bestRoute.Fitness >= RouteCalc.Route_Cutoff: stats.Types.append(bestRoute.Route_Type) stats.Values.append(bestRoute.Fitness) solved = True stats.Times.append(elapsed) stats.Solved.append(solved) stats.Gens.append(numGenerations) print(stats)
def __RunGenetic(systems: list, routeLength: int, fitType: FitnessType, silent: bool, stopShort: bool): exitTestLoop = False runNum = 0 maxRuns = 5 geneticStart = time.time() bestRoute = None while not exitTestLoop and runNum < maxRuns: runNum += 1 print("Run: {0}".format(runNum)) bestRoute, numGenerations = RouteCalc.StartGeneticSolver( systems, routeLength, silent, fitType) geneticEnd = time.time() if bestRoute.Fitness >= RouteCalc.Route_Cutoff or stopShort: exitTestLoop = True if bestRoute.Fitness < RouteCalc.Route_Cutoff: print("No good route found") print(bestRoute) bestRoute.DisplayInConsole() print("Generations: {0}".format(numGenerations)) print("Time since start: {0:.5f}s".format((geneticEnd - geneticStart))) bestRoute.DrawRoute() #Eventually take this out once im satisfied with hold times for k, v in bestRoute.Hold_Times.items(): print(k.System_Name, " -> ", v)
def test_Genetic_StartBadArgs(self): #Assert empty system list raises exception with self.assertRaises(Exception): RouteCalc.StartGeneticSolver(500, [], 20, True, self.Fit_Type) #Assert passing a pop size under 3 raises exception for popSize in range(3): with self.subTest(popSize=popSize): with self.assertRaises(Exception): RouteCalc.StartGeneticSolver(popSize, self.All_Systems, 6, True, self.Fit_Type) #Assert fail if there are more systems in the route than in the list of valid systems with self.assertRaises(Exception): RouteCalc.StartGeneticSolver( 200, self.All_Systems[:self.Route_Length - 1], self.Route_Length, True, self.Fit_Type)
def test_Genetic_Mutate(self): ''' General test to make sure mutate will never return the same system list that we pass to it ''' systemLists = routecalc.GenerateSystemLists(self.Pop_Size, self.Route_Length, self.All_Systems) for systemList in systemLists: with self.subTest(systemList=systemList): mutatedList = RouteCalc.Wrap_Mutate(systemList) self.failIfEqual(systemList, mutatedList)
def setUp(self): self.Pop_Size = 300 self.Route_Length = 8 self.Fit_Type = FitnessType.FirstOver RouteCalc.SetValidSystems(self.All_Systems) self.Population = [ EDRareRoute(systems, self.Fit_Type) for systems in routecalc.GenerateSystemLists( self.Pop_Size, self.Route_Length, self.All_Systems) ]
def test_Genetic_StartNoArgs(self): RouteCalc.StartGeneticSolver()