matlab矩形最短路径求解

用matlab怎么求矩形的最短路径问题,就类似于这种,现在很需要来人讲解,有没有
会做的佬,可有偿

img

基于Monster 组和GPT的调写:

Matlab代码实现最短路径问题:

img

% 输入矩阵
mat = [2 3 4 5 6 7 2 5 3;       4 3 7 6 4 5 8 9 6;       5 6 7 2 3 4 2 4 6;       3 5 3 5 6 7 2 5 4;       2 8 7 6 7 3 4 3 4;       4 5 4 3 5 4 3 2 6;       9 6 3 6 7 3 6 6 7;       8 7 4 5 8 9 6 5 6];
   
% 定义起点和终点
start = [1, 1];
finish = [8, 9];

% 初始化dp矩阵
dp = inf(size(mat));
dp(start(1), start(2)) = 0;

% 动态规划
for i = start(1):finish(1)
    for j = start(2):finish(2)
        % 求当前格子到左边格子的最短路径
        if j > start(2)
            dp(i, j) = min(dp(i, j), dp(i, j-1) + mat(i, j));
        end
        % 求当前格子到上边格子的最短路径
        if i > start(1)
            dp(i, j) = min(dp(i, j), dp(i-1, j) + mat(i, j));
        end
        % 求当前格子到起点的最短路径
        if i == start(1) && j > start(2)
            dp(i, j) = dp(i, j-1) + mat(i, j);
        end
        if j == start(2) && i > start(1)
            dp(i, j) = dp(i-1, j) + mat(i, j);
        end
    end
end

