python中的部分列表,索引的麻烦

时间:2016-04-22 18:50:08

标签: python genetic-programming

我对python很新,列表和索引给我带来了一些麻烦。

我想做的是: &#39 ;, 获得两个代表RPN表达的个体,个体1和个体2代表axample:

i1=['3', 'x', '*', '3' ,'4' ,'*', '/']
i2=['x', '4', '/', 'x' ,'4' ,'+', '-']

然后,获取它们的子集并交换子集,如下所示:

来自i1我需要采用子集[' 3' ' 4' ,' *']和i2 [' 4'](最终3)然后做交叉产品两个输出:

out1=['3', 'x', '*','4' , '/']
out2=['x', '3' ,'4' ,'*', '/', 'x' ,'6' ,'+', '-']

我所做的代码就是下面的内容,并且它一直给我错误的结果,就像一次错误一样,我不想进入for循环路线,因为我打赌有更多的pythonesque方式做所以。请问任何一只giceme吗?

def crossover(individual1,individual2,treedepth):
    from commonfunctions import getDepth,traverse,get_random_operator
    from commonfunctions import isOperator
    from generators import generate_RPN_expr
    #simple element mutation
    cxposindividual1 = random.randint(0, len(individual1) - 1)
    cxposindividual2 = random.randint(0, len(individual2) - 1)

    subtree1=traverse(individual1,cxposindividual1)
    subtree2 = traverse(individual2, cxposindividual2)
    individual1depth=getDepth(individual1)
    individual2depth = getDepth(individual2)
    subtree1depth=getDepth(subtree1)
    subtree2depth = getDepth(subtree2)


    output1=list()
    output1[:]=[]

    output2=list()
    output2[:]=[]


    #todo debug this !!!!

    #verificar se ecsolhemos um operador ou um nó terminal
    output1 = individual1[:len(individual1)+1-cxposindividual1-len(subtree1)]+subtree2+individual1[len(individual1)-cxposindividual1+1:]
    output2 = individual2[:len(individual2) + 1 - cxposindividual2 - len(subtree2)] + subtree1 + individual2[len(individual2) - cxposindividual2 + 1:]

    if len(output1) == 2 or len(output2) == 2:
        print('argh>>>') # problema !!!!

    #print ('CX')
    return (output1,output2)

遍历函数返回所选位置的子树。 getDepth还没有被使用。

由于

豪尔赫

新代码

def crossover(individual1,individual2,treedepth):
    from commonfunctions import getDepth,traverse,get_random_operator,traverse_with_indexes
    from commonfunctions import isOperator

    r1 = random.randrange(len(individual1))
    r2 = random.randrange(len(individual2))

    st1 = traverse(individual1, r1)
    st2 = traverse(individual2, r2)

    slice1 = slice(r1, r1+len(st1))
    slice2 = slice(r2, r2+len(st2))


    i1,i2 = individual1[:],individual2[:]
    a,b=i1[slice1],i2[slice2]
    i1[slice1],i2[slice2] = i2[slice2],i1[slice1]

    return i1, i2

此处,个人1等于[' 3.8786681846845'' x',' +']和st1 = [' x' ]切片是2,3,我认为它应该是1,2但...... 个别2 = [' x'] st2 = [' x']切片是0,1哪个很好!!! 我很想制作一些带有大小异常的块,但我不喜欢异常

谢谢

1 个答案:

答案 0 :(得分:2)

我怀疑你的问题来自于python中的切片不包含它们的最终索引。也就是说,[0:1]是一个切片,其中只包含一个元素[0]。

你的例子:

i1=['3', 'x', '*', '3' ,'4' ,'*', '/']
i2=['x', '4', '/', 'x' ,'4' ,'+', '-']
#    0    1    2    3    4    5    6

然后:

temp1 = i1[3:6]   # 3,4,*  
temp2 = i2[1:2]   # 4

然后:

print(i1)
print(i2)

i1[3:6] = temp2
i2[1:2] = temp1

print(i1)
print(i2)

最后,因为太棒了,你可以这样做:

i1[3:6],i2[1:2] = i2[1:2],i1[3:6]

或者这个:

A = slice(3,6)
B = slice(1,2)

i1[A],i2[B] = i2[B],i1[A]

修改

更进一步,您可以使用random.randrange()来避免fencepost错误,并执行以下操作:

def crossover(individual1,individual2,treedepth):

    r1 = random.randrange(len(individual1))
    r2 = random.randrange(len(individual2))

    st1 = traverse(individual1, r1)
    st2 = traverse(individual2, r2)

    slice1 = slice(r1, r1+len(st1))
    slice2 = slice(r2, r2+len(st2))

    # fazer pseudonimos 
    i1,i2 = individual1,individual2
    # o fazer copias
    i1,i2 = individual1[:],individual2[:]

    i1[slice1],i2[slice2] = i2[slice2],i1[slice1]

    return i1, i2

travese功能

这个功能的目的是返回从位置开始开始的有意义的子树(因为程序是一个rpn表示)

def traverse(inputexpr,start):
    from copy import copy,deepcopy
    components=list()
    components[:]=[]
    components=inputexpr[0:len(inputexpr)-start+1]
    components.reverse()
    pos=0
    result=list()
    result[:]=[]
    score=0
    if isOperator(components[pos]):
        result.append(components[pos])
        score=score+getArity(components[pos])
    else:
        result.append(components[pos])
        score=score -1
    pos=pos+1
    while score>0:
        if isOperator(components[pos]):
            result.append(components[pos])
            score = score + getArity(components[pos])-1
        else:
            result.append(components[pos])
            score = score - 1
        pos = pos + 1
    result.reverse()
    return result

第二次修改

考虑这种重新实现。这样做你想要的吗?

_Arity = {op:2 for op in '*/+-%'}

def getArity(op):
    return _Arity[op] if op in _Arity else 0

def isOperator(op):
    return op in _Arity

def traverse(inputexpr, pos):
    """
    Return the meaningful subtree of inputexpr that has its upper node
    at position pos. Given an input like this:

        [ A, B, +, 5, * ]
        # 0  1  2  3  4

    Here are the expected results:

        0:  [ A ]
        1:  [ B ]
        2:  [ A B + ]
        3:  [ 5 ]
        4:  [ A B + 5 * ]

    """
    chop = pos + 1
    subtree = inputexpr[:chop]
    score = 1
    while score:
        chop -= 1
        score += getArity(subtree[chop]) - 1

    return subtree[chop:]

i1=['3', 'x', '*', '3' ,'4' ,'*', '/']
i2=['x', '4', '/', 'x' ,'4' ,'+', '-']

for i in range(len(i1)):
    print("#: {}, subtree= {}".format(i, traverse(i1, i)))

最终按预期工作

#output tree
output1=list()
output1[:]=[]

output2=list()
output2[:]=[]

i1p1 = individual1[:len(individual1) - len(subtree1) - cxposindividual1]
i1p2 = subtree2
i1p3 = individual1[len(i1p1) + len(subtree1):]

i2p1 = individual2[:len(individual2) - len(subtree2) - cxposindividual2]
i2p2 = subtree1
i2p3 = individual2[len(i2p1) + len(subtree2):]


output1=i1p1+i1p2+i1p3
output2=i2p1+i2p2+i2p3

非常感谢奥斯汀,谢谢你,我发现这个错误正在惹恼我的其他错误。 在开始工作之后,我将以更加pythonesque的方式实现它。 现在我使用这个非常详细的代码,所以我不会得到语言细节。

再次感谢