专题四 Problem L

本文介绍了一道编程题的解决方法,该题要求在一个n*m的矩阵中找到从左上角到右下角的最短路径。通过使用Dijkstra算法,并详细展示了如何根据特定的输入格式构建图模型来解决问题。
一、题目编号:
          1012
二、简单题意:
       给出一个n*m的矩阵,起点在矩形的左上角, 终点在右下角,里面一个小矩形代表一个街区(block)。每个小矩形的边长都是2520, 小矩形的边有一个速度限制,范围是0~9, 如果是0表示这条边不能行驶。关于输入方面(此题最恶心的地方),由上到下,从左到右,按照上图的对应的位置方式给出数据, 每一条边是 "数字"+“空格”+“符号”的形式, 数字表示这条边的限速, 符号表示这条路是单向(还分东西, 南北)的还是双向的。
三、解题思路形成过程
      输入部分也是醉了。。把图建出来然后dijkstra算法算就可以了。
四、感想
     读题太困难了,不百度题意直接看晕了。英语水平急需提高。。
五、AC代码
 #include<iostream>
 #include<cstdio>
 #include<cstring>
 #include<queue>
 #include<utility>
 using namespace std;

 typedef pair<int,int>pii;
 const int INF = 0x7fffffff;
 const int VN = 445;
 const int EN = VN*VN/2;

 struct Edge{
     int v, next, w;
 }E[EN];

 int n;
 int m;
 int vn;
 int size;
 int head[VN];
 int d[VN];

 void addEdge(int u,int v,int w){
     E[size].v=v;
     E[size].w=w;
     E[size].next=head[u];
     head[u]=size++;
 }
 void init(){
     vn=(m+1)*(n+1);
     size=0;
     memset(head, -1, sizeof(head));
 }

 void Dijkstra(int src){
     for(int i=1; i<=vn; ++i)d[i]=INF;
     d[src]=0;
     priority_queue<pii,vector<pii>,greater<pii> >q;
     q.push(make_pair(d[src],src));
     while(!q.empty()){
         pii x = q.top(); q.pop();
         int u=x.second;
         if(d[u]!=x.first)continue;
         for(int e=head[u]; e!=-1; e=E[e].next){
             int tmp=d[u]+E[e].w;
             if(d[E[e].v] > tmp){
                 d[E[e].v] = tmp;
                 q.push(make_pair(tmp,E[e].v));
             }
         }
     }
 }


 int main(){
     char str[100];
     int u,v,w;
     while(~scanf("%d%d%*c",&n,&m)&&n+m){
         // input
         init();
         for(int i=1; i<=n*2+1; ++i){
             gets(str);
             int len=strlen(str);
             if(i&1){
                 for(int j=0,k=1; j<len; j+=4,++k){
                     u=(m+1)*(i/2)+k;
                     w = str[j]-'0';
                     if(w==0)continue;
                     if(str[j+2]=='*'){
                         addEdge(u,u+1,2520/w);
                         addEdge(u+1,u,2520/w);
                     }
                     else if(str[j+2]=='<'){
                         addEdge(u+1,u,2520/w);
                     }
                     else{
                         addEdge(u,u+1,2520/w);
                     }
                 }
             }
             else{
                 for(int j=0,k=1; j<len; j+=4,++k){
                     u = (m+1)*(i/2-1)+k;
                     w = str[j]-'0';
                     if(w==0) continue;
                     if(str[j+2]=='*'){
                         addEdge(u, u+m+1, 2520/w);
                         addEdge(u+m+1, u, 2520/w);
                     }
                     else if(str[j+2]=='v'){
                         addEdge(u, u+m+1, 2520/w);
                     }
                     else if(str[j+2]=='^'){
                         addEdge(u+m+1, u, 2520/w);
                     }
                 }
             }
         }
         Dijkstra(1);
         if(d[vn]!=INF) printf("%d blips\n", d[vn]);
         else puts("Holiday");
     }
     return 0;
 }

<think>我们正在讨论pymop库中的Problem类。根据用户需求,需要了解Problem类的用法和定义。首先,pymop是一个用于多目标优化问题的Python库。Problem类是该库中定义优化问题的基础类。根据pymop文档,Problem类用于定义一个新的优化问题。用户需要继承这个基类并实现其中的方法,特别是`_evaluate`方法,该方法用于评估给定解的目标函数值和约束(如果有)。定义问题通常需要指定:-变量个数(n_var)-目标个数(n_obj)-约束个数(n_constr)-变量的类型(例如,实数、整数等)-变量的上下界然后,在`_evaluate`方法中,对于传入的种群(一组解),计算每个解的目标函数值和约束违反程度。下面是一个简单的示例,展示如何定义一个自定义问题:</think>### pymop.problemProblem 类的用法与定义 `pymop` 是 Python 中用于**多目标优化**的库,其核心 `Problem` 类用于定义优化问题。以下是关键要点: #### 1. Problem 类定义 ```python class Problem: def __init__(self, n_var: int, # 变量维度 n_obj: int, # 目标函数数量 n_constr: int = 0, # 约束数量(默认0) xl=None, # 变量下界 xu=None, # 变量上界 type_var=np.double): # 变量类型 self.n_var = n_var self.n_obj = n_obj self.n_constr = n_constr self.xl = xl self.xu = xu self.type_var = type_var def _evaluate(self, x: np.ndarray, # 决策变量矩阵 (n_pop x n_var) out: dict, # 输出字典 *args, **kwargs): # 需用户实现:计算目标函数和约束 out["F"] = ... # 目标矩阵 (n_pop x n_obj) out["G"] = ... # 约束矩阵 (n_pop x n_constr) ``` [^1] #### 2. 基础用法示例(ZDT1问题) ```python from pymop.problems import Problem import numpy as np class ZDT1(Problem): def __init__(self): super().__init__(n_var=30, n_obj=2, xl=0, xu=1) def _evaluate(self, x, out, *args, **kwargs): f1 = x[:, 0] # 第一个目标 g = 1 + 9.0 / (self.n_var - 1) * np.sum(x[:, 1:], axis=1) f2 = g * (1 - np.sqrt(f1 / g)) out["F"] = np.column_stack([f1, f2]) # 目标输出 # 使用问题 problem = ZDT1() x = np.random.rand(10, 30) # 10个解 out = {} problem.evaluate(x, out) print(out["F"].shape) # (10, 2) ``` #### 3. 关键特性 - **变量边界**:通过 `xl` 和 `xu` 设置(标量或向量),例如 `xl=[0,0], xu=[1,2]` - **约束处理**:在 `out["G"]` 中返回违反约束的值($\leq 0$ 表示可行) - **并行评估**:通过 `evaluate_all()` 支持并行计算[^2] - **内置问题**:库预置了 `ZDT`, `DTLZ`, `CEC` 等标准测试问题 #### 4. 高级用法 **带约束的自定义问题:** ```python class MyConstraintProblem(Problem): def __init__(self): super().__init__(n_var=2, n_obj=1, n_constr=1, xl=-5, xu=5) def _evaluate(self, x, out, *args, **kwargs): out["F"] = np.sum(x**2, axis=1) # 目标:最小化x1²+x2² out["G"] = x[:, 0] + x[:, 1] - 1 # 约束:x1 + x2 ≤ 1 ``` **使用预置问题:** ```python from pymop.problems.zdt import ZDT2 problem = ZDT2(n_var=10) # 10维变量 x0 = np.array([0.5] * 10) print("目标值:", problem.evaluate(x0)["F"]) ``` ### 注意事项 1. 必须重写 `_evaluate` 方法,否则抛出 `NotImplementedError` 2. 目标函数需最小化(最大化问题需手动转换) 3. 变量边界未设置时默认为 `None`(需在评估函数中检查可行性)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值