python - 在 Python 中表示图灵机的无限磁带的最有效方法是什么?

标签 python memory data-structures turing-machines

一个Turing machine根据规则表操作无限条磁带上的符号。

就我而言,磁带上的条目可以是 0 和 1(二进制)。

磁带从“空”开始,在正向和负向都有无穷多个 0。该磁带根据机器遵循的规则进行写入,可能会在未写入的边缘添加 0 或 1。

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

Python 列表可以做到这一点,如下所示在左侧插入 1:

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

此输出:

[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 倍:

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

给予:

[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 对象更有效的方式来表示二进制磁带?

最佳答案

鉴于磁带两端都是无限的,您还必须考虑索引的 (-inf, -1] 范围。在我看来,最好的表示是一对列表- 一个用于非负范围,另一个用于负范围(索引相反)。当您超出磁带的分配范围时,您只需附加到相应的列表(这与添加到列表不同) ,是一个快速操作)。

实现草案(使用 this answer 中的 GrowingList 的增强版本):

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)

输出:

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])

关于python - 在 Python 中表示图灵机的无限磁带的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43110398/

相关文章:

Python——输出文件中的数据位于不方便的位置

android - 如何找出android中当前正在运行的应用程序的内存使用情况?

c - C语言中,指针访问的静态变量

sql - 程序结构——简单的命令行待办事项列表应用程序——Haskell 的方式是什么?

c - 为什么我的程序会读取一个额外的结构?

python - 我们可以在训练和测试数据中建立具有不同输入向量大小的模型吗?

python - cxFreeze 使用 sc2reader 库和多处理破坏 Python 应用程序

python - sqlacodegen - 无法连接到数据库

python - 使用 iterparse() 解析大型 XML 会消耗太多内存。还有其他选择吗?

algorithm - 除了对完整性的要求外,B-tree 和 B*-tree 之间有什么区别?