0

概述:我是 python 的新手,正在 python 中实现本地化算法。执行此代码的机器人首先感知其环境,并将概率分布乘以sensor_right单元格的颜色是否与measurements列表中的颜色匹配。该move函数以 0.8 的成功移动概率将机器人移动到所需位置:

代码 :

colors = [['red', 'green', 'green', 'red' , 'red'],
          ['red', 'red', 'green', 'red', 'red'],
          ['red', 'red', 'green', 'green', 'red'],
          ['red', 'red', 'red', 'red', 'red']]

measurements = ['green', 'green', 'green' ,'green', 'green']


motions = [[0,0],[0,1],[1,0],[1,0],[0,1]]

sensor_right =1

p_move = 0.8

def show(p):
    for i in range(len(p)):
        print p[i]

p = []
sum=0
for i in range(len(colors)):
    for j in range(len(colors[i])):
        sum+=1

p=[[1.0/sum for j in range(len(colors[i]))] for i in range(len(colors))]

def sense(p,z):
    q=[]
    sum=0
    for i in range(len(colors)):
        new=[]
        for j in range(len(colors[i])):
            if (colors[i][j]==z) :
                new.append(p[i][j]*sensor_right)
                sum+=p[i][j]*sensor_right
            else :
                new.append(p[i][j]*(1-sensor_right))
                sum+=p[i][j]*(1-sensor_right)

        q.append(new)
    for i in range(len(q)):
        for j in range(len(q)):
            q[i][j]/=sum

    return q

def move(lst,u=[]):
    q=[]
    if (u[0]!=0) :
        for i in range(len(lst)):
            new=[]
            for j in range(len(lst[i])):
                val=lst[j-u[0]][i]*p_move
                new.append(val)
            q.append(new)



    elif (u[1]!=0) :
        for i in range(len(lst)):
            new=[]
            for j in range(len(lst[i])):
                val=lst[i][j-u[1]]*p_move
                new.append(val)
            q.append(new)

    return q

for i in range(len(measurements)):
    p=sense(p,measurements[i])
    p=move(p,motions[i])


show(p)

问题: 编译器返回以下输出:

in sense new.append(p[i][j]*(1-sensor_right)) IndexError: list index out of range

当我调用该motions方法时,编译器没有抛出错误并显示了正确的输出。奇怪的是,当我检查该motions方法的输出时,它返回的二维列表与在循环中调用该方法时传递给该方法的二维列表具有相同的维度sense。另外,为什么编译器没有抛出错误在

new.append(p[i][j]*sensor_right)
sum+=p[i][j]*sensor_right

如果索引超出范围。

为什么编译器会抛出这个错误?

4

3 回答 3

1

您一直在提到“编译器”。Python 没有编译器。它是一种解释型语言,这意味着它会在找到程序文本时直接执行它。(有一个中间步骤pyc,它是文本的编译版本,但实际上并不相关)。

如果您习惯于编译语言,那么这可能会令人困惑。问题不在于编译器在静态上下文中给你一个错误,而是你的程序实际运行的结果,或者i超出了.pjp[i]

您可以将语法错误(在 Python 运行时加载并尝试解析您的程序时触发)与运行时错误分开,但没有中间步骤。这在哲学上与编译程序不同,因为在运行时程序的一位可以更改变量的值(以及类型)。

要解决您当前的问题,请打印出ij,以及p,您将能够缩小问题发生的范围。

如果执行此操作,您将看到调用 tomove正在返回[],并且 this 被分配回p. 所以下次range循环运行时,sense用 调用p = [],任何索引访问都会抛出一个越界错误。

要解决这个问题,请查看程序的逻辑并确定sense返回[]的原因以及函数尝试p使用无效索引进行索引的原因。

于 2013-09-07T15:59:08.417 回答
1

第一次通过你的for i in range(len(measurements)):p 是一个 5x4 列表,返回的sense()是一个分配给 的 5x4 列表pp然后分配给 的输出,move(p,[0,0])因为两个条件move()都为 falsemove()返回一个空列表。第二次遇到异常,恰好else:sense().

于 2013-09-07T16:29:08.430 回答
0

如果您要使用这种矩阵操作,我建议您看看numpy 。我已经重写了您的部分代码,以便您可以比较并了解它的运行方式:

import numpy as np

colors = np.array([['red', 'green', 'green', 'red' , 'red'],
                   ['red', 'red', 'green', 'red', 'red'],
                   ['red', 'red', 'green', 'green', 'red'],
                   ['red', 'red', 'red', 'red', 'red']])

sensor_right = 1
p = np.ones_like(colors, dtype=np.float) / colors.size

def sense(p, z):
    condition = colors == z
    p[condition] *= sensor_right
    p[~condition] *= 1 - sensor_right
    return p / p.sum()
于 2013-09-07T16:44:17.110 回答