用matlab怎么求矩形的最短路径问题,就类似于这种,现在很需要来人讲解,有没有
会做的佬,可有偿
Matlab代码实现最短路径问题:
% 输入矩阵
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)));
一个信号,这个信号中仅包含两个正(余)弦波,一个是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 ,是这两个频率的公约数
%所以谱线同时经过 1 和 1.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,那么有: