python派森知多少_派森吧 - pythonpub.com | 享受python带来的便利以及快乐

硕士毕业论文的时候使用了遗传算法,所以研究了一段时间,曾经用Python写一个简单的遗传算法,好自己拿来实验。整个代码还是仿照《游戏编程中的人工智能技术》中的代码来写的。如果想简单的学习一下遗传算法以及简单应用《游戏编程中的人工智能技术》是不错的选择。代码如下面所附。

我写了一个简单的测试函数main

运行后多数情况下会产生如下输出

-----------------

Function: y = 0 - 2 * x * x + 12 * x + 5

The best genome is: [0, 0, 1, 1]

The variable is: 3

The max value is 23

-----------------

Function: y = 0 - 2 * x * x + 8 * x + 4

The best genome is: [0, 0, 1, 0]

The variable is: 2

The max value is 12

-----------------

以y = 0 - 2 * x * x + 8 * x + 4为例,在Matlab中画出该函数的曲线的时候,可以看到该函数的极值点确实在x = 2处,证明算法还是相当成功的。

因为写的测试算法主要针对求函数的极大值,如果是求函数极小值可以乘上-1就OK了。

其实上边的函数,乘上-1,然后求导也可以知道极值为x=8/4=2,这是极小值,乘上-1就得极大值了。

算是初步改写成功了,当然还有很多问题,比如选择时用的轮盘赌,但是AI的书上的算法似乎有点问题,另外似乎变异操作也有点问题,变异我现在只是变异一处,而原书上则是每一处都根据变异率来进行变异。

种群要设置的稍微大点,太小了没效果。变异率也要大一点。

另外,测试函数里的解空间比较小,还有就是终止条件目前仅判断代数是否超过了设置的最大代数,我想还应该在判断适应性分数最高的地方设置终止条件。这样就避免了多余的运算

[code lang="python"]

# -*- coding:utf-8 -*-

# file: GA.py

# date: 2011-10-22

# note:

import random

class genome:

def __init__(self, length = 0):

self.fitness = 0

self.bits = []

for i in range(length):

self.bits.append(random.randint(0, 1))

class ga:

def __init__(self,

pop_size,

genome_len,

expr = 'y = 0 - 2 * x * x + 8 * x + 4',

crossover_rate = 0.7,

mutation_rate = 0.01,

max_generation = 1000

):

self.crossover_rate = crossover_rate

self.mutation_rate = mutation_rate

self.pop_size = pop_size

self.genome_len = genome_len

self.generation = 0

self.genomes = []

self.busy = False

self.fittest_genome = genome()

self.best_fitness_score = 0

self.total_fitness_score = 0

self.expr = expr

self.max_generation = max_generation

def create_start_populations(self):

del self.genomes[0:]

for i in range(self.pop_size):

self.genomes.append(genome(self.genome_len))

self.generation = 0

self.best_fitness_score = 0

self.total_fitness_score = 0

def selection(self):

f_slice = random.uniform(0, 1) * self.total_fitness_score

c_f_slice = 0.0

selected_genome = 0

for i in range(self.pop_size):

c_f_slice = c_f_slice + self.genomes[i].fitness

if c_f_slice > f_slice:

selected_genome = i

break

return self.genomes[i]

def crossover(self, mum, dad):

baby1 = []

baby2 = []

if (random.uniform(0, 1) > self.crossover_rate):

baby1 = mum.bits;

baby2 = dad.bits;

return baby1, baby2

cp = random.randint(0, self.genome_len - 1)

for i in range(cp):

baby1.append(mum.bits[i])

baby2.append(dad.bits[i])

for i in range(cp, self.genome_len):

baby1.append(dad.bits[i])

baby2.append(mum.bits[i])

return baby1, baby2

def mutate(self, bits):

if (random.uniform(0, 1) < self.mutation_rate):

mp = random.randint(0, self.genome_len - 1)

bits[mp] = int(not bits[mp])

def decode(self, gen):

x = self.bin2int(gen)

exec(self.expr)

return y

def bin2int(self, lists):

m = 1

r = 0

lists.reverse()

for i in range(len(lists)):

r = r + m * lists[i]

m = m * 2

lists.reverse()

return r

def update_fitness_scores(self):

self.total_fitness_score = 0

for i in range(self.pop_size):

self.genomes[i].fitness = self.decode(self.genomes[i].bits)

self.total_fitness_score += self.genomes[i].fitness

if self.genomes[i].fitness > self.best_fitness_score:

self.best_fitness_score = self.genomes[i].fitness

self.fittest_genome = self.genomes[i]

def epoch(self):

self.update_fitness_scores()

new_babies = 0

baby_genomes = []

baby1 = genome()

baby2 = genome()

while (new_babies < self.pop_size):

mum = self.selection()

dad = self.selection()

baby1.bits, baby2.bits = self.crossover(mum, dad)

self.mutate(baby1.bits)

self.mutate(baby2.bits)

baby_genomes.append(baby1)

baby_genomes.append(baby2)

new_babies = new_babies + 2

self.genomes = baby_genomes

self.generation += 1

if self.generation >= self.max_generation:

self.busy = False

def start(self):

self.busy = True

self.create_start_populations()

def get_best_genome(self):

return self.fittest_genome.bits

def get_best_variable(self):

return self.bin2int(self.fittest_genome.bits)

def get_max_value(self):

return self.decode(self.fittest_genome.bits)

def main():

print "-----------------"

testga = ga(pop_size = 8, genome_len = 4, expr = 'y = 0 - 2 * x * x + 12 * x + 5')

testga.start()

while testga.busy:

testga.epoch()

print "Function: %s" % testga.expr

print "The best genome is: ",

print testga.get_best_genome()

print "The variable is: %d" % testga.get_best_variable()

print "The max value is %d" % testga.get_max_value()

del testga

print "-----------------"

testga = ga(pop_size = 8, genome_len = 4)

testga.start()

while testga.busy:

testga.epoch()

print "Function: %s" % testga.expr

print "The best genome is: ",

print testga.get_best_genome()

print "The variable is: %d" % testga.get_best_variable()

print "The max value is %d" % testga.get_max_value()

print "-----------------"

if __name__ == '__main__':

main()

[/code]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值