美文网首页
用Python实现遗传算法(GA)-(二)-One Max Pr

用Python实现遗传算法(GA)-(二)-One Max Pr

作者: Yuri7 | 来源:发表于2019-10-31 17:21 被阅读0次

    第二个项目是最大化问题,依旧沿用(一)的engine,这里的geneSet是0-1组合,即geneset = [0, 1]。本章节一共涉及三个py文件

    1. genetic.py

    import random
    import statistics
    import sys
    import time
    
    def _generate_parent(length, geneSet, get_fitness):
        genes = []
        while len(genes) < length:
            sampleSize = min(length - len(genes), len(geneSet))
            genes.extend(random.sample(geneSet, sampleSize))
        fitness = get_fitness(genes)
        return Chromosome(genes, fitness)
    

    因为要求最大化数字,所以不再适合用string编码,所以直接用复制,即childGenes = parent.Genes[:],取代list constructure

    def _mutate(parent, geneSet, get_fitness):
        childGenes = parent.Genes[:]
        index = random.randrange(0, len(parent.Genes))
        newGene, alternate = random.sample(geneSet, 2)
        childGenes[index] = alternate if newGene == childGenes[index] else newGene
        fitness = get_fitness(childGenes)
        return Chromosome(childGenes, fitness)
    
    def get_best(get_fitness, targetLen, optimalFitness, geneSet, display):
        random.seed()
        bestParent = _generate_parent(targetLen, geneSet, get_fitness)
        display(bestParent)
        if bestParent.Fitness >= optimalFitness:
            return bestParent
        while True:
            child = _mutate(bestParent, geneSet, get_fitness)
            if bestParent.Fitness >= child.Fitness:
                continue
            display(child)
            if child.Fitness >= optimalFitness:
                return child
            bestParent = child
    
    class Chromosome:
        def __init__(self, genes, fitness):
            self.Genes = genes
            self.Fitness = fitness
    
    class Benchmark:
        @staticmethod
        def run(function):
            timings = []
            stdout = sys.stdout
            for i in range(100):
                sys.stdout = None
                startTime = time.time()
                function()
                seconds = time.time() - startTime
                sys.stdout = stdout
                timings.append(seconds)
                mean = statistics.mean(timings)
                if i < 10 or i % 10 == 9:
                    print("{} {:3.2f} {:3.2f}".format(
                        1 + i, mean,
                        statistics.stdev(timings, mean) if i > 1 else 0))
    

    2. guessPasswordTests.py

    import datetime
    import random
    import unittest
    import genetic
    
    def get_fitness(guess, target):
        return sum(1 for expected, actual in zip(target, guess)
                   if expected == actual)
    
    
    def display(candidate, startTime):
        timeDiff = datetime.datetime.now() - startTime
        print("{}\t{}\t{}".format(
            ''.join(candidate.Genes),
            candidate.Fitness,
            timeDiff))
    

    在display里面要重组基因成string

    class GuessPasswordTests(unittest.TestCase):
        geneset = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!.,"
    
        def test_Hello_World(self):
            target = "Hello World!"
            self.guess_password(target)
    
        def test_For_I_am_fearfully_and_wonderfully_made(self):
            target = "For I am fearfully and wonderfully made."
            self.guess_password(target)
    
        def guess_password(self, target):
            startTime = datetime.datetime.now()
    
            def fnGetFitness(genes):
                return get_fitness(genes, target)
    
            def fnDisplay(candidate):
                display(candidate, startTime)
    
            optimalFitness = len(target)
            best = genetic.get_best(fnGetFitness, len(target), optimalFitness,
                                    self.geneset, fnDisplay)
            self.assertEqual(''.join(best.Genes), target)
    
        def test_Random(self):
            length = 150
            target = ''.join(random.choice(self.geneset)
                             for _ in range(length))
    
            self.guess_password(target)
    
        def test_benchmark(self):
            genetic.Benchmark.run(self.test_Random)
    
    
    if __name__ == '__main__':
        unittest.main()
    

    3. oneMaxTest.py

    import datetime
    import unittest
    import genetic
    
    
    def get_fitness(genes):
        return genes.count(1)
    
    
    def display(candidate, startTime):
        timeDiff = datetime.datetime.now() - startTime
        print("{}...{}\t{:3.2f}\t{}".format(
            ''.join(map(str, candidate.Genes[:15])),
            ''.join(map(str, candidate.Genes[-15:])),
            candidate.Fitness,
            timeDiff))
    
    
    class OneMaxTests(unittest.TestCase):
        def test(self, length=100):
            geneset = [0, 1]
            startTime = datetime.datetime.now()
    
            def fnDisplay(candidate):
                display(candidate, startTime)
    
            def fnGetFitness(genes):
                return get_fitness(genes)
    
            optimalFitness = length
            best = genetic.get_best(fnGetFitness, length, optimalFitness,
                                    geneset, fnDisplay)
            self.assertEqual(best.Fitness, optimalFitness)
    
        def test_benchmark(self):
            genetic.Benchmark.run(lambda: self.test(4000))
    
    
    if __name__ == '__main__':
        unittest.main()
    

    相关文章

      网友评论

          本文标题:用Python实现遗传算法(GA)-(二)-One Max Pr

          本文链接:https://www.haomeiwen.com/subject/dxetbctx.html