BM61 矩阵最长递增路径

该博客讨论了一种寻找矩阵中最长递增路径的问题,其中每个元素是非负整数。通过使用广度优先搜索(BFS)或深度优先搜索(DFS)策略,并使用动态规划优化,可以在O(nm)的时间复杂度内解决此问题。博客提到了如何避免重复遍历和存储每个位置的最大递增路径长度,从而提高效率。示例展示了在不同输入矩阵中找到最长递增路径的方法。

描述
给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。
这个路径必须满足以下条件:

  1. 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外。
  2. 你不能走重复的单元格。即每个格子最多只能走一次。

数据范围:1≤n,m≤1000,1≤matrix[i][j]≤1000
进阶:空间复杂度 O(nm) ,时间复杂度 O(nm)

例如:当输入为[[1,2,3],[4,5,6],[7,8,9]]时,对应的输出为5,
其中的一条最长递增路径如下图所示:
在这里插入图片描述

示例1
输入:
[[1,2,3],[4,5,6],[7,8,9]]
返回值:
5
说明:
1->2->3->6->9即可。当然这种递增路径不是唯一的。

示例2
输入:
[[1,2],[4,3]]
返回值:
4
说明:
1->2->3->4

思路:这道题是一个常规的广度/深度遍历的题目,需要注意的是,直接用最常规的思路做, 时间复杂度 是 mnO(4^(mn)),显然太慢, 优化思路**是用一个矩阵来存储 从 某个位置开头的最大递增长度,这样下次再遍历到这个地方时,就不用再重新全部搜索了,这样每个位置只遍历了一遍,**时间复杂度可以近似看成 O(mn)。

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 递增路径的最大长度
# @param matrix int整型二维数组 描述矩阵的每个数
# @return int整型
#
class Solution:
    
    def dfs(self, matrix, dp, r, c, pre):
        if r<0 or r>=len(matrix) or c<0 or c>=len(matrix[0]) or matrix[r][c]<=pre:
            return 0
        if dp[r][c] > 0:
            return dp[r][c]
        temp = self.dfs(matrix, dp, r+1, c, matrix[r][c])
        temp = max(temp, self.dfs(matrix, dp, r-1, c, matrix[r][c]))
        temp = max(temp, self.dfs(matrix, dp, r, c+1, matrix[r][c]))
        temp = max(temp, self.dfs(matrix, dp, r, c-1, matrix[r][c]))
        dp[r][c] = max(dp[r][c], temp+1)
        return dp[r][c]
        
        
    def solve(self , matrix: List[List[int]]) -> int:
        # write code here
        if len(matrix) == 0:
            return 0
        rows, cols = len(matrix), len(matrix[0])
        dp = [[0 for j in range(cols)] for i in range(rows)]
        res = 1
        for i in range(rows):
            for j in range(cols):
                res = max(res, self.dfs(matrix, dp, i, j, -1))
        return res
                
                
当 `Bm` 矩阵为 4x3 矩阵时,需要对原代码中的部分内容进修改以适配新的矩阵维度。以下是修改后的 `SpeedCurrent_MPC_Simulink` 函数代码: ```matlab function uq = SpeedCurrent_MPC_Simulink(omega, iq, p, r) % 带速度和电流约束的非级联MPC(PMSM专用),兼容Simulink代码生成 % 输入: omega(当前速度, rad/s), iq(当前q轴电流, A), p(当前位置, rad), r(位置参考, rad) % 输出: uq(q轴电压指令, V), ud_comp(d轴电压补偿, V,此处设为0,可扩展) %% 0. 显式初始化所有变量(优先级最高,解决未定义错误) % 输出变量初始化 uq = 0.0; % q轴电压指令(标量,double) ud_comp = 0.0; % d轴补偿(固定为0,标量,double) % 输入变量类型转换(按实际输入格式调整,此处转为single) omega = single(omega); iq = single(iq); p = single(p); r = single(r); % 中间变量预初始化(核心修复:确保所有变量有初始值) Nc = 16; % 控制时域需提前定义(用于Delta_U尺寸) Delta_U = zeros(Nc, 1, 'double'); % 二次规划输出(Nc×1,double) Delta_uq = 0.0; % q轴电压增量(标量,double) uq_current = 0.0; % 当前q轴电压指令(标量,double) uq_prev = 0.0; % 前一时刻电压(适配persistent初始化) %% 1. 关键参数定义(预定义所有常量,避免未定义错误) % 采样与硬件参数 Tms = 0.001; % 采样时间 (s) u_max = 310.0; % 最大相电压(380V电网→直流母线√2×220≈310V) id = 0.0; % d轴电流指令(表贴式电机弱磁前设为0,double) % 电机参数(根据实际PMSM调整,此处为示例值) J = 0.020; % 转动惯量 (kg·m²) B = 0.008; % 粘性阻尼系数 (N·m/(rad/s)) P = 4; % 极对数 Kt = 1.0; % 转矩系数 (N·m/A) R = 0.4; % 定子电阻 (Ω) Lq = 6e-3; % q轴电感 (H) Ld = 6e-3; % d轴电感 (H)(表贴式电机Ld=Lq) Psi_f = 0.186; % 永磁磁链 (Wb) % MPC核心参数 Np = 24; % 预测时域(步数,需≥Nc) % Nc已在开头初始化(控制时域,步数) % 物理约束(硬件/安全限制) omega_max = 3000.0; % 最大速度 (rad/s) iq_max = 40.0; % 最大q轴电流 (A) delta_uq_max = 20; % q轴电压增量约束 (V) %% 2. PMSM状态空间模型(dq轴4阶模型:id, iq, omega, p) % 状态方程:dx/dt = Am*x + Bm*u(u=[ud; uq; 新增控制量]) Am = [ -R/Ld, omega, -Psi_f/Ld, 0; -omega , -R/Lq, 0, 0; 0, (3*P*Kt)/(2*J), -B/J, 0; 0, 0, 1, 0]; % 4×4状态矩阵(double) % 输入矩阵(ud控制id,uq控制iq/omega,新增控制量) Bm = [1/Ld, 0, 0; 0, 1/Lq, 0; 0, 0, 0; 0, 0, 0]; % 4×3输入矩阵(double) % 输出矩阵(关注iq、omega、p三个被控量) Cm = [0, 1, 0, 0; % 输出1:iq 0, 0, 1, 0; % 输出2:omega 0, 0, 0, 1]; % 输出3:p ny = size(Cm, 1); % 输出维度(ny=3,double) %% 3. 模型离散化(零阶保持ZOH,适配数字控制) % 增广矩阵用于ZOH离散化:[Am Bm; 0 0](7×7) aug_mat = [Am, Bm; zeros(3, size(Am,2)+size(Bm,2))]; % 7×7增广矩阵(double) M = expm(aug_mat * Tms); % 矩阵指数实现ZOH(double) Ad = M(1:4, 1:4); % 4×4离散状态矩阵(double) Bd = M(1:4, 5:7); % 4×3离散输入矩阵(double) %% 4. MPC增广模型(状态+前一输入,实现增量控制) % 增广状态:[id; iq; omega; p; uq_prev](5×1) nx_aug = 5; % 增广状态维度 nu_aug = 1; % 控制输入维度(仅Δuq) % 增广状态矩阵(5×5,double) A_aug = [Ad, Bd(:,2); % 原状态对uq的响应 zeros(1, 4), 1 ];% 前一电压传递:uq_prev(k+1)=uq(k) % 增广输入矩阵(5×1,double,输入为Δuq) B_aug = [Bd(:,2); 1]; % 原状态对Δuq的响应 + uq(k)=uq_prev+Δuq % 增广输出矩阵(3×5,double) C_aug = [Cm, zeros(ny, 1)]; % 输出与前一输入无关 %% 5. 预测矩阵构建(Np步预测,double类型) phi = zeros(Np*ny, nx_aug, 'double'); F = zeros(Np*ny, Nc*nu_aug, 'double'); for i = 1:Np % 填充phi:第i步状态预测(A_aug^i * x_aug) A_aug_pow = A_aug^i; phi((i-1)*ny+1:i*ny, :) = C_aug * A_aug_pow; % 填充F:第i步控制影响(仅控制时域内的Δuq) for j = 1:min(i, Nc) A_aug_pow_ij = A_aug^(i-j); F((i-1)*ny+1:i*ny, j) = C_aug * A_aug_pow_ij * B_aug; end end %% 6. 权重矩阵与参考轨迹(均为double类型) % 输出权重矩阵Q_bar(对角矩阵,突出位置控制权重) Q_iq = 8000; % iq权重 Q_omega = 8000; % 速度权重 Q_theta = 8000; % 位置权重 R_u = 0.01; % 增量权重(标量,double) Q_bar = zeros(Np*ny, Np*ny, 'double'); for i = 1:Np % 第i步的iq权重(Q_iq)和omega权重(Q_omega) Q_bar((i-1)*ny+1, (i-1)*ny+1) = Q_iq; % iq权重 Q_bar((i-1)*ny+2, (i-1)*ny+2) = Q_omega; % omega权重 Q_bar((i-1)*ny+3, (i-1)*ny+3) = Q_theta; % p权重 end % 控制权重矩阵R_bar(抑制电压增量波动) R_bar = kron(eye(Nc, 'double'), R_u); % Nc×Nc对角矩阵(double) % 参考轨迹生成(位置→速度→电流,强制double) omega_ref = abs(r - p) ; % 由位置误差计算速度参考 omega_ref = max(min(omega_ref, omega_max), -omega_max); % 速度限幅 iq_ref = (J*(omega_ref - omega) + B*omega) / (3*P*Kt/2); % 转矩平衡求电流参考 iq_ref = max(min(iq_ref, iq_max), -iq_max); % 电流限幅 % 参考向量强制转为double(核心修复:避免r_seq为single) ref_single = [iq_ref; omega_ref; r]; ref_double = double(ref_single); r_seq = repmat(ref_double, Np, 1); % 扩展为Np步参考(double) %% 7. 增广状态向量(当前状态+前一电压,double类型) persistent uq_prev_persist; % 用persistent保存前一时刻电压 if isempty(uq_prev_persist) uq_prev_persist = 0.0; % 首次调用初始化(double) end uq_prev = uq_prev_persist; % 关联persistent变量 % 增广状态:[id; iq; omega; p; uq_prev](强制double) x_aug_current = double([id; iq; omega; p; uq_prev]); %% 8. 二次规划问题构建(适配Simulink代码生成) % 目标函数:min(0.5*ΔU'*H*ΔU + ΔU'*E) H = F' * Q_bar * F + R_bar; % 二次项矩阵(Nc×Nc,double) pred_error = phi * x_aug_current - r_seq; % 预测误差(double) E = double(F' * Q_bar * pred_error); % 线性项(Nc×1,double,核心修复) % 约束条件(电压增量限幅,double) lb = -delta_uq_max * ones(Nc, 1); % 最小增量(Nc×1) ub = delta_uq_max * ones(Nc, 1); % 最大增量(Nc×1) % 优化选项(关闭显示,固定算法,适配代码生成) options = optimoptions('quadprog','Algorithm','active-set'); % 求解二次规划(所有输入均为double,双重初始化Delta_U) x0 = zeros(Nc, 1, 'double'); % 初始搜索点 Delta_U = zeros(Nc, 1, 'double'); % 再次初始化,避免歧义 Delta_U = quadprog(H, E, [], [], [], [], lb, ub, x0, options); %% 9. 控制量计算与限幅 Delta_uq = Delta_U(1); % 取第一个控制增量(仅用控制时域第一步) uq_current = uq_prev + Delta_uq; % 计算当前电压 % 电压幅值限幅(确保不超过直流母线电压) uq_current = max(min(uq_current, u_max), -u_max); % 更新前一时刻电压(供下一周期使用) uq_prev_persist = uq_current; %% 10. 输出赋值 uq = uq_current; end ``` ### 主要修改点: 1. **`Bm` 矩阵维度修改**:将 `Bm` 矩阵修改为 4x3 矩阵,以适配新增的控制量。 2. **增广矩阵维度修改**:由于 `Bm` 矩阵维度变化,增广矩阵 `aug_mat` 的维度从 6x6 变为 7x7。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值