2014-02-25 42 views
2

我正在使用GA并需要修改基因组。我已经将基因组中的最小值设置为表示随机过程的“标志”。所以,当函数在包含范围[0,8]中输入输入时,GA只会选择值[4,8]。任何“4”的实例都需要用另一个列表中的[0,4]替换。将列表中的项目替换为另一个列表中的相应项目(Python)

我目前做到这一点使用下面的代码:

#------------------------------------------------------------------------------- 
def modify_chromosome(chromosome): 
    # If value == replace option, replace from another list 
    for (index,value) in enumerate(chromosome): 
     # Note "<=" necessary in case GA mutates the values 
     if value <= flag_option: 
      chromosome[index] = changed_value[index] 
    # This changes the actual chromosome in the GA 
    return chromosome 

凡changed_value列表被预先确定为

changed_value = random.randint(0,flag_option,len(num_entries)) 

上面的代码工作正常,但通过列表迭代这样很耗时(总体运行时间的10%在此功能中)。

我的问题: 是否有更高效的方法来实现上述代码块?

在此先感谢。

+1

无论你做什么,你将不得不迭代? –

+5

关于改进工作代码的问题更适合[codereview.se]。 –

+4

此问题属于Stack Exchange网络中的其他站点:http://codereview.stackexchange.com – zmo

回答

0

您可以做的最好的方法是使用izip迭代这两个列表,以便每次运行enumerate(chromosome)命令时都不会创建index列表。

from itertools import izip 

changed_value = random.randint(0,flag_option,len(num_entries)) 
chromosome = [c if c <= flag_option else v 
       for c, v in izip(chromosome, changed_value)] 

编辑:所以我下使用下面的脚本一些基准测试:

from itertools import izip 
import random 
import timeit 

def test_setup(n, flag_option=4): 
    setup = 'from itertools import izip\nfrom random import randint\n' 
    setup += 'flag_option = {}\n'.format(flag_option) 
    setup += 'changed_val = [randint(0, flag_option) for _ in xrange({})]\n'.format(n) 
    setup += 'chromosome = [randint(0, 8) for _ in xrange({})]\n'.format(n) 
    return setup 

test_izip = '[v if c <= flag_option else c ' 
test_izip += 'for c, v in izip(chromosome, changed_val)]' 

test_zip = '[v if c <= flag_option else c ' 
test_zip += 'for c, v in zip(chromosome, changed_val)]' 

test_enum = '[changed_val[i] if c <= flag_option else c ' 
test_enum += 'for i,c in enumerate(chromosome)]' 

test_orig = 'for (i,c) in enumerate(chromosome):\n' 
test_orig += '\tif c <= flag_option:\n' 
test_orig += '\t\tchromosome[i] = changed_val[i]' 

if '__main__' == __name__: 
    for n in [10 ** i for i in xrange(7)]:  
     print 'izip {}: '.format(n), 
     print min(timeit.Timer(test_izip, setup=test_setup(n)).repeat(7, 1000)) 

     print 'zip {}: '.format(n), 
     print min(timeit.Timer(test_zip, setup=test_setup(n)).repeat(7, 1000)) 

     print 'enum {}: '.format(n), 
     print min(timeit.Timer(test_enum, setup=test_setup(n)).repeat(7, 1000)) 

     print 'orig {}: '.format(n), 
     print min(timeit.Timer(test_orig, setup=test_setup(n)).repeat(7, 1000)) 

     print 

结果如下:

izip 10: 0.00132203102112 
zip 10: 0.00159502029419 
enum 10: 0.00130820274353 
orig 10: 0.000921964645386 

izip 100: 0.00951504707336 
zip 100: 0.01145195961 
enum 100: 0.00957798957825 
orig 100: 0.00854301452637 

izip 1000: 0.0860891342163 
zip 1000: 0.109489917755 
enum 1000: 0.0958349704742 
orig 1000: 0.0862739086151 

izip 10000: 0.922410964966 
zip 10000: 1.31961488724 
enum 10000: 1.00453591347 
orig 10000: 0.93142914772 

izip 100000: 9.61347794533 
zip 100000: 18.9829239845 
enum 100000: 10.6979219913 
orig 100000: 9.5124809742 

izip 1000000: 100.970448971 
zip 1000000: 211.297281027 
enum 1000000: 122.404583931 
orig 1000000: 94.8837227821 

所以一切之后,它看起来像你的原始代码将是最快的。

+0

我不想生成每个通过的randint,因为这会产生不同的功能结果。 /// 有一个机会我会替换相同的值,是的(例如3 => 3)。然而,由于GA会偶尔“改变”输入,所以我不想让2 => 3。 /// 输入代表“行动”,其中5-8是“积极行动”,而“4”代表“没有行动”。我用“随机不良事件”(4个选项)取代“不采取行动”。我希望“坏事件”对于优化过程是恒定的,但是在每个位置都是随机的,因此就是changed_value列表。 – planetes42

+0

如果在第一种情况下提前生成该条件,该条件如何保证?你可以使用'random.randint(c,flag_option)'来代替吗? – cdhagmann

+0

我不明白你的问题。我的意图是确保在选择_no action_时每个位置都会出现相同的_bad event_。通过用随机生成的数字替换染色体“c”中的条目,每次迭代将具有不同的_bad event_替换值。通过预先生成'changed_value'列表,我确保通过〜10K迭代,每次选择_no action_时,在该节点处发生相同的_bad event_。 – planetes42

相关问题