![cover](https://img-blog.csdnimg.cn/bffdb222832944f1b9029b6934904a27.png)
猎狗与兔子问题的Matlab编程思路与过程
有一只雄狗在B点位置发现了一只兔子在正东北方距离它200米的地方O处。此时免子开始以 8m/s的速度向正西北万亞离为 120 m 的洞口 A 全速跑去,假设猎狗在追赶兔子的时候始终朝着免于的方向全速奔跑,按要求完成下面的实验:(1)问猎狗能追上兔子的最小速度是多少,(2)选取猎狗的速度分别为 15m/s,18 m/s,计算猎狗追赶免子时跑过的路程。(3)画出猎狗追赶兔子奔跑的曲线图. 由于我们是
猎狗与兔子问题
有一只雄狗在B点位置发现了一只兔子在正东北方距离它200米的地方O处。此时免子开始以 8m/s的速度向正西北万亞离为 120 m 的洞口 A 全速跑去,假设猎狗在追赶兔子的时候始终朝着免于的方向全速奔跑,按要求完成下面的实验:
(1)问猎狗能追上兔子的最小速度是多少,
(2)选取猎狗的速度分别为 15m/s,18 m/s,计算猎狗追赶免子时跑过的路程。
(3)画出猎狗追赶兔子奔跑的曲线图.
问题(1)分解
问题的整体结构
由于我们是要求得猎狗能够抓到兔子的最小速度,所以我们应当设置一个大循环,在这个循环中,我们不断增加猎狗的初始速度。然后,在增加了猎狗的初始速度后,再进入一个小循环,用来计算猎狗是否能够抓到兔子。如果不能抓到兔子,小循环便自动结束,返回到大循环并进入下一轮循环;如果能够抓住兔子,便结束小循环并同时结束大循环,并输出猎狗的初始速度。其流程图如下:
猎狗与兔子的初始位置
上面的问题本质上是一个二维平面上的几何问题,所以我们先建立一个坐标系。因为问题的描述中是以猎狗所在的B点来描述位置关系的,所以我们就以猎狗所在的初始位置来作为坐标系的原点,同时将坐标系的正上方作为正北、正右方作为正东。
由此,我们可以初步的建立一个初始状态的二维平面状态图:
兔子的移动
要求解问题,我们需要不断的按照时间进行迭代计算猎狗和兔子的最新位置,并进行“猎狗——兔子”、“兔子——洞口”的关系判断。
首先,我们设置一个变量Tstep,用于表示每一轮迭代的计算时间。然后,设置变量rabSpeed和dogSpeed用于表示兔子和猎狗各自的速度。然后用rab(1,1)和rab(1,2)分别存储兔子每一轮迭代的坐标X、Y值;并用dog(1,1)和dog(1,2)分别存储猎狗每一轮迭代的坐标X、Y值。
对于兔子来说,显然它的初始位置X值为sin(45°)*200、Y值也是sin(45°)*200。故有:
rab(1,1)=200/sqrt(2);
rab(1,2)=200/sqrt(2);
对于兔子来说,每一轮迭代它都会跑TsteprabSpeed的距离。而因为兔子是向正西北方向逃跑,所以显然在每一轮迭代里兔子的X坐标会减小TsteprabSpeedsin(45°),兔子的Y坐标会增加TsteprabSpeed*sin(45°)。故有:
rab(1,1)=rab(1,1)-(Tstep*rabSpeed/sqrt(2));
rab(1,2)=rab(1,2)+(Tstep*rabSpeed/sqrt(2));
兔子逃跑成功的判断
由初始位置图可以得知,兔子从自己的起始位置不断的向洞口方向进行靠近。当兔子进入洞口后,兔子的X坐标将小于等于洞口位置的X坐标。所以,只要兔子的X坐标小于等于洞口的X坐标后,我们就可以认为兔子逃跑成功,便可以直接终止迭代计算了。即:
if rab(1,1)<=200/sqrt(2)-120/sqrt(2);
break;
end
猎狗的移动
猎狗的移动的基本思路与兔子相同,但是猎狗在移动的时候移动方向始终是朝向兔子的。猎狗的移动可以用下面的图来表示:
其中,A为兔子和猎狗的X坐标的的差值,B为兔子和猎狗的Y坐标的差值,a为猎狗在当前一轮迭代中X方向的移动距离,b为猎狗在当前一轮迭代中Y方向的移动距离,s则为猎狗在本轮迭代中的移动距离,S为猎狗在本轮迭代中的初始位置和兔子位置间的距离。
显然有a/s=A/S、b/s=B/S,即a=A * s/S、b=B * s/S。
由上,我们可以获得猎狗的移动程序段为:
x=rab(1,1)-dog(1,1); %对应上图中的A
y=rab(1,2)-dog(1,2); %对应上图中的B
xy=sqrt(x^2+y^2); %对应上图中的S
dog(1,1)=dog(1,1)+x/xy*(dogSpeed*Tstep); %dogSpeed*Tstep为猎狗一轮迭代中的移动距离
%对应上图中的s
dog(1,2)=dog(1,2)+y/xy*(dogSpeed*Tstep);
猎狗抓到兔子的判断
对于猎狗来说,只要在某一轮迭代中,它(在位置更新前)与兔子(位置更新后)之间的距离小于等于猎狗所跑的距离,就说明在本轮迭代中猎狗会捕获到兔子。即判断条件为
(猎狗x-兔子x)^ 2 +(猎狗y-兔子y)^2 < 猎狗速度 * 迭代时间
用Matlab代码表示为:
if (dog(1,1)-rab(1,1))^2+(dog(1,2)-rab(1,2))^2<=(dogSpeed*Tstep)^2
flag=1; %flag用来标识猎狗是否已抓到兔子
break;
end
问题的总体代码
我们把各个计算和判断的部分根据流程图进行组合,得到问题(1)的整体代码如下:
clear
clc
Tstep=0.01;
rabSpeed=8;
dogSpeed=7;
flag=0;
tar=200/sqrt(2)-120/sqrt(2);
while 1
dogSpeed=dogSpeed+0.1;
rab(1,1)=200/sqrt(2);
rab(1,2)=200/sqrt(2);
dog(1,1)=0;
dog(1,2)=0;
while 1
rab(1,1)=rab(1,1)-(Tstep*rabSpeed/sqrt(2));
rab(1,2)=rab(1,2)+(Tstep*rabSpeed/sqrt(2));
if rab(1,1)<=tar
break;
end
if (dog(1,1)-rab(1,1))^2+(dog(1,2)-rab(1,2))^2<=(dogSpeed*Tstep)^2
flag=1;
break;
end
x=rab(1,1)-dog(1,1);
y=rab(1,2)-dog(1,2);
xy=sqrt(x^2+y^2);
dog(1,1)=dog(1,1)+x/xy*(dogSpeed*Tstep);
dog(1,2)=dog(1,2)+y/xy*(dogSpeed*Tstep);
end
if flag==1
break;
end
end
disp('最小速度是:');
disp(dogSpeed);
代码的运行结果:
问题(2)(3)的求解
问题(2)(3)实际上可以看作是同一个问题的不同过程量的展示,所以在此作为一个问题进行求解。而问题(2)(3)的基本构架与问题(1)是相同的,区别在于——1、不需要外层的大循环来进行最小速度的叠加;2、需要对每次迭代猎狗所跑的距离进行叠加;3、需要存储猎狗和兔子每轮迭代中的位置,并最终画出曲线。
对于1,我们只需要直接删除外层的大循环;对于2,我们可以设置一个变量S并在每次迭代中向其累加猎狗奔跑的距离;对于3,我们引入一个计数器c,用于存储迭代的次数,然后将每次迭代的猎狗和兔子的位置存储到dog和rab里,最终用plot将其显示。修改后的程序如下:
Tstep=0.01;
rabSpeed=8;
dogSpeed=15;
flag=0;
tar=200/sqrt(2)-120/sqrt(2);
rab(1,1)=200/sqrt(2);
rab(1,2)=200/sqrt(2);
dog(1,1)=0;
dog(1,2)=0;
c=1; %计数器,用来标识迭代次数
S=0;
while 1
rab(c+1,1)=rab(c,1)-(Tstep*rabSpeed/sqrt(2));
rab(c+1,2)=rab(c,2)+(Tstep*rabSpeed/sqrt(2));
if rab(c+1,1)<=tar
break;
end
if (dog(c,1)-rab(c+1,1))^2+(dog(c,2)-rab(c+1,2))^2<=(dogSpeed*Tstep)^2
dog(c+1,1)=rab(c+1,1);
dog(c+1,2)=rab(c+1,2);
S=S+sqrt((dog(c,1)-rab(c+1,1))^2+(dog(c,2)-rab(c+1,2))^2); %对猎狗跑的距离进行累加(猎狗抓到兔子的迭代中,猎狗跑的距离是猎狗和兔子间的距离)
break;
end
x=rab(c+1,1)-dog(c,1);
y=rab(c+1,2)-dog(c,2);
xy=sqrt(x^2+y^2);
S=S+dogSpeed*Tstep; %对猎狗跑的距离进行累加
dog(c+1,1)=dog(c,1)+x/xy*(dogSpeed*Tstep);
dog(c+1,2)=dog(c,2)+y/xy*(dogSpeed*Tstep);
c=c+1;
end
disp('猎狗奔跑距离是');
disp(S);
plot(dog(:,1),dog(:,2));
hold on;
plot(rab(:,1),rab(:,2));
运行结果15m/s(显然可怜的猎狗没有抓到兔子):
运行结果18m/s(显然可怜的兔子被猎狗抓到了):
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)