Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1782911
  • 博文数量: 297
  • 博客积分: 285
  • 博客等级: 二等列兵
  • 技术积分: 3006
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-06 22:04
个人简介

Linuxer, ex IBMer. GNU https://hmchzb19.github.io/

文章分类

全部博文(297)

文章存档

2020年(11)

2019年(15)

2018年(43)

2017年(79)

2016年(79)

2015年(58)

2014年(1)

2013年(8)

2012年(3)

分类: Python/Ruby

2016-10-23 20:11:45

此书我才看了没几页。但是其中的代码实在是精妙,不由顿生不明觉厉的感慨。
最早的版本是数据和算法混合在一起的代码:

点击(此处)折叠或打开

  1. import string
  2. import random

  3. geneSet=string.ascii_letters+" !?.,"
  4. target="Hello World!"

  5. def generate_parent(length):
  6.     genes=[]
  7.     while len(genes) < length:
  8.         sampleSize=min((length - len(genes)), len(geneSet))
  9.         genes.extend(random.sample(geneSet, sampleSize))
  10.     return ''.join(genes)


  11. #print(generate_parent(10))

  12. def get_fitness(guess):
  13.     return sum(1 for expected, actual in zip(target, guess) if expected == actual)

  14. def mutate(parent):
  15.     index=random.randrange(0,len(parent))
  16.     childGenes=list(parent)
  17.     newGene, alternate=random.sample(geneSet, 2)
  18.     childGenes[index]=alternate if newGene ==childGenes[index] else newGene
  19.     return ''.join(childGenes)


  20. import datetime

  21. def display(guess):
  22.     timeDiff=datetime.datetime.now() - startTime
  23.     fitness=get_fitness(guess)
  24.     print("{0}\t{1}\t{2}".format(guess, fitness, str(timeDiff)))


  25. random.seed()
  26. startTime=datetime.datetime.now()
  27. bestParent=generate_parent(len(target))
  28. bestFitness=get_fitness(bestParent)
  29. display(bestParent)

  30. while True:
  31.     child=mutate(bestParent)
  32.     childFitness=get_fitness(child)
  33.     if bestFitness >= childFitness:
  34.         continue
  35.     display(child)
  36.     if childFitness >= len(bestParent):
  37.         break
  38.     bestFitness=childFitness
  39.     bestParent=child

然后第二个版本是讲算法单独抽出来做了个genetic.py.
将实际的应用写入guesspassword.py

genetic.py 如下:

点击(此处)折叠或打开

  1. import random

  2. def _generate_parent(length, geneSet):
  3.     genes=[]
  4.     while len(genes) < length:
  5.         sampleSize=min(length-len(genes), len(geneSet))
  6.         genes.extend(random.sample(geneSet, sampleSize))
  7.     return ''.join(genes)

  8. def _mutate(parent, geneSet):
  9.     index=random.randrange(0, len(parent))
  10.     childGenes=list(parent)
  11.     newGene, alternate=random.sample(geneSet, 2)
  12.     if newGene==childGenes[index]:
  13.         childGenes[index]=alternate
  14.     else:
  15.         childGenes[index]=newGene

  16.     return ''.join(childGenes)


  17. def get_best(get_fitness, targetLen, optimalFitness, geneSet, display):
  18.     random.seed()
  19.     bestParent=_generate_parent(targetLen, geneSet)
  20.     bestFitness=get_fitness(bestParent)
  21.     display(bestParent)

  22.     if bestFitness >= optimalFitness:
  23.         return bestParent

  24.     while True:
  25.         child=_mutate(bestParent, geneSet)
  26.         childFitness = get_fitness(child)
  27.         if bestFitness >= childFitness:
  28.             continue

  29.         display(child)
  30.         if childFitness >= optimalFitness:
  31.             return child
  32.         bestFitness = childFitness
  33.         bestParent=child
guesspassword.py 内容如下:

点击(此处)折叠或打开

  1. import datetime
  2. import genetic
  3. import string
  4. import unittest

  5. def test_hello_world():
  6.     target="Hello World!"
  7.     guess_password(target)

  8. def guess_password(target):
  9.     geneset=string.ascii_letters+" !?.,"
  10.     startTime=datetime.datetime.now()

  11.     def fnGetFitness(genes):
  12.         return get_fitness(genes,target)

  13.     def fnDisplay(genes):
  14.         display(genes, target, startTime)

  15.     optimalFitness=len(target)
  16.     genetic.get_best(fnGetFitness, len(target), optimalFitness, geneset, fnDisplay)

  17. def display(genes, target, startTime):
  18.     timeDiff=datetime.datetime.now() - startTime
  19.     fitness= get_fitness(genes, target)
  20.     print("{0}\t{1}\t{2}".format(genes, fitness, str(timeDiff)))

  21. def get_fitness(genes, target):
  22.     return sum( 1 for expected, actual in zip(target, genes) if expected==actual)


  23. #test_hello_world()


  24.     def fnDisplay(genes):
  25.         display(genes, target, startTime)

  26. class GuessPasswordTests(unittest.TestCase):
  27.     geneset=string.ascii_letters+" !?,."
  28.     startTime=datetime.datetime.now()
  29.     
  30.     def test_001_hello_world(self):
  31.         target="Hello World!"
  32.         self.guess_password(target)

  33.     def guess_password(self, target):
  34.         def fnGetFitness(genes):
  35.             return get_fitness(genes,target)

  36.         def fnDisplay(genes):
  37.             display(genes, target, self.startTime)
  38.         
  39.         optimalFitness=len(target)
  40.         best=genetic.get_best(fnGetFitness, len(target), optimalFitness, self.geneset, fnDisplay)
  41.         self.assertEqual(best, target)


  42.     def test_002_for_i_am_fearfully_and_wonderfully_made(self):
  43.         target="For I am fearfully and wonderfully made."
  44.         self.guess_password(target)

  45. unittest.main()
后记:

因为书上用了statistics 这个library,害得我在kali 上找了半天,不知道为啥官方源把我定向到kali.mirror.garr.it,超级慢,apt-get update 要跑3天。
还是改了好。 

点击(此处)折叠或打开

  1. #中科大kali source
  2. deb http://mirrors.ustc.edu.cn/kali kali-rolling main contrib non-free
  3. deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main contrib non-free
瞎猜一通,感觉astlib 像是,最后还给我蒙对了

点击(此处)折叠或打开

  1. apt-cache search statistics |grep -i python3
  2. apt-get install astlib

点击(此处)折叠或打开

  1. >>> import statistics
  2. >>> statistics.__file__
  3. '/usr/lib/python3.5/statistics.py'
  4. >>> statistics.__name__
  5. 'statistics'
阅读(1971) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~