【ESPPRC问题】数学模型与CPLEX求解

一、问题描述

在这里插入图片描述
此时cij为距离dij,也就是在容量约束、时间窗约束、每个客户点只能访问一次约束下求得起点到终点的最短路径。

ESPPRC问题是VRPTW问题的一个子问题,即VRPTW是多辆车的路径规划,而ESPPRC是里面一辆车时的路径规划,找出一辆车的可行路径。

二、数学模型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、CPLEX求解

3.1 程序结构

3.1.1 主方法运行

  1. 记录求解时间
  2. 读取数据
  3. 初始化参数
  4. 测试数据集
  5. cplex求解与结果打印
  6. 检验解结果

3.1.2 读取数据

IO流

运用string.split()方法对文本进行切割

3.1.3 初始化参数

总点数、坐标、时间窗、需求量、服务时间数据、距离矩阵、无向图构建

3.1.4 测试数据(可有可无)

判断时间与需求数据是否有误

3.1.5 cplex建模求解

变量不仅仅是决策变量,也还可以是约束中的所需变量

cplex.addLe(a,b)方法指a<=b,注意别写成addLe(b,a)了

3.1.6 检验解结果

测试解的某些数据是否对应算例的数据,该解测试其车容量、时间窗是否满满足要求

注意两个整数值转成double值进行比较大小时,有精度误差,需要加上或者减去一定大的小数

3.2 算例(Solomon经典算例C101(100))

VEHICLE
NUMBER     CAPACITY
  25         200

CUSTOMER
CUST NO.  XCOORD.   YCOORD.    DEMAND   READY TIME  DUE DATE   SERVICE   TIME
 
    0      40         50          0          0       1236          0   
    1      45         68         10        912        967         90   
    2      45         70         30        825        870         90   
    3      42         66         10         65        146         90   
    4      42         68         10        727        782         90   
    5      42         65         10         15         67         90   
    6      40         69         20        621        702         90   
    7      40         66         20        170        225         90   
    8      38         68         20        255        324         90   
    9      38         70         10        534        605         90   
   10      35         66         10        357        410         90   
   11      35         69         10        448        505         90   
   12      25         85         20        652        721         90   
   13      22         75         30         30         92         90   
   14      22         85         10        567        620         90   
   15      20         80         40        384        429         90   
   16      20         85         40        475        528         90   
   17      18         75         20         99        148         90   
   18      15         75         20        179        254         90   
   19      15         80         10        278        345         90   
   20      30         50         10         10         73         90   
   21      30         52         20        914        965         90   
   22      28         52         20        812        883         90   
   23      28         55         10        732        777         90   
   24      25         50         10         65        144         90   
   25      25         52         40        169        224         90   
   26      25         55         10        622        701         90   
   27      23         52         10        261        316         90   
   28      23         55         20        546        593         90   
   29      20         50         10        358        405         90   
   30      20         55         10        449        504         90   
   31      10         35         20        200        237         90   
   32      10         40         30         31        100         90   
   33       8         40         40         87        158         90   
   34       8         45         20        751        816         90   
   35       5         35         10        283        344         90   
   36       5         45         10        665        716         90   
   37       2         40         20        383        434         90   
   38       0         40         30        479        522         90   
   39       0         45         20        567        624         90   
   40      35         30         10        264        321         90   
   41      35         32         10        166        235         90   
   42      33         32         20         68        149         90   
   43      33         35         10         16         80         90   
   44      32         30         10        359        412         90   
   45      30         30         10        541        600         90   
   46      30         32         30        448        509         90   
   47      30         35         10       1054       1127         90   
   48      28         30         10        632        693         90   
   49      28         35         10       1001       1066         90   
   50      26         32         10        815        880         90   
   51      25         30         10        725        786         90   
   52      25         35         10        912        969         90   
   53      44          5         20        286        347         90   
   54      42         10         40        186        257         90   
   55      42         15         10         95        158         90   
   56      40          5         30        385        436         90   
   57      40         15         40         35         87         90   
   58      38          5         30        471        534         90   
   59      38         15         10        651        740         90   
   60      35          5         20        562        629         90   
   61      50         30         10        531        610         90   
   62      50         35         20        262        317         90   
   63      50         40         50        171        218         90   
   64      48         30         10        632        693         90   
   65      48         40         10         76        129         90   
   66      47         35         10        826        875         90   
   67      47         40         10         12         77         90   
   68      45         30         10        734        777         90   
   69      45         35         10        916        969         90   
   70      95         30         30        387        456         90   
   71      95         35         20        293        360         90   
   72      53         30         10        450        505         90   
   73      92         30         10        478        551         90   
   74      53         35         50        353        412         90   
   75      45         65         20        997       1068         90   
   76      90         35         10        203        260         90   
   77      88         30         10        574        643         90   
   78      88         35         20        109        170         90   
   79      87         30         10        668        731         90   
   80      85         25         10        769        820         90   
   81      85         35         30         47        124         90   
   82      75         55         20        369        420         90   
   83      72         55         10        265        338         90   
   84      70         58         20        458        523         90   
   85      68         60         30        555        612         90   
   86      66         55         10        173        238         90   
   87      65         55         20         85        144         90   
   88      65         60         30        645        708         90   
   89      63         58         10        737        802         90   
   90      60         55         10         20         84         90   
   91      60         60         10        836        889         90   
   92      67         85         20        368        441         90   
   93      65         85         40        475        518         90   
   94      65         82         10        285        336         90   
   95      62         80         30        196        239         90   
   96      60         80         10         95        156         90   
   97      60         85         30        561        622         90   
   98      58         75         20         30         84         90   
   99      55         80         10        743        820         90   
  100      55         85         20        647        726         90  

3.3 java+cplex源码

package test;

import ilog.concert.*;
import ilog.cplex.IloCplex;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * ClassName: ESPPRC
 * Package: test
 * Description:cplex求解ESPPRC问题
 *
 * @Author:
 * @Create: 2023/6/12 - 17:56
 * @Version:
 */
public class ESPPRC {
    int locationNum;//总点数
    int vehicleNum;//车子总数
    double[] locationData;//[x,y,d,a,b,s],坐标+需求+时间窗+服务时间,读取数据用
    List<double[]> locationList;//存储点数据的集合,读取数据用
    double[][] location;//存储每个点的坐标[x,y]
    int[][] arcs;//弧,arcs[i][j]表示i到j点的弧,值为1则此弧存在,值为0则此弧不存在
    double[][] distance;//两点之间的距离矩阵,满足三角关系,暂用距离表示花费c[i][j]=distance[i][j]
    double[] a;//时间窗[ai,bi]
    double[] b;//时间窗[ai,bi]
    double E;//仓库点(起始点、终点)时间窗[E,l]
    double L;//仓库点(起始点、终点)时间窗[E,l]
    double C;//车子的总容量
    double CMin;//车子最低载货量
    double[] d;//每个点的需求di
    double[] s;//每个点的服务时间
    List<Integer> route;//存储车的路径回路(用于结果输出)
    List<Double> arriveTime;//存储车到达每个地点的时刻(用于结果的检验)

    //读取数据
    public List<double[]> dataInput(String path){
        File file;
        FileInputStream fileInputStream = null;
        StringBuilder sb = null;
        try {
            file = new File(path);//创建文件对象
            fileInputStream = new FileInputStream(file);//创建字节输入流对象,导入文件
            //读入数据
            int len;
            sb = new StringBuilder();//创建该对象,将文本内容转为字符串存储到该对象中
            while ((len = fileInputStream.read()) != -1){
                sb.append((char)len);//append()方法将一个个(char)len字符存储字符串中
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();//关闭数据
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //将读取到的数据传到List<double[]> locationList中
        String[] data = sb.toString().split("\n");//将文本内容按行存储进字符串数组中
        String[] data1 = data[2].split("\\s+");//将第三行的数据按空格分开,存储进字符串数组中
        vehicleNum = Integer.parseInt(data1[1]);
        C = Integer.parseInt(data1[2]);//每辆车总容量
        locationData = new double[6];//数据数组初始化
        locationList = new ArrayList<>();//数据集合初始化
        for (int i = 7;i < data.length;i++){//将起始点与客户点数据传输到数组和集合里
            String[] data2 = data[i].split("\\s+");
            locationData[0] = Double.parseDouble(data2[2]);//坐标x
            locationData[1] = Double.parseDouble(data2[3]);//坐标y
            locationData[2] = Double.parseDouble(data2[4]);//需求d
            locationData[3] = Double.parseDouble(data2[5]);//时间窗a
            locationData[4] = Double.parseDouble(data2[6]);//时间窗b
            locationData[5] = Double.parseDouble(data2[7]);//服务时间s
            locationList.add(locationData.clone());
        }
        //将终点传输到数组和集合里,终点数据即起点数据,只是编号不一样而已
        String[] data2 = data[7].split("\\s+");
        locationData[0] = Double.parseDouble(data2[2]);//坐标x
        locationData[1] = Double.parseDouble(data2[3]);//坐标y
        locationData[2] = Double.parseDouble(data2[4]);//需求d
        locationData[3] = Double.parseDouble(data2[5]);//时间窗a
        locationData[4] = Double.parseDouble(data2[6]);//时间窗b
        locationData[5] = Double.parseDouble(data2[7]);//服务时间s
        locationList.add(locationData.clone());

        return locationList;//返回数据集合,包含起点、终点、客户点,共n+2各点
    }

    //初始化参数及问题初始条件
    public void init(){
        locationNum = locationList.size();//总点数
        //坐标、时间窗、需求量、服务时间数据
        location = new double[locationNum][2];//数组初始化
        a = new double[locationNum];
        b = new double[locationNum];
        d = new double[locationNum];
        s = new double[locationNum];
        for (int i = 0;i < locationNum;i++){//取数据
            location[i][0] = locationList.get(i)[0];//x坐标
            location[i][1] = locationList.get(i)[1];//y坐标
            a[i] = locationList.get(i)[3];
            b[i] = locationList.get(i)[4];
            d[i] = locationList.get(i)[2];
            s[i] = locationList.get(i)[5];
        }

        //车子最低载货量
        double demandSum = 0.0;
        for (int i = 0;i < locationNum;i++){
            demandSum = demandSum + d[i];
        }
        CMin = demandSum / vehicleNum;

        //仓库点的时间窗,即起点和终点的时间窗
        E = a[0];
        L = b[0];

        //两点之间距离的获取
        distance = new double[locationNum][locationNum];
        for (int i = 0;i < locationNum;i++){
            for (int j = i;j < locationNum;j++){
                if (i == j){
                    distance[i][j] = Double.MAX_VALUE;//不能自己到达自己,设置距离为无限大
                } else {//欧式距离
                    distance[i][j] = Math.sqrt(Math.pow(location[i][0] - location[j][0],2) + Math.pow(location[i][1] - location[j][1],2));
                    distance[j][i] = distance[i][j];
                }
            }
        }
        //三点之间的距离满足三角关系,即a+b<c
        for (int k = 0;k < locationNum;k++){
            for (int i = 0;i < locationNum;i++){
                for (int j = 0;j < locationNum;j++){
                    if (distance[i][j] > distance[i][k] + distance[k][j]){
                        distance[i][j] = distance[i][k] + distance[k][j];
                    }
                }
            }
        }

        //G=(V,A)无向图的构建,去除掉某些不符合原始数据条件的弧和规定了起点和终点是单向弧后所得的图
        arcs = new int[locationNum][locationNum];//无向图中的弧
        for (int i = 0;i < locationNum;i++){//初始化完全图
            for (int j = 0;j < locationNum;j++){
                if (i != j){//其余i==j的弧值默认为0(数组默认值)
                    arcs[i][j] = 1;
                }
            }
        }
        for (int i = 0;i < locationNum;i++){//除掉某些不符合时间数据和容量数据的弧
            for (int j = 0;j < locationNum;j++){
                if (i != j){
                    if (a[i] + s[i] + distance[i][j] > b[j] + 0.0001){//不能晚到
                        arcs[i][j] = 0;
                    }
                    if (d[i] + d[j] > C){
                        arcs[i][j] = 0;
                    }
                }
            }
        }
        //起点和终点是单向弧,起点只能出不能进,终点只能进不能出
        for (int i = 0;i < locationNum;i++){
            arcs[i][0] = 0;
            arcs[locationNum - 1][i] = 0;
        }
        arcs[0][locationNum - 1] = 0;//起点不能直接到达终点
    }

    //测试数据集是否有误
    public void testData(){
        for (int i = 0;i < locationNum;i++){
            for (int j = 0;j < locationNum;j++){
                if (i != j){
                    if (a[0] + distance[0][i] + s[i] + distance[i][locationNum - 1] > b[locationNum - 1]){
                        //从起始点出发,最早到达i点,再到达终点时,判断其所花费的时间是否满足整个过程的时间窗,不满足则该数据集有误
                        System.out.println("The calculating example is false!");
                    }
                }
            }
        }
        //最小值min1=最晚到达i点的时间(即时间窗bi) - 起始点到i点所花费的时间(距离),如果min1比整个过程的时间窗E还小,则数据集有误
        //最小值min2=最早到达i点的时间(即时间窗ai)+ i点的服务时间 + i点到终点所花费的时间(距离),如果min2比整个过程的时间窗L还大,则数据集有误
        double min1 = Double.MAX_VALUE;
        double min2 = Double.MAX_VALUE;
        for (int i = 1;i < locationNum - 1;i++){
            if (b[i] - distance[0][i] < min1){
                min1 = b[i] - distance[0][i];
            }
            if (a[i] + s[i] + distance[i][locationNum - 1] < min2){
                min2 = a[i] + s[i] + distance[i][locationNum - 1];
            }
        }
        if (E > min1 || L < min2){
            System.out.println("Duration false!");
            System.exit(0);
        }
        //如果一个地点的需求量超过一辆车的容量,则数据集有误
        for (int i = 0;i < locationNum;i++){
            if (d[i] > C){
                System.out.println("Demand false!");
            }
        }
    }

    //CPLEX建模求解
    public void cplexSolve() throws IloException{
        //建立模型
        IloCplex cplex = new IloCplex();
        //决策变量
        IloIntVar[][] x = new IloIntVar[locationNum][locationNum];//0 1变量,xij=1时表示车从i点到j点
        IloNumVar[] w = new IloNumVar[locationNum];//wi表示车子访问i点时的到达时刻
        for (int i = 0;i < locationNum;i++){
            for (int j = 0;j < locationNum;j++){
                if (arcs[i][j] == 0){//弧不存在时,变量即不存在
                    x[i][j] = null;
                } else {
                    x[i][j] = cplex.intVar(0,1);
                }
            }
            w[i] = cplex.numVar(0,1e15, IloNumVarType.Float);//定义域定大一些,需大于时间窗L
        }

        //目标函数:距离最小值
        IloLinearNumExpr expr = cplex.linearNumExpr();
        for (int i = 0;i < locationNum;i++){
            for (int j = 0;j < locationNum;j++){
                if (arcs[i][j] == 1){//添加有弧的式子
                    expr.addTerm(distance[i][j],x[i][j]);
                }
            }
        }
        cplex.addMinimize(expr);

        //约束条件
        //车必须从起始点0开始出发
        IloLinearNumExpr expr2 = cplex.linearNumExpr();
        for (int j = 1;j < locationNum;j++){
            if (arcs[0][j] == 1) {
                expr2.addTerm(1, x[0][j]);
            }
        }
        cplex.addEq(1,expr2);
        //每辆车必须在终点处停
        IloLinearNumExpr expr3 = cplex.linearNumExpr();
        for (int i = 0;i < locationNum - 1;i++){
            if (arcs[i][locationNum - 1] == 1) {
                expr3.addTerm(1, x[i][locationNum - 1]);
            }
        }
        cplex.addEq(1,expr3);
        //车到达一个客户点后必须从该客户点出发,不能停留在该客户点(流平衡)
        for (int j = 1;j < locationNum - 1;j++){
            IloLinearNumExpr expr4 = cplex.linearNumExpr();
            for (int i = 0;i < locationNum;i++){
                if (arcs[i][j] == 1){
                    expr4.addTerm(1,x[i][j]);
                }
                if (arcs[j][i] == 1){
                    expr4.addTerm(-1,x[j][i]);
                }
            }
            cplex.addEq(0,expr4);
        }
        //地点到达时间前后关系约束,同时可以用来防止子回路的产生,并且约束了车子只能访问一次客户点
        double M = 1e5;//一个足够大但得尽量小的数
        for (int i = 0;i < locationNum;i++){
            for (int j = 0;j < locationNum;j++){
                if (arcs[i][j] == 1){
                    IloLinearNumExpr expr5 = cplex.linearNumExpr();
                    expr5.addTerm(1,w[i]);
                    expr5.addTerm(-1,w[j]);
                    expr5.addTerm(M,x[i][j]);
                    cplex.addLe(expr5,M - s[i] - distance[i][j]);
                }
            }
        }
        //车到达i点的时刻必须在时间窗之内
        for (int i = 1;i < locationNum - 1;i++){
            IloLinearNumExpr expr6 = cplex.linearNumExpr();
            IloLinearNumExpr expr7 = cplex.linearNumExpr();
            for (int j = 0;j < locationNum;j++){
                if (arcs[i][j] == 1){
                    expr6.addTerm(a[i],x[i][j]);
                    expr7.addTerm(b[i],x[i][j]);
                }
            }
            cplex.addLe(expr6,w[i]);
            cplex.addLe(w[i],expr7);
        }
        //车从起点0出发和到达终点的时刻必须在整个过程的时间窗[E,L]之内(限制了总流程的时间范围)
        IloLinearNumExpr expr8 = cplex.linearNumExpr();
        IloLinearNumExpr expr9 = cplex.linearNumExpr();
        expr8.addTerm(1,w[0]);
        expr9.addTerm(1,w[locationNum - 1]);
        cplex.addLe(E,expr8);
        cplex.addLe(expr8,L);
        cplex.addLe(E,expr9);
        cplex.addLe(expr9,L);
        //车到达的点的需求量总和不超过车容量,且不少于车子的一定容量(客户点需求量之和除以总车辆数)
        IloLinearNumExpr expr10 = cplex.linearNumExpr();
        for (int i = 1;i < locationNum - 1;i++){
            for (int j = 0;j < locationNum;j++){
                if (arcs[i][j] == 1){
                    expr10.addTerm(d[i],x[i][j]);
                }
            }
        }
        cplex.addLe(expr10,C);
        cplex.addLe(CMin,expr10);

        //求解结果输出
        cplex.setOut(null);//关闭cplex求解的过程数据
        route = new ArrayList<>();//存储车的路径回路(用于结果输出)
        arriveTime = new ArrayList<>();//存储车到达每个地点的时刻(用于结果的检验)
        double obj;//目标函数值
        double demand = 0.0;//车子在该条路径中的载货量
        //判断建立的数学模型是否有解
        if (cplex.solve() == false){
            //模型无解
            System.out.println("The problem should not solve!!!");
            return;//若无解,则跳出cplexSolve()方法
        } else {
            //模型有解,生成车辆路径
            route.add(0);//添加起始点0
            arriveTime.add(0.0);//添加起点到达时刻
            int i = 0;
            while (true){
                for (int j = 0;j < locationNum;j++){
                    if (arcs[i][j] == 1 && cplex.getValue(x[i][j]) > 1e-06){
                        route.add(j);
                        arriveTime.add(cplex.getValue(w[j]));
                        i = j;
                        break;
                    }
                }
                if (i == locationNum - 1){
                    break;
                }
            }
        }
        obj = cplex.getObjValue();//获取目标函数值
        for (int i = 0;i < route.size();i++){
            demand = demand + d[route.get(i)];
        }
        //打印结果
        System.out.println("最优路径为:" + route);
        System.out.println("车子载货量为:" + demand);
        System.out.println("最短路径长度为:" + obj);
    }

    //检验解的正确性
    public void checkSolution(){
        //解中车的车辆载荷是否超过车容量的判断
        double capacity = 0;
        for (int i = 0;i < route.size();i++){
            capacity += d[route.get(i)];
        }
        if (capacity > C){
            System.out.println("error:Capacity!!!");
            System.exit(0);
        }
        if (capacity < CMin) {
            System.out.println("可行路径,该路径的车载量小于车载量平均水平");
        }
        //解中时间窗可行性判断
        for (int i = 0;i < route.size() - 1;i++){
            int origin = route.get(i);
            int destination = route.get(i + 1);
            double originTime = arriveTime.get(i);
            double destinationTime = arriveTime.get(i + 1);
            if (originTime < a[origin] && destinationTime > b[destination]){//到达时间不在时间窗范围内
                System.out.println("Error:arriveTime!!!");
                System.exit(0);
            }
            if (originTime + s[origin] + distance[origin][destination] > b[destination] + 0.0001){//从i点到j点,到达j点时超过了j点的时间窗
                System.out.println(origin + "->" + destination);
                System.out.println("Error:be late!");
                System.exit(0);
            }
            if (destinationTime - s[origin] - distance[origin][destination] < a[origin] - 0.0001){//double精度问题,两个整数值相等,换算成double值时不一定相等,容易造成误差,故在两个double值比较大小时,得加或者减去一定大的小数以消除精度差
                double temp = destinationTime - s[origin] - distance[origin][destination];
                System.out.println(origin + "->" + destination + ":" + temp);
                System.out.println("Error!");
                System.exit(0);
            }
        }
    }

    //主方法运行
    public static void main(String[] args) throws IloException {
        long startTime = System.currentTimeMillis();//开始时间(毫秒),该时间返回的是long值
        ESPPRC espprc = new ESPPRC();
        espprc.dataInput("D:\\IDEA2022\\IDEA projects\\algorithm implementation\\CplexTest\\VRPTWDATAC101(100).txt");//读取数据,手动修改文件
        System.out.println("Input successfully!!");
        System.out.println("cplex求解器求解ESPPRC问题:" + (espprc.locationList.size() - 2) + "个客户点");
        espprc.init();//初始化参数
        espprc.testData();//测试数据集是否有误
        espprc.cplexSolve();//cplex求解及结果输出
        espprc.checkSolution();//检查求解结果是否正确
        System.out.println("程序运行时间:" + (System.currentTimeMillis() - startTime) / 1000d + "s");//所花费的时间,1000d指1000是double值,也就是1000.0
    }
}

结果展示

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
TSP(Traveling Salesman Problem,旅行商问题)是一个NP难问题,是一类重要的组合优化问题,其目标是在给定的城市中找到一条最短的路径,使得每个城市都被访问一次且仅访问一次,并返回起点城市。下面是一个TSP问题的模型及cplex求解代码。 模型: 我们将城市表示为节点,将城市之间的距离表示为边。下面是一个TSP问题的模型: - 变量:对于每一对城市i和j,定义二元变量x[i][j],表示是否从城市i到城市j。 - 目标函数:最小化所有城市之间的距离之和,即minimize(sum(d[i][j]*x[i][j])). - 约束条件: - 每个城市只能被访问一次,即对于每个城市i,sum(x[i][j])=1。 - 从每个城市出发,只能到达一个城市,即对于每个城市j,sum(x[i][j])=1。 - 排除子回路,即对于任意的子集S(包含两个或两个以上的城市),满足sum(x[i][j])>=2,其中i和j分别为S中的任意两个城市。 cplex求解代码: 下面是一个使用cplex求解TSP问题的Python代码示例: ```python import cplex import numpy as np # 定义问题数据 n = 5 # 城市数量 cities = np.arange(n) # 城市编号 d = np.random.rand(n,n) # 城市之间的距离 # 创建cplex模型 prob = cplex.Cplex() prob.objective.set_sense(prob.objective.sense.minimize) # 添加变量 x = {} for i in cities: for j in cities: if i != j: x[i,j] = prob.variables.add(names=["x({},{})".format(i,j)], lb=[0], ub=[1], types=["B"]) # 添加约束条件 for i in cities: prob.linear_constraints.add(lin_expr=[cplex.SparsePair(ind=[x[i,j] for j in cities if j != i], val=[1]* (n-1))], senses=["E"], rhs=[1]) for j in cities: prob.linear_constraints.add(lin_expr=[cplex.SparsePair(ind=[x[i,j] for i in cities if i != j], val=[1]* (n-1))], senses=["E"], rhs=[1]) for S in range(2, n): for i in cities: idx = [j for j in cities if j != i] for T in itertools.combinations(idx, S-1): T = list(T) for j in T: idx.remove(j) prob.linear_constraints.add(lin_expr=[cplex.SparsePair(ind=[x[i,j] for j in T+idx], val=[1]* S + [1]* (n-S))], senses=["G"], rhs=[1]) # 设置目标函数 prob.objective.set_linear([(x[i,j], d[i,j]) for i in cities for j in cities if i != j]) # 求解问题 prob.solve() # 输出结果 print("Solution status = ", prob.solution.get_status()) print("Optimal value = ", prob.solution.get_objective_value()) for i in cities: for j in cities: if i != j and prob.solution.get_values(x[i,j]) > 0: print("x({},{}) = {}".format(i,j,prob.solution.get_values(x[i,j]))) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值