遺傳算法示例

今晚簡單研究下遺傳算法,學習的是一個求N個數,使之加起來剛好爲X的例子,比較簡明易懂,python實現起來也很方便。python

幾個基礎的概念:算法

個體individual,它有本身的生存力,也就是適應力,強弱就是與咱們的目標的差距數組

種羣population,個體的集合,生存力不一樣,有強有弱app

適應力fitness,針對個體而言,越小越好,看它與目標的差距dom

評分grade,針對種羣而言,一樣越小越好,定義了全部個體與目標差距的平均值學習

進化evolve,核心部分,生物的物競天擇適者生存過程,不斷淘汰種羣中的弱者,留下強者,並從強者中選擇2個做爲父母繁衍後代,後代有父母的基因,同時產生的過程當中有機率發生變異,也能夠選擇讓父母產生變異,從結果上看效果是同樣的。spa

下面的例子中,設定目標值371,種羣中個體數100,每一個個體由6個數組成,在0到100之間,每次進化留下的優良個體比例20%,不良個體被留下的機率爲5%(這個能夠不要,留下會表現有遺傳的多樣性),留下的個體中,變異機率1%。進化前會對種羣中個體的適應力排序,選擇必定比例的留下,而後讓其中的每一個按機率發生變異,結果做爲父母,繁衍後代,直到個體總量達到規定值。這裏,咱們預先知道咱們的目標值,所以發現有個體徹底適應時就能夠中止進化了,而有些問題並不能準確知道這個值,所以能夠將結果不斷的保留,最後取一個最值做爲咱們的結果,獲得原問題的近似最優解。code

 1 # -*- coding:gbk -*-
 2 import random, operator
 3 
 4 def individual(length, min, max):
 5     return [random.randint(min, max) for x in xrange(length)]
 6 
 7 def population(count, length, min, max):
 8     return [individual(length, min, max) for x in xrange(count)]
 9 
10 def fitness(individual, target):
11     sum = reduce(operator.add, individual, 0)
12     return abs(target - sum)
13 
14 def grade(pop, target):
15     summed = reduce(operator.add, (fitness(x, target) for x in pop))
16     return summed / (len(pop) * 1.0)
17 
18 def evolve(pop, target, retain = 0.2, random_select = 0.05, mutate = 0.01):
19     graded = [(fitness(x, target), x) for x in pop]
20     graded = [x[1] for x in sorted(graded)]
21     retain_length = int(len(graded) * retain)
22     parents = graded[:retain_length]
23     for individual in graded[retain_length:]:
24         if random_select > random.random():
25             parents.append(individual)
26         
27     for individual in parents:
28         if mutate > random.random():
29             pos_to_mutate = random.randint(0, len(individual) - 1)
30             individual[pos_to_mutate] = random.randint(min(individual), max(individual))
31     parents_length = len(parents)
32     desired_length = len(pop) - parents_length
33     children = []
34     while len(children) < desired_length:
35         male = random.randint(0, parents_length - 1)
36         female = random.randint(0, parents_length - 1)
37         if male != female:
38             male = parents[male]
39             female = parents[female]
40             half = len(male) / 2
41             child = male[:half] + female[half:]
42             children.append(child)
43     parents.extend(children)
44     return parents
45 
46 
47 target = 371
48 p_count = 100
49 i_length = 6
50 i_min = 0
51 i_max = 100
52 
53 p = population(p_count, i_length, i_min, i_max)
54 fitness_history = [grade(p, target),]
55 for i in xrange(200):
56     p = evolve(p, target)
57     g = grade(p, target)
58     fitness_history.append(g)
59     if g == 0:
60         break
61 
62 for datum in fitness_history:
63     print datum
64     
65 individual = p[len(p) - 1]
66 print 'individual is'
67 sum  = 0
68 for n in individual:
69     sum += n
70     print n
71 print 'total=%d,target=%d,evolve=%d'%(len(fitness_history), target, sum)
相關文章
相關標籤/搜索