我对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哪个很好!!! 我很想制作一些带有大小异常的块,但我不喜欢异常
谢谢
答案 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
这个功能的目的是返回从位置开始开始的有意义的子树(因为程序是一个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的方式实现它。 现在我使用这个非常详细的代码,所以我不会得到语言细节。
再次感谢