% 输出结果
fprintf("最短路径长度为:%d\n", dp(finish(1), finish(2)));


  • 首先,我们定义了输入矩阵 mat,其大小为 $8\times9$,代表一个 $8\times9$ 的矩形。
  • 接着,定义了起点和终点的坐标 start 和 finish。
  • 接下来,初始化了一个和输入矩阵大小相同的矩阵 dp,并将其中所有元素的初始值设为正无穷。这个矩阵将用于记录从起点到每个格子的最短路径长度。
  • 然后,开始进行动态规划算法的计算。具体来说,我们使用两层循环遍历矩阵中的每个格子,依次计算该格子到左边格子、上边格子、起点格子的最短路径长度,并将计算出来的最短路径长度更新到 dp 矩阵中。具体而言,对于矩阵中的每个格子 $(i,j)$,我们可以按照如下方式进行计算:
  • 如果当前格子 $(i,j)$ 的列坐标 $j$ 大于起点格子的列坐标,说明当前格子左边有格子,可以从左边格子到达当前格子。我们可以通过以下公式计算当前格子到左边格子的最短路径长度:dp(i,j)=min⁡(dp(i,j),dp(i,j−1)+mat(i,j))dp(i,j)=min(dp(i,j),dp(i,j−1)+mat(i,j))
  • 如果当前格子 $(i,j)$ 的行坐标 $i$ 大于起点格子的行坐标,说明当前格子上面有格子,可以从上边格子到达当前格子。我们可以通过以下公式计算当前格子到上边格子的最短路径长度:dp(i,j)=min⁡(dp(i,j),dp(i−1,j)+mat(i,j))dp(i,j)=min(dp(i,j),dp(i−1,j)+mat(i,j))
  • 如果当前格子 $(i,j)$ 的行坐标 $i$ 等于起点格子的行坐标,且列坐标 $j$ 大于起点格子的列坐标,说明当前格子在起点格子的右边,可以从起点格子到达当前格子。我们可以通过以下公式计算当前格子到起点格子的最短路径长度:dp(i,j)=dp(i,j−1)+mat(i,j)dp(i,j)=dp(i,j−1)+mat(i,j)
  • 如果当前格子 $(i,j)$ 的列坐标 $j$ 等于起点格子的列坐标,且行坐标 $i$ 大于起点格子的行坐标,说明当前格子在起点格子的下面,可以从起点格子到达当前格子。我们可以通过以下公式计算当前格子到起点格子的最短路径长度:dp(i,j)=dp(i−1,j)+mat(i,j)dp(i,j)=dp(i−1,j)+mat(i,j)
  • 最后,输出 dp(finish(1), finish(2)) 即为从起点到终点的距离
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7653772
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:matlab一次读入多幅顺序编号的图片,并赋予顺序变量,并对其中某一变量操作
  • 除此之外, 这篇博客: 基于matlab深入形象理解频率分辨率,补零,栅栏效应,频谱泄漏中的 基于matlab实例分析 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 一个信号,这个信号中仅包含两个正(余)弦波,一个是1.05MHz ,一个是 1MHz ,即 f(t)=cos(2π1050000t)+cos(2π1000000t)。设定采样频率为Fs=100Mhz,如果采 1000个点,那么时域信号的时长就有 10微秒

    NO.1

    clear;clc
    close all %频率分辨率为1/NTs=fs/N=100e6/1000=100kHz>50kHz 所以分不出来
    %% FFT
    Fs = 100e6;		    % 采样频率 Hz
    T = 1/Fs;		    % 采样周期 s
    L0 = 1000;                  % 信号长度
    L = 1000;                   % 数据长度
    t0 = (0:L0-1)*T;            % 信号时间序列
    x = cos(2*pi*1e6*t0) + cos(2*pi*1.05e6*t0); % 信号函数
    t = (0:L-1)*T;              % 数据时间序列
    %% Plot
    figure(1)
    plot(t*1e6,x,'b-','linewidth',1.5)
    title ('\fontsize{10}\fontname{Times New Roman}Time domain signal')
    xlabel('\fontsize{10}\fontname{Times New Roman}\it t /\rm \mus')
    ylabel('\fontsize{10}\fontname{Times New Roman}\it y\rm(\itt\rm)')
    grid on;
    axis([0 10 -2 2])
    set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
    set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
    %% FFT
    Y = fft(x);                   % 快速傅里叶变换
    % 计算双侧频谱 P2。然后基于 P2 和偶数信号长度 L 计算单侧频谱 P1 双边普的幅度两倍,对折,移到零点,fftshift是双边频谱移到零点偶对称。
    P2 = abs(Y/L0);   %fft除以L0才是真实的fourier系数
    P1 = P2(1:L/2+1); %第一个点到
    P1(2:end-1) = 2*P1(2:end-1);
    f = Fs*(0:(L/2))/L;% Rfft
    figure(2)
    plot(f,P1,'r-','Marker','.','markersize',10,'linewidth',1.5)
    axis([0.5e6 1.5e6 0 1.5])
    title('\fontsize{10}\fontname{Times New Roman}Power Spectrum')
    xlabel('\fontsize{10}\fontname{Times New Roman}\it f /\rm Hz')
    ylabel('\fontsize{10}\fontname{Times New Roman}\it y\rm(\itf\rm)')
    grid on;
    set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
    set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
    % figure(3)
    % f = Fs*(0:(L-1))/L;% Rfft
    % plot(f,P2,'r-','Marker','.','markersize',10,'linewidth',1.5)  %看下双边普
    % figure(4)
    % plot(f,abs(fftshift(Y)),'r-','Marker','.','markersize',10,'linewidth',1.5)  %看下fftshift双边普
    
    

    在这里插入图片描述在这里插入图片描述
    频谱点稀疏,在1MHz附近根本无法将1 MHz 和1.05 MHz 的两个频率分开。
    NO.2
    在1基础上补0 可以看出时时域上前面与1相同补零6000个,在频谱上显得更加细致,
    但补零操作增加了频域的插值点数,让频域曲线看起来更加光滑,即减缓了栅栏效应
    频率分辨率不改变Fs/Nfft=100kHz>50kHz 增加了FFT频率分辨率使得频谱细化

    clear;clc
    close all  
    %% FFT
    Fs = 100e6;		    % 采样频率 Hz
    T = 1/Fs;		    % 采样周期 s
    L0 = 1000;                  % 信号长度
    L = 7000;                   % 数据长度
    t0 = (0:L0-1)*T;            % 信号时间序列
    x = cos(2*pi*1e6*t0) + cos(2*pi*1.05e6*t0); % 信号函数
    t = (0:L-1)*T;              % 数据时间序列
    y = zeros(1,L);
    y(1:L0) = x;
    %% Plot
    figure(1)
    plot(t*1e6,y,'b-','linewidth',1.5)
    title('\fontsize{10}\fontname{Times New Roman}Time domain signal with Zero Padding')
    xlabel('\fontsize{10}\fontname{Times New Roman}\it t /\rm \mus')
    ylabel('\fontsize{10}\fontname{Times New Roman}\it y\rm(\itt\rm)')
    grid on;
    axis([0 70 -2 2])
    set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
    set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
    %% FFT
    Y = fft(y);                   % 快速傅里叶变换
    % 计算双侧频谱 P2。然后基于 P2 和偶数信号长度 L 计算单侧频谱 P1。
    P2 = abs(Y/L0);
    P1 = P2(1:L/2+1);
    P1(2:end-1) = 2*P1(2:end-1);
    f = Fs*(0:(L/2))/L;% Rfft
    figure(2)
    plot(f, P1,'r-','Marker','.','markersize',10,'linewidth',1.5)
    axis([0.5e6 1.5e6 0 1.5])
    title('\fontsize{10}\fontname{Times New Roman}Power Spectrum')
    xlabel('\fontsize{10}\fontname{Times New Roman}\it f /\rm Hz')
    ylabel('\fontsize{10}\fontname{Times New Roman}\it y\rm(\itf\rm)')
    grid on;
    set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
    set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
    

    在这里插入图片描述在这里插入图片描述频谱点密集了不少,但是在 1MHz 附近依然无法将 1.05MHz和 1MHz的两个频率成分分开。
    可以看出,波形分辨率只与原始数据的时长T有关
    也就是说,补零操作增加了频域的插值点数,让频域曲线看起来更加光滑,也就是增加了FFT频率分辨率.
    NO.3
    这里不补零而是真实的增加信号长度 频率分辨率=14kHz<50kHz
    采样频率对1MHz来说是整周期取样所以无频谱泄漏 但1.05MHz有
    但是其周边的点上却都有不小的幅值,这就是所谓的频谱泄露,因为数据点的个数影响,1mhz处有谱线存在,但在1.05处没有谱线存在

    clear;clc
    close all
    
    %% FFT
    Fs = 100e6;		    % 采样频率 Hz  
    T = 1/Fs;		    % 采样周期 s
    L0 = 7000;                  % 信号长度
    L = 7000;                   % 数据长度
    t0 = (0:L0-1)*T;            % 信号时间序列
    x = cos(2*pi*1e6*t0) + cos(2*pi*1.05e6*t0); % 信号函数
    t = (0:L-1)*T;              % 数据时间序列
    %% Plot
    figure(1)
    plot(t*1e6,x,'b-','linewidth',1.5)
    title('\fontsize{10}\fontname{Times New Roman}Time domain signal')
    xlabel('\fontsize{10}\fontname{Times New Roman}\it t /\rm \mus')
    ylabel('\fontsize{10}\fontname{Times New Roman}\it y\rm(\itt\rm)')
    grid on;
    axis([0 70 -2 2])
    set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
    set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
    %% FFT
    Y = fft(x);                   % 快速傅里叶变换
    % 计算双侧频谱 P2。然后基于 P2 和偶数信号长度 L 计算单侧频谱 P1。
    P2 = abs(Y/L0);
    P1 = P2(1:L/2+1);
    P1(2:end-1) = 2*P1(2:end-1);
    f = Fs/2*linspace(0,1,L/2+1);% Rfft
    figure(2)
    plot(f, P1,'r-','Marker','.','markersize',10,'linewidth',1.5)
    axis([0.5e6 1.5e6 0 1.5])
    title('\fontsize{10}\fontname{Times New Roman}Power Spectrum')
    xlabel('\fontsize{10}\fontname{Times New Roman}\it f /\rm Hz')
    ylabel('\fontsize{10}\fontname{Times New Roman}\it y\rm(\itf\rm)')
    grid on;
    set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
    set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
    

    在这里插入图片描述
    在这里插入图片描述
    NO.4
    为了解决上个问题,可以设法使得谱线同时经过 1.05MHz 和 1MHz这两个频率点,找到他们的公约数。
    如果原始数据不变,在后面再补充 1000 个零点:

    clear;clc
    close all  %3基础上补零看看对频谱泄漏的影响
    %增加了FFT频率分辨率使得频谱细化
    %FFT分辨率就是 fs/8000=12.5khz ,是这两个频率的公约数
    %所以谱线同时经过 11.05 这两个频率点。 减缓了频谱泄漏 但其余部分任有少量泄漏,会有一些旁瓣出现,这是因为补零影响了原始信号
    %所以将L0=8000,试试 这样就不存在补零带来的误差了。
    %补零仅是减小了频域采样的间隔。这样有利于克服由于栅栏效应带来的有些频谱泄露的问题 但也可能加重
    %% FFT
    Fs = 100e6;	            % 采样频率 Hz
    T = 1/Fs;		    % 采样周期 s
    L0 = input('please 7000 or 8000=');                  % 信号长度
    L = 8000;                   % 数据长度  把它改成16000试试 频谱更清晰
    t0 = (0:L0-1)*T;            % 信号时间序列
    x = cos(2*pi*1e6*t0) + cos(2*pi*1.05e6*t0); % 信号函数
    t = (0:L-1)*T;              % 数据时间序列
    y = zeros(1,L);
    y(1:L0) = x;
    %% Plot
    
    figure(1)
    plot(t*1e6,y,'b-','linewidth',1.5)
    title('\fontsize{10}\fontname{Times New Roman}Time domain signal')
    xlabel('\fontsize{10}\fontname{Times New Roman}\it t /\rm \mus')
    ylabel('\fontsize{10}\fontname{Times New Roman}\it y\rm(\itt\rm)')
    grid on;
    axis([0 80 -2 2])
    set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
    set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
    %% FFT
    Y = fft(y);                   % 快速傅里叶变换
    % 计算双侧频谱 P2。然后基于 P2 和偶数信号长度 L 计算单侧频谱 P1。
    P2 = abs(Y/L0);  %%%%%%%除以信号长度才是真正幅度  ? 谱密度 乘以1/L0   看一下FT和DFT公式,用fft后乘以dt才是真实
    P1 = P2(1:L/2+1);
    P1(2:end-1) = 2*P1(2:end-1);
    f = Fs/2*linspace(0,1,L/2+1);% Rfft
    figure(2)
    plot(f, P1,'r-','Marker','.','markersize',10,'linewidth',1.5)
    axis([0.5e6 1.5e6 0 1.5])
    title('\fontsize{10}\fontname{Times New Roman}Power Spectrum')
    xlabel('\fontsize{10}\fontname{Times New Roman}\it f /\rm Hz')
    ylabel('\fontsize{10}\fontname{Times New Roman}\it y\rm(\itf\rm)')
    grid on;
    set(gca,'FontSize', 10 ,'FontName', 'Times New Roman')
    set(gcf,'unit','centimeters','position',[15 10 13.53 9.03],'color','white')
    

    L0=7000,补零1000个点
    在这里插入图片描述在这里插入图片描述上图会有一些旁瓣出现,这是因为补零影响了原始信号,如果,直接采8000个点作为原始数据,即将程序中的L0改为8000,那么有:在这里插入图片描述在这里插入图片描述

  • 您还可以看一下 硬核野生技术咨询客服小李老师的matlab零基础入门路径规划城市遍历机器人路径等问题课程中的 数据显示格式、逻辑值等小节, 巩固相关知识点