BM61 矩阵最长递增路径

该文章讨论了一个关于非负数矩阵的问题,寻找一条从任意位置开始的最长递增路径,路径上元素递增,且每个单元格只能访问一次。解决方案是使用深度优先搜索(DFS)算法,通过遍历矩阵并在满足递增条件时递归探索相邻单元格,存储并返回最大路径长度。

矩阵最长递增路径_牛客题霸_牛客网 (nowcoder.com)

n*m矩阵 ,所有数均为非负数,需要在矩阵中找到一条最长路径,使这条路上元素都是递增;

上下左右方向移动,不重复走每个各自走一次

 定义四个方向int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

遍历比较,条件是matrix[nexti][nextj] > matrix[i][j]) 计数


class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 递增路径的最大长度
     * @param matrix int整型vector<vector<>> 描述矩阵的每个数
     * @return int整型
     */
    int dir[4][2] ={{-1,0},{1,0},{0,-1},{0,1}};
    int dfs(int i,int j,vector<vector<int> > &dp,vector<vector<int> >& matrix,int n,int m){
        if(dp[i][j] != 0)return dp[i][j];
        dp[i][j]++;
        for(int k =0; k < 4; k++){
            int nexti = i + dir[k][0];
            int nextj = j + dir[k][1];
            if (nexti >= 0 && nexti < n && nextj >= 0 && nextj < m &&
                    matrix[nexti][nextj] > matrix[i][j]){
                       dp[i][j] = max(dp[i][j],dfs(nexti,nextj,dp,matrix,n,m)+1);
                    }
        }
        return dp[i][j];
    }
    int solve(vector<vector<int> >& matrix) {
        // write code here
        if(matrix.size()==0 ||matrix[0].size()==0){return 0;}
        int res = 0;
        int n = matrix.size();
        int m = matrix[0].size();
        vector<vector<int> > dp(n,vector<int>(m));
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < m; ++j){
                res = max(res,dfs(i,j,dp,matrix,n,m));
            }
        }
        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、付费专栏及课程。

余额充值