c++调用cplex求解例子_C++调用cplex求解VRPTW模型(源代码)

31a3106e7d19679f7b89e60dc73d701e.gif

哈喽,大家好,好久不见,今天给大家分享一个团队小伙伴整理的一个C++调用Cplex求解VRPTW问题的源代码。

欢迎关注团队小伙伴的CSDN博客,博主名为“ZhaoDongqiang”

欢迎关注哔哩哔哩UP主:“我家公子Q”。

坚持、努力;你我同行!Born to fight!

34695f5a53017d03965e30dc838e6ec2.png

目录VRPTW问题简介VRPTW数学模型C++调用Cplex进行求解VRPTW是什么鬼?定义

VRPTW是个什么鬼呢?是VR嘛?要买3D眼镜才能搞的研究?

189ec92bec744508619dc09b4dd0a893.png

VRPTW的全称是vehicle routing problems with time windows,翻译为有时间窗的车辆路径问题,是VRP问题的变种。

简单描述一下:VRP是指一定数量的客户,各自有不同数量的货物需求,配送中心向客户提供货物,由一个车队负责分送货物,组织适当的行车路线,目标是使得客户的需求得到满足,并能在一定的约束下,达到诸如路程最短、成本最小、耗费时间最少等目的。后面的时间窗就是指每位顾客的服务时间是有要求的,包括最早开始时间、最晚开始时间,二者之差就形成了服务的时间窗。

就像你有个快递,你给快递小哥哥打电话,(很傲娇)说:“快递我上午就要,送我宿舍来,9点到11点,要是晚了,本仙女就要生气了。”这样你服务的时间窗就是服务9点到11点这一段时间。(最好别这样昂,快递小哥也不容易,除非他是你男朋友)

VRPTW数学模型及求解一数学模型

    好了,我知道这个问题的意思啦,然后呢?一脸懵逼啊。

07150ba9d9799390d50df31c1bbd0490.png

然后当然是建模啊,建立该问题的数学模型。小编这里直接贴上了。

feed4e29c7ecfe6a1ed1b5fb13e9b2a5.png

释义如下:

(1)目标函数为最小化成本或者时间。(2)约束1:每个顾客只能被访问一次;约束2:车辆的载重限制。(3)约束3-5:车辆从depot(0)出发回到depot(n+1)。(4)约束6:车辆数量限制。(5)约束7-8:时间窗约束。

d8374ca26b274af1101020058a5063cd.png二C++调用Cplex求解

    就这?这还用什么Cplex?瞧着,本仙儿给你心算,叫你瞅瞅什么叫真正的实力。

。。。

心算中

。。。

41411a06de633306733343cffd14f018.png

emm...

那什么...

小编,你说到哪了?你接着说啊!

(小编:好的吧。。。)

    其实也不咋难,我们需要先了解下C++调用Cplex时多维变量的创建。

(1)多维变量的创建

    IloNumVarArray类,只能定义一维的数组,而这里的模型中需要用到三维和二维的变量。Cplex C++ 接口提供了一个lloArray类模版,我们可以利用此类模版定义多维数组。

    比如二维变量数组,在头文件中做如下定义:

1typedef IloArray NumVarMatrix; 

接下来,便可以用NumVarMatrix定义二维变量。

1NumVarMatrix s(env, v_num);
2for (IloInt k = 0; k 3{
4    s[k] = IloNumVarArray(env, c_num + 2);
5    for (IloInt i = 0; i 2; i++)
6    {
7        s[k][i] = IloNumVar(env, ILOINT);
8    }
9}

三维数组也是同样的方法:

1typedef IloArray NumVarMatrix; 2typedef IloArray NumVar3Matrix;

(2)C++调用cplex求解VRPTW完整代码

  1#include 
2#include 
3#include 
4#include 
5typedef IloArray IntVarMatrix;   6typedef IloArray NumVarMatrix;   7typedef IloArray NumVar3Matrix;  8typedef IloArray IntMatrix;   9typedef IloArray NumMatrix;    10typedef IloArray Num3Matrix;     11 12ILOSTLBEGIN //#define ILOSTLBEGIN using namespace std; 13 14int main(int argc, char **argv)    15{ 16    IloEnv env; 17 18    IloModel model(env); 19 20    const int M = 10000; 21    const int v_num = 3, capacity = 500, c_num = 25; 22    float xcord[c_num + 2], ycord[c_num + 2], t_service[c_num + 2]; 23    int demand[c_num + 2], lbtw[c_num + 2], ubtw[c_num + 2]; 24 25    //从txt文件中读取客户信息_____x,ycord,demand,tw,time_service 26    ifstream inn; 27    inn.open("vrptw.txt"); 28    if (inn) 29    { 30        for (int j = 0; j 2; j++) { 31            inn >> xcord[j], inn >> ycord[j], inn >> demand[j], inn >> lbtw[j], inn >> ubtw[j], inn >> t_service[j]; 32        } 33    } 34    inn.close(); 35 36    float distance[c_num + 2][c_num + 2], time[c_num + 2][c_num + 2]; 37 38    //数据初始化,计算客户之间的距离以及访问时长 39    for (int i = 0; i 2; i++) { 40        for (int j = 0; j 2; j++) { 41            if (i == j) { 42                distance[i][j] = 0; 43                time[i][j] = 0; 44            } 45            else{ 46                distance[i][j] = floor(sqrt((xcord[i] - xcord[j]) * (xcord[i] - xcord[j]) + (ycord[i] - ycord[j]) * (ycord[i] - ycord[j]))*10)/10; 47                time[i][j] = distance[i][j] + t_service[i]; 48            }    49        } 50    } 51 52    //三维决策变量x[k][i][j],1 if a vehicle drives directly from customer i to customer j 53    NumVar3Matrix x(env, v_num); 54    for (IloInt k = 0; k  55    { 56        x[k] = NumVarMatrix(env, c_num + 2); 57        for (IloInt i = 0; i 2; i++) 58        { 59            x[k][i] = IloNumVarArray(env, c_num + 2); 60            for (IloInt j = 0; j 2; j++) { 61                x[k][i][j] = IloNumVar(env, 0, 1, ILOBOOL); 62            } 63        } 64    } 65 66    //二维决策变量s[k][i],the time a vehicle starts to service a customer 67    NumVarMatrix s(env, v_num); 68    for (IloInt k = 0; k  69    { 70        s[k] = IloNumVarArray(env, c_num + 2); 71        for (IloInt i = 0; i 2; i++) 72        { 73            s[k][i] = IloNumVar(env, ILOINT); 74        } 75    } 76 77    //约束1 对角元素为0 78    for (int k = 0; k  79        for (int i = 0; i 2; i++) { 80            model.add(x[k][i][i] == 0); 81        } 82    } 83 84    //约束2 Each customer is visited exactly once 85    IloExpr sum_xkij(env); 86    for (int i = 1; i 1; i++) { 87        sum_xkij.clear(); 88        for (int k = 0; k  89            for (int j = 0; j 2; j++) { 90                sum_xkij += (x[k][i][j]); 91            } 92        } 93        model.add(sum_xkij == 1); 94    } 95 96    //约束3 A vehicle can only be loaded up to it's capacity 97    IloExpr sum_demand(env); 98    for (int k = 0; k  99        sum_demand.clear();100        for (int i = 1; i 1; i++) {101            for (int j = 0; j 2; j++) {102                sum_demand += (demand[i] * x[k][i][j]);103            }104        }105        model.add(sum_demand <= capacity);106    }107108    //约束4 Each vehicle must leave the depot 0109    IloExpr sum_xk0j(env);110    for (int k = 0; k 111        sum_xk0j.clear();112        for (int j = 0; j 2; j++) {113            sum_xk0j += (x[k][0][j]);114        }115        model.add(sum_xk0j == 1);116    }117118    //约束5 After a vehicle arrives at a customer it has to leave for another destination119    IloExpr sumxi(env), sumxj(env);120    for (int h = 1; h 1; h++) {121        for (int k = 0; k 122            sumxi.clear(); sumxj.clear();123            for (int i = 0; i 2; i++) {124                sumxi += (x[k][i][h]);125                sumxj += (x[k][h][i]);126            }127            model.add(sumxi - sumxj == 0);128        }129    }130131    //约束6 All vehicles must arrive at the depot n + 1132    IloExpr sumxki(env);133    for (int k = 0; k 134        sumxki.clear();135        for (int i = 0; i 2; i++) {136            sumxki += (x[k][i][c_num + 1]);137        }138        model.add(sumxki == 1);139    }140141    //约束7 The time windows are observed142    for (int i = 0; i 2; i++) {143        for (int k = 0; k 144            model.add(s[k][i] <= ubtw[i]);145            model.add(s[k][i] >= lbtw[i]);146        }147    }148149    //约束8 From depot departs a number of vehicles equal to or smaller than v150    IloExpr s1(env);151    for (int k = 0; k 152        for (int j = 0; j 2; j++) {153            s1 += (x[k][0][j]);154        }155    }156    model.add(s1 <= v_num);157158    //约束9 Vehicle departure time from a customer and its immediate successor159    for (int i = 0; i 2; i++) {160        for (int j = 0; j 2; j++) {161            for (int k = 0; k 162                model.add(s[k][i] + time[i][j] - M * (1 - x[k][i][j]) <= s[k][j]);163            }164        }165    }166167    //目标函数168    IloExpr obj(env);169    for (int k = 0; k 170        for (int i = 0; i 2; i++) {171            for (int j = 0; j 2; j++) {172                obj += distance[i][j] * x[k][i][j];173            }174        }175    }176    model.add(IloMinimize(env, obj));177178    //创建求解对象179    IloCplex cplex(model);180181    //处理异常182    cout <"begin to solve." <endl;183184    try185    {186        if (!cplex.solve())187        {188            cout <"求解失败" <endl;189            if ((cplex.getStatus() == IloAlgorithm::Infeasible) ||190                (cplex.getStatus() == IloAlgorithm::InfeasibleOrUnbounded))191            {192                cout <endl <"No solution - starting Conflict refinement" <endl;193            }194195            env.error() <"Failed to optimize LP." <endl;196            throw(-1);197        }198        cout <"异常处理完毕" <endl;199200        env.out() <"Solution status = " <endl;201        env.out() <"Solution value = " <endl;202    }203204    catch (IloException& e)205    {206        cerr <"Concert exception caught: " <endl;207        //save results208    }209    catch (...)210    {211        cerr <"Unknown exception caught" <endl;212    }213214    //输出VRP路线215    cout <"Solutions: " <endl;216    for (int k = 0; k 217    {218        cout <"vehicle " <1 <" :" <endl;219        for (int i = 0; i <= c_num + 1; i++) 220        {221            for (int j = 0; j <= c_num + 1; j++) 222            {223                IloInt c = cplex.getValue(x[k][i][j]);224                if (c == 1) {225                    if (i == 0) cout <" --> " <226                    else if (i != 0) cout <" --> " <227                    i = j - 1;228                    break;229                }230                if (j == c_num + 1) { cout <endl; break; }231            }232        }233    }234235    env.end();236    //return 0;237    system("PAUSE");238    return EXIT_SUCCESS;239}

(3)vrptw.txt 输入格式

小算例:25个客户,3辆车,载重上限500。

 140    50  0   0   1236    0
245    68  10  912 967 90
345    70  30  825 870 90
442    66  10  65  146 90
542    68  10  727 782 90
642    65  10  15  67  90
740    69  20  621 702 90
840    66  20  170 225 90
938    68  20  255 324 90
1038    70  10  534 605 90
1135    66  10  357 410 90
1235    69  10  448 505 90
1325    85  20  652 721 90
1422    75  30  30  92  90
1522    85  10  567 620 90
1620    80  40  384 429 90
1720    85  40  475 528 90
1818    75  20  99  148 90
1915    75  20  179 254 90
2015    80  10  278 345 90
2130    50  10  10  73  90
2230    52  20  914 965 90
2328    52  20  812 883 90
2428    55  10  732 777 90
2525    50  10  65  144 90
2625    52  40  169 224 90
2740    50  0   0   1236    0

(4)该算例求解结果:

1ab95880c8a5563abb253fa9cc03f10c.png

ok,今天的内容到此就大概结束了,希望对大家有帮助,欢迎点赞、转发哦!!

a8b6565422193c733f7f7040466deda3.png微信号:ycwwzzq哔哩哔哩:我家公子Q-扫码关注我们-仙女都在看点点点,赞和在看都在这儿!
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值