一个基于matlab的简易加法图灵机实现

题主还是个普通的大一新生,分享写程序的点点滴滴,这是我的第一次pre的主题

图灵机是什么

为了把这个抽象的问题具象化,让我们设想这样一条纸带:

纸带可以根据我们的需求有长有短,被分成很多格,每一格都是0,在操作需要下可变成1,在机械中可用凹凸的活塞,电路中可用高低电平来实现01的区分。

(现在请各位短暂的忘掉二进制,这个模拟图灵机中,111不是7,而是3

我们通过一个加法运算来了解它:4+3=?,在图灵机中是怎么实现的呢?

我们先认可这样一套规则,算的第一个数字是几,那么就让纸带上几个连续的空变为1,然后隔一个不变的0表示加号,再按如上规则录入第二个数字,纸带便变成如下的样子

对于传统的图灵机而言,以上录入工作就结束了。

接下来,有一个探测头,它可以检测每一格是0还是1,并根据此格状态自身的执行规则(传统图灵机是翻转着的机械结构,电子的是小型电路)改变纸带上各格的状态自身的状态。(比如将此格从1变成0,并切换自身该执行规则中的哪一条

介绍重点:图灵机自身的规则 

L:表示探测头左移                             R:表示探测头右移                                   H:表示探测头不动

图灵机有一套“自身的规则”,如右表所示

探测头有三个状态:q1,q2,q3,刚开始探测时,探测头默认为q1状态。

探测头处于不同状态时,有遇到01时的不同改变方法

表中右下处数字+字母表示三项分别代表了

把这一格变成0/1,下一步往左/右移动/静止不动,改变探测头内部规则为q1/q2/q3

(下面我们以探测头处在q1状态时,遇到纸带上的“1”为例进行讲解。

1,读表可知 此时情况对应操作为1Rq1

2,先执行“1”,这格就是1,保持即可

3,再执行“R”,往右移动至下一格

4,最后执行”q1”,探测头状态仍为q1

5,步骤完成)

该规则与实现图灵机加法的关系

还是以4+3为例,我们都知道答案是77在图灵机中的表示是11111110000…)

4+311110111,因此要实现4+3的计算,本质上就是要实现让11110111

变成11111110这样一个过程。

看似是将后面的“111”前移,其实在直观执行来说,就是把中间的0变成1,再消去最后一位1的过程。

那么我们来看看,图灵机如何实现这一变化

“变01

当探测头处于q1状态,检测到中间的0时,会执行1Rq2指令,将原本代表“+“号的0处改为1

从而实现前后两段“1”的合并过程第一步。

  |

“虚晃一枪”

图灵机顺利检测完了所有的1,但是不是还忘了什么?前面可有81!,此时就需要“0Lq3”这个指令发挥作用了,当检测到最后的0时,探测头便需要向左移动一格,将那个尾部多余的1去掉

                                                                              |

“哼,想逃?”

探测头返回,检测到1,在状态q3下执行0Hq3指令,变多余的10,然后执行“H”指令保持不动停止运行。

变“11110111”为“11111110”的过程便大功告成,接下来图灵机即可检测到7个连续的1进行阿拉伯数字7的输出,图灵机的一个加法过程自此实现完毕

                                                                              |

 Matlab的具体实现代码 

此代码的重点不是输出,而是在运算过程中将变成以此实现模仿图灵机计算的效果

%一,输入与转化阶段
%给予用户输入提示语(图灵机在键盘上敲数字环节)
prompts={'请输入第一个数字:','请输入第二个数字:'};
title='加法的图灵机实现';
answer = inputdlg(prompts, title);
% 下面是图灵机是将数字n转化为n个1存储,因此使用 repmat 函数重复字符 '1',重复次数为 num,以形成类似图灵机转化的过程)
num1=str2double(answer{1});  
str1 = repmat('1', 1, num1);
num2=str2double(answer{2});
str2 =repmat('1',1,num2);
tape=strcat(str1,num2str(0),str2,num2str(0));
%在第十行图灵机的转化功能已经实现,顺利将两个数字相加"a"+"b"表现为(a个1)0(表示+)(b个1)的形式
% 末尾加上0是在调试中发现不加上0会导致机器无法将第二个数原本位置的最后一位变成0,造成结果+1

%二,读写头初始化阶段
%读写头位置与状态初始化环节
head_position = 1; % 初始化读写头的位置(到了纸带头)
state = 'A'; %图灵机初始状态为A

%三,读写头内部代码编辑阶段
% 定义图灵机的规则
%按照图灵探索出的3x2指令表编写
rules = struct();
rules.A_0 = struct('write','1','move','R','next_state','B');
rules.A_1 = struct('write','1','move','R','next_state','A');
rules.B_0 = struct('write','0','move','L','next_state','C');
rules.B_1 = struct('write','1','move','R','next_state','B');
rules.C_0 = struct('write','0','move','H','next_state','C');
rules.C_1 = struct('write','0','move','H','next_state','C');

%四,图灵机运行阶段
% 执行图灵机的计算
%用循环实现扫描过程
for i = 1:numel(tape)+1 %(+1的原因与第一步的最后一条同理,检测完所有项后需要返回将倒数第二位变成0 )
    % 获取读写头当前位置的符号(读到的是0还是1?以设置读写头状态为A/B/C_0/1的数字项)
    current_symbol = tape(head_position); 
    % 获取到读写头的状态中的字母项(来自初始化或上一步执行完的更新),并与上一步的数字项拼接,共同实现设置状态过程
    rule = rules.(sprintf('%s_%c',state,current_symbol));
    tape(head_position) = rule.write; 
    %根据既有指令实现运动(strcmp函数可比较两字符项是否一致)
    if strcmp(rule.move,'R')
        head_position = head_position + 1;
    elseif strcmp(rule.move,'H')
            head_position = tape(head_position);
    else
        head_position = head_position - 1;
    end
    %更新读写头接触此项后的新状态
    state = rule.next_state;
end
%执行完以上步骤后,(a个1)与(b个1)之间的0已消失,象征着二者的合并,也就是类似相加的过程

%五,计数与输出
D=count(tape,"1");
disp(['答案是',num2str(D)]) % 此项意为图灵机最终输出的人能看懂的阿拉伯数字

这只是题主的一个小实验,参考了很多大佬的代码,来实现对于经典的一次拙劣的模仿,还敬请各位CSDN上的大佬多多指教。

主修方向其实是人工智能,接下来期望能够给大家带来更多算法与程序!

谢谢大家!

相关图灵机运行过程及截图取材自 【什么是图灵机】_哔哩哔哩_bilibili

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shiroha Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值