C++嵌套调用 用Python 脚本写的 基于Gurobi 的解数学模型的经验记录

本文记录了如何在C++项目中嵌套调用Python脚本,该脚本基于Gurobi求解数学模型。作者在尝试解决大规模优化问题时,发现使用Python和Gurobi接口比C++接口更有效率。文章介绍了从选择优化工具到最终实现C++调用Python脚本的全过程,并提供了Python模型求解和C++调用的代码示例。
摘要由CSDN通过智能技术生成

       How to embed a Gurobi-based Mathematical Model solving script, which is written in Python, into a C++ simulation project.

       一、前言

       标题写得有点拗口,总共涉及到3个工具:Python, Gurobi, C++,其中 Gurobi 是一个类似于 IBM 的 CPlex 的解数学模型的工具,下文有详述。

       这篇记录是把我用 C++ 调用 由python 脚本 写的基于 Gurobi optimizer 的 程序的经验分享出来。

       我当初开始试着解决问题时,搜索了整个网络,国语写成的资料,最多涉及到2项,如 “如何用C++调用 python 脚本” 或者 “如何 调用 Gurobi 的 C++ 接口”,又或者 “ 如何调用 Gurobi 的 python 接口”。 没有一个符合我的要求的,只好去参考原版的 Gurobi  Manual 与 python 27 的 tutorial, 然后一步步地做实验,探索用法。然后结合着 Google Group (https://groups.google.com/forum/#!forum/gurobi) 的帖子,去借鉴别人的经验。虽然这个过程走了很多的弯路,最后终于把自己的问题解决了!

       首先,把我的基本情况说明如下:

       1)现有一个数学模型,但是不知道是否正确,所以需要用一个简单的小例子快速地验证;

       2)如果数学模型正确了,我需要把它封装一下,嵌到C++工程里,这样可以在模拟程序里一轮一轮地反复调用,记录多次调用数学模型解出来的optimal 值,同时可以让模拟程序里设计的算法执行在由同样的输入数据的情况下,最终可以比较算法的结果与最优值之间的 performance 差别。

       前边 之所以说,走了弯路,而且走了两次:一是因为最开始时,我没有挑选对优化工具,用了国内常用的Lingo,因为在国内网站上搜到很多诸如“谢金星Lingo优化工具讲解” ,说实话这个工具的脚本语言真是不好用,花了好几天的时间还用不好。渐渐生出换工具的念头。请教师兄,他推荐我使用世界上优化效率最好的 Gurobi,比著名的CPlex还要好用。最开始不信,google一下再说,结果第一条便是“Gurobi — The overall fastest and best supported solver available”,而且找到了几种主流的优化工具效率的比较的柱状图,不是重点,此处略去。

       开读 Gurobi 的 manual,我发现,它的使用很灵活,提供了若干种主流语言的 interfaces, 如 C, C++, Java, Python, .net等等,比较适合嵌套在用户的程序里去被调用,来解决优化问题。

       紧接着,我又走了一次弯路,因为我最熟悉C++,然后就参照着 Gurobi 提供的C++ examples,与 quick start Refs,用了C++ interfaces 来写解数学模型 的程序。经过千辛万苦,终于把解数学模型的程序封装并写好了调用。一试用效果,小规模的程序很快,model 也被验证了正确性,窃喜。可是一旦上了规模,结果程序慢得像蜗牛,因为输入的数据上了规模后,用来被测试的一个Model 里的变量与 constraints 的数量很多,有时 constraints 的数量甚至达到了数百万个,解起来很费时,根本没法用在模拟程序里进行成百上千次的反复调用。究其原因,可能性是1)我的水平不够,写的C++程序效率奇差;2)我的数学模型本身的特殊性造成的,当变量规模大了,constraints 就异常多;3)也可能是因为 Gurobi 所提供的C++ interfaces 在解我的数学模型时,效果不好。

       再次请教师兄,他建议我使用 python试试。于是,就现学现用python了。对照着师兄给的例子程序,慢慢将我的数学模型写成用python脚本来解。又经过1天的埋头coding,终于写好了单独的一个用 python 脚本写好的 model solving 程序。开试效果:只要规模不是太大,几乎瞬间被解出。怎么回事? 现在看来刚才用 C++ 调用效果不好的3个可能的原因,应该是第3条被验证了。

       那我就用 python 脚本写成的 model-solving 程序来解最优值。

       Then, the next problem is: How to embed this python-based model-solving script into a C++ project ?

       到了这一步,问题就简单多了,只需要解决用C++来调用 python 脚本就可以了。很快,这个问题被我攻克了。

       以上便是我的此次的问题解决路线,弯路有时候必须走一走,到终点时,才知道它原来是一条弯路。尽管觉得费了很大力气,做了很多无用功,但是,我倒不觉得这是在浪费时间与精力。弯路才能让人领略到更多风景。

       Ok, 废话不多说,我把我的 用 python 写的 gurobi 脚本 与 一部分 C++ 调用这个脚本的关键程序贴在最后,如果对谁有帮助,那我的汗水也会增加一分重量。

       贴出来的程序分为2个主要部分:1)python 写的 model solving 脚本示例; 2)用C++调用 Python 脚本的一些 api 的用法与封装示例.

       关于用到的数学模型,如下图的 Integer Programming (IP) optimization:

其中,各个限制条件请具体参考论文“Optimal VM Placement in Data Centers with Architectural and Resource Constraints”。这个优化问题有点类似于背包问题或者Bin packing 问题,又或者minimum k-cut problem。解它的脚本原样贴出。

   2015-Otc-03 补充: 另外一个更好的解模的例子的 Source-code 与相应的论文,请参考 ResearchGate 上的一个Dataset (Title: The_Source_Code_sample_to_solve_an_optimization_model_using_Gurobi ) URL:  https://www.researchgate.net/publication/282362692 


// ================================================================ //

       二、程序示例与解释

       1)  The implementation of mathematical model based on Gurobi, in Python script:

       简单解释:此Python脚

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值