首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Python表示图灵机的无限磁带最有效的方法是什么?

用Python表示图灵机的无限磁带最有效的方法是什么?
EN

Stack Overflow用户
提问于 2017-03-30 06:43:46
回答 1查看 401关注 0票数 1

图灵机根据规则表在无限带的上操纵符号。

在我的例子中,磁带上的条目可以是0和1(二进制)。

磁带从“空”开始,在正方向和负方向上的无穷大都是0。该磁带是根据机器遵循的规则编写的,可能会将0或1添加到未写入的边缘。

由于磁带值是二进制的,在机器写入磁带时,是否有一种最有效的方法在内存中表示它们,向左或向右添加新值?显然,我不需要表示无限零(未写入磁带),但我确实需要扩展数据结构,因为新的值被添加到磁带的末端。

python列表可以做到这一点,如下图所示,在左边插入一个1:

代码语言:javascript
复制
start_time = time.time()
tape = [0]*10000000
print tape[:10]
insertion_time = time.time()
tape = [1] + tape 
print tape[:10]
print "total execution time: ", time.time() - start_time
print "time to add entry: ", time.time() - insertion_time

这一产出如下:

代码语言:javascript
复制
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
total execution time:  0.257364034653
time to add entry:  0.109524011612

使用list.insert确实使其速度提高了23倍:

代码语言:javascript
复制
start_time = time.time()
tape = [0]*100000
print tape[:10]
insertion_time = time.time()
tape.insert(0, [1])
print tape[:10]
print "execution time: ", time.time() - start_time
print "time to add entry: ", time.time() - insertion_time

给予:

代码语言:javascript
复制
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[[1], 0, 0, 0, 0, 0, 0, 0, 0, 0]
execution time:  0.0270080566406
time to add entry:  0.00468802452087

有比使用list对象更有效的方法来表示二进制磁带吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-30 06:49:56

如果磁带两端都是无限的,那么您也必须考虑索引的(-inf, -1]范围。最好的表示法,IMO,将是一对列表--一个用于非负范围,另一个用于负范围(索引反转)。当您超出磁带的分配范围时,您只需附加到相应的列表(与列表的前面不同,这是一个快速的操作)。

实现草案(使用来自这个答案的增强版本的这个答案):

代码语言:javascript
复制
class GrowingList(list):
    def __init__(self, default_value):
        self.default_value=default_value

    def __getitem__(self, i):
        return list.__getitem__(i) if i < len(self) else self.default_value

    def __setitem__(self, i, v):
        if i >= len(self):
            self.extend([self.default_value]*(i + 1 - len(self)))
        list.__setitem__(self, i, v)

class Tape:
    def __init__(self):
        self.pos_range=GrowingList(0)
        self.neg_range=GrowingList(0)

    def __getitem__(self, i):
        if i >= 0:
            return self.pos_range[i]
        else:
            return self.neg_range[-i-1]

    def __setitem__(self, i, v):
        if i >= 0:
            self.pos_range[i]=v
        else:
            self.neg_range[-i-1]=v

    def __repr__(self):
        start = -len(self.neg_range)
        end = len(self.pos_range)
        data = list(reversed(self.neg_range)) + self.pos_range
        return "Tape(range=[{}, {}), data={})".format(start, end, data)


t = Tape()
print(t)
t[4]=1
print(t)
t[-2]=1
print(t)

输出:

代码语言:javascript
复制
Tape(range=[0, 0), data=[])
Tape(range=[0, 5), data=[0, 0, 0, 0, 1])
Tape(range=[-2, 5), data=[1, 0, 0, 0, 0, 0, 1])
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43110398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档