利用堆栈实现走迷宫算法

数据结构:堆栈

算法思想:堆栈弹栈,压栈,回溯法

 

 

  1 //迷宫问题
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #define m 9
  5 #define n 9 
  6 #define MAXSIZE 100 
  7 //迷宫问题
  8 
  9 //定义移动位置 ,其中 
 10 typedef struct{
 11     int x,y;
 12 }item;
 13 //定义一个数据类型为dataType,在栈里面存在此数据
 14 //主要作为迷宫移动位置的临时存放点,其中x为当前位置的横坐标,y为当前位置的纵坐标
 15 //d为 搜索的次数(方向) 
 16 typedef struct{
 17     int x,y,d;
 18 }dataType; 
 19 
 20 //定义一个栈 
 21 typedef struct{
 22     dataType data[MAXSIZE];
 23     int top; 
 24 }list,*pList;
 25 
 26 
 27 //创建栈
 28 
 29 pList initList(){
 30     pList p;
 31     p = (pList)malloc(sizeof(list));
 32     if(p){
 33         p->top = -1;
 34     }
 35     
 36     return p; 
 37 } 
 38 
 39 //判断栈是否为空
 40 int isEmpty(pList p){
 41     if(p->top==-1){
 42         return 1;//如果是空栈就返回1 
 43     }else{
 44         return 0;
 45     }
 46 }
 47 
 48 //压栈
 49 int pushList(pList p,dataType data){
 50     if(p->top==MAXSIZE-1){//如果栈超出了大小,返回0 
 51         return 0;
 52     }
 53     p->top++;
 54     p->data[p->top] = data;//压栈操作
 55     return 1;//压栈成功,返回1 
 56 }
 57 
 58 //弹栈
 59 int popList(pList p,dataType *data){
 60     if(isEmpty(p)){
 61         return 0;//如果是空栈,就不弹,直接返回0 
 62     }else{
 63         *data = p->data[p->top];
 64         p->top--;
 65         return 1;
 66     } 
 67 }
 68 
 69 //销毁栈
 70 void destory(pList *p){
 71     if(*p){
 72         free(*p);
 73     }
 74     *p = NULL;
 75     return; 
 76 } 
 77  
 78 int mazePath(int maze[][n+2],item move[],int x0,int y0){//maze表示一个迷宫的数组,move表示当前探索,x0,y0表示初始位置
 79     pList p;//定义栈
 80     dataType temp;//定义临时位置 
 81     int x,y,d,i,j;//x,y用来存放临时位置的角标,d表示临时的探索次数,i,j所在位置的迷宫角标
 82     p = initList();//创建栈
 83     if(!p){//如果创建失败 
 84         printf("创建栈失败");
 85         return 0;  
 86     }
 87     
 88     //初始化走过的位置 
 89     temp.x = x0;
 90     temp.y = y0;
 91     temp.d = -1;
 92     
 93     //把迷宫入口压栈
 94     pushList(p,temp);
 95     
 96     //当栈里面不为空时 
 97     while(!isEmpty(p)){
 98         popList(p,&temp);//弹栈
 99         x = temp.x;
100         y = temp.y;
101         d = temp.d+1;//给d+1,让其进行第一次探索
102         while(d<4){//四次探索 
103             i = x+move[d].x;//原来的位置加上探索的位置
104             j = y+move[d].y;
105             
106             //当某条路是通路的时候 
107             if(maze[i][j]==0){//表示此路可走 
108                 //使用temp来保存路径 
109                 temp.x = x;
110                 temp.y = y;
111                 temp.d = d;
112                 //将路径压栈
113                 pushList(p,temp);
114                 //x、y来保存当前新的路径 
115                 x = i;
116                 y = j; 
117                 maze[x][y] = -1;//把走过的路径的值设为-1 
118                 
119                 if(x==m && y==n){//判断是否走到头,如果走到头 
120                     while(!isEmpty(p)){//如果栈不为空 
121                         popList(p,&temp);//弹栈
122                         printf("(%d,%d,%d),<-",temp.x,temp.y,temp.d);//打印路径 
123                     }
124                     //程序结束,销毁栈
125                     destory(&p);
126                     return 1; 
127                 }else{//如果能走通,但是却没有走完迷宫,把d置为0 
128                     d = 0;
129                 } 
130             } else{//如果路不通,换个方向在进行探索 
131                 d++; 
132             } 
133         } 
134          
135     }
136     //如果最后都没找到,说明迷宫没有通路
137         destory(&p);
138         return 0; 
139      
140 } 
141 
142 void main(){
143     item move[4];//定义一个控制探索路径的移动数组
144     //定义迷宫数组 
145      int maze[11][11]={
146                   {1,1,1,1,1,1,1,1,1,1,1},
147                  {1,0,0,0,1,0,1,1,1,0,1},
148                  {1,0,1,0,0,0,0,1,0,1,1},
149                  {1,0,0,1,0,0,0,1,0,0,1},
150                  {1,1,0,1,0,1,0,1,0,1,1},
151                  {1,0,1,0,1,0,0,1,0,0,1},
152                  {1,0,0,0,0,0,1,0,1,0,1},
153                  {1,1,1,1,0,1,0,0,0,0,1},
154                  {1,0,0,1,0,0,0,1,0,1,1},
155                  {1,0,0,0,0,1,0,1,0,0,1},
156                  {1,1,1,1,1,1,1,1,1,1,1}
157                  };
158     
159     //定义第一次移动 ,方向为北 
160     move[0].x = 0;
161     move[0].y = 1;
162     
163     //定义第二次移动,方向为南 
164     move[1].x = 0;
165     move[1].y = -1;
166     
167     //规定第三次移动,方向为东 
168     move[2].x = 1;
169     move[2].y = 0;
170     
171     //规定第三次移动,方向为西 
172     move[3].x = -1;
173     move[3].y = 0; 
174     
175     mazePath(maze,move,1,1); 
176 }
View Code

 

转载于:https://www.cnblogs.com/yghjava/p/6672064.html

### 模型预测控制(MPC)概述 模型预测控制是种基于优化理论的先进控制策略,其核心思想是在每个采样时刻解决个有限时间范围内的最优控制问题[^1]。通过滚动优化的方式,在当前状态下计算未来段时间内的最佳输入序列,并仅应用第个控制动作于实际系统。 #### MPC 的基本组成要素 MPC 控制器的设计通常涉及以下几个关键部分: - **动态模型**:描述系统的动态行为,可以是离散化后的状态空间形式或其他适合的形式。 - **目标函数**:定义性能指标,通常是使跟踪误差最小化的二次代价函数。 - **约束条件**:包括输入、输出以及状态变量的物理限制。 这些组成部分共同构成了 MPC 的优化框架,使得它能够处理复杂的工业过程并满足严格的运行需求[^2]。 --- ### MPC 实现方法 为了实现 MPC 控制器,般遵循以下技术路线: #### 动态建模 假设被控对象可以用如下离散时间的状态空间表示: \[ \mathbf{x}_{k+1} = A\mathbf{x}_k + B\mathbf{u}_k, \quad \mathbf{y}_k = C\mathbf{x}_k + D\mathbf{u}_k \] 其中 \(A\) 和 \(B\) 是系统矩阵,\(C\) 和 \(D\) 表示测量关系,\(\mathbf{x}\) 为状态向量,\(\mathbf{u}\) 为输入向量,\(\mathbf{y}\) 为输出向量[^3]。 #### 构造优化问题 对于给定的时间窗口长度 \(N_p\) (预测步长),需构建如下的二次规划 (Quadratic Programming, QP) 问题: \[ J = \sum_{k=0}^{N_p-1} (\|\mathbf{r}_k-\mathbf{y}_k\|_Q^2+\|\Delta\mathbf{u}_k\|_R^2)+\|\mathbf{e}_{N_p}\|_P^2 \] 这里的目标是最小化轨迹偏差和控制变化率的影响,权重矩阵 \(Q,R,P\) 分别对应输出误差、控制增量和平稳终端成本项[^1]。 #### 使用工具包求解 现代软件环境提供了多种高效算法来快速求解上述 QP 问题。例如 Python 中有 `CasADi` 库支持自动生成梯度信息从而加速收敛速度;MATLAB 则内置了 fmincon 或 quadprog 函数用于数值运算[^4]。 下面给出段简单的 MATLAB 示例代码展示如何利用 CasADi 工具箱完成双积分系统的 MPC 设计: ```matlab % 定义符号变量 nx = 2; nu = 1; x = SX.sym('x', nx); u = SX.sym('u', nu); sys = integrator(x,u); % 设置参数 Tf = .5; Np = 10; dt = Tf/Np; % 创建优化实例 opti = casadi.Opti(); X = opti.variable(nx,Np+1); U = opti.variable(nu,Np); J = sum((X(1,:)-ref).^2*dt)+sum(U.^2)*gamma; for k=0:Np-1, % 添加动力学约束 opti.subject_to(X(:,k+2)==... sys.map(Np)(X(:,k+1),U(:,k))); end % 边界条件和其他限制 opti.set_initial(randn(nx,1)); opti.solver('ipopt'); sol = opti.solve(); disp(sol.value(U)); % 输出结果 ``` 此脚本展示了从零开始搭建整个流程的过程,具体细节可根据项目调整适应不同场景的应用需求。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值