【漫漫科研路\CC++】CPLEX解SOCP问题

2024-03-24 14:58
文章标签 c++ 问题 科研 cplex 漫漫 socp

本文主要是介绍【漫漫科研路\CC++】CPLEX解SOCP问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

IBM CPLEX可以解SOCP问题,但是需要先将这个SOCP问题化为指定的格式。本文首先介绍SOCP问题,然后举例介绍如何将SOCP问题转化为CPLEX认可的输入格式并求解。

SOCP的介绍

关于SOCP问题的介绍,可以参考Boyd等人写的Convex Optimization 或者是维基百科的SOCP词条 。这里摘录Convex Optimization一书中关于SOCP的定义:

在这里插入图片描述

CPLEX求解SOCP问题

使用CPLEX求解SOCP问题,一般需要将问题转化为CPLEX可以识别的格式。CPLEX的例子ilosocpex1(位于安装目录的examples文件夹内,例如:C:\Program Files\IBM\ILOG\CPLEX_Enterprise_Server129\CPLEX_Studio\cplex\examples)给予了格式说明:
在这里插入图片描述
下面我们首先给一个直接可以使用CPLEX求解的例子,然后在此基础上考虑一个更一般的例子(需要变量替换来符合格式)。

一个简单的例子

在这里插入图片描述
如上图所示,q1, q2可以直接转化为前面提到的CPLEX认可格式。下面给出源代码如下(注意项目需要预先配置好,配置请见上一篇博文):

#include <cmath>
#include <string>
#include <iostream>
#include <ilcplex/ilocplex.h>ILOSTLBEGIN // import namespace std// Tolerance for testing KKT conditions.
#define TESTTOL 1e-9
// Tolerance for barrier convergence.
#define CONVTOL 1e-9//  A Simple Example//  Minimize//   obj: x1 + x2 + x3 + x4 + x5 + x6//  Subject To//   c1: x1 + x2      + x5      = 8//   c2:           x3 + x5 + x6 = 10//   q1: x1 >= |(x2, x3)| ---->>>>  q1: [ -x1^2 + x2^2 + x3^2 ] <= 0 and x1 >=0//   q2: x4 >= |x5|       ---->>>>  q2: [ -x4^2 + x5^2 ] <= 0 and x4 >=0//  Bounds//   x2 Free//   x3 Free//   x5 Free//   x6 Free//  Endstatic void
createmodel(IloModel& model, IloObjective &obj, IloNumVarArray &x,IloRangeArray &rngs, IloIntArray& cone)
{IloEnv env = model.getEnv();// Create variables.x.add(IloNumVar(env, 0, IloInfinity));x.add(IloNumVar(env, -IloInfinity, IloInfinity));x.add(IloNumVar(env, -IloInfinity, IloInfinity));x.add(IloNumVar(env, 0, IloInfinity));x.add(IloNumVar(env, -IloInfinity, IloInfinity));x.add(IloNumVar(env, -IloInfinity, IloInfinity));// Create objective function and immediately store it in return value.// obj = IloMinimize(env, x1 + x2 + x3 + x4 + x5 + x6);obj = IloMinimize(env, x[0]+x[1] + x[2] + x[3] + x[4] + x[5]);// Setup model.model.add(x[0] + x[1] + x[4]==8);model.add(x[2] + x[4] + x[5]==10);model.add(-x[0] * x[0] + x[1] * x[1] + x[2] * x[2]<=0);//equal to model.add(-x[3] * x[3] + x[4] * x[4]<=0), useful for lots of variablesdouble a[] = {0,0,0, -1,1 };IloExpr temp(env);for (IloInt i = 3; i < 5; i++){temp += a[i] * x[i] * x[i];}model.add(temp <= 0);temp.end();model.add(obj);
}int
main(void)
{IloEnv env;int retval = -1;try {// Create the model.IloModel model(env);IloCplex cplex(env);IloObjective obj(env);IloNumVarArray vars(env);IloRangeArray rngs(env);IloIntArray cone(env);createmodel(model, obj, vars, rngs, cone);// Extract model.cplex.extract(model);// Solve the problem. If we cannot find an _optimal_ solution then// there is no point in checking the KKT conditions and we throw an// exception.cplex.setParam(IloCplex::Param::Barrier::QCPConvergeTol, CONVTOL);if (!cplex.solve() || cplex.getStatus() != IloAlgorithm::Optimal)throw string("Failed to solve problem to optimality");IloNumArray vals_x(env);env.out() << "Solution status = " << cplex.getStatus() << endl;env.out() << "Solution value  = " << cplex.getObjValue() << endl;cplex.getValues(vals_x, vars);env.out() << "Values        = " << vals_x << endl;env.end();}catch (IloException &e) {cerr << "IloException: " << e << endl;if (env.getImpl())env.end();::abort();}catch (string& e) {cerr << e << endl;if (env.getImpl())env.end();::abort();}return retval;
}

运行结果如下图:
在这里插入图片描述

一个更一般的例子

在前面例子的基础上,我们只是改变了约束q1,使其更一般化,如下图所示:
在这里插入图片描述

为了将q1转化为合适的格式,我们使用变量替换 $x_7=x_1+x_2 $ 。因此只需在前面源代码中更改 createmodel 函数中的部分代码。为保持代码完整性,我们依旧给出完整的代码:

#include <cmath>
#include <string>
#include <iostream>
#include <ilcplex/ilocplex.h>ILOSTLBEGIN // import namespace std// Tolerance for testing KKT conditions.
#define TESTTOL 1e-9
// Tolerance for barrier convergence.
#define CONVTOL 1e-9//  A Simple Example//  Minimize//   obj: x1 + x2 + x3 + x4 + x5 + x6//  Subject To//   c1: x1 + x2      + x5      = 8//   c2:           x3 + x5 + x6 = 10//   q1: x1 + x2 >= |(x1, x2, x3)| ---->>>> q1:[-x7^2+x1^2+x2^2+x3^2]<=0 and x7=x1+x2>=0//   q2: x4 >= |x5|       ---->>>>  q2: [ -x4^2 + x5^2 ] <= 0 and x4 >=0//  Bounds//   x1 Free//   x2 Free//   x3 Free//   x5 Free//   x6 Free//  Endstatic void
createmodel(IloModel& model, IloObjective &obj, IloNumVarArray &x,IloRangeArray &rngs, IloIntArray& cone)
{IloEnv env = model.getEnv();// Create variables.x.add(IloNumVar(env, -IloInfinity, IloInfinity));x.add(IloNumVar(env, -IloInfinity, IloInfinity));x.add(IloNumVar(env, -IloInfinity, IloInfinity));x.add(IloNumVar(env, 0, IloInfinity));x.add(IloNumVar(env, -IloInfinity, IloInfinity));x.add(IloNumVar(env, -IloInfinity, IloInfinity));x.add(IloNumVar(env, 0, IloInfinity));// x7// Create objective function and immediately store it in return value.// obj = IloMinimize(env, x1 + x2 + x3 + x4 + x5 + x6);obj = IloMinimize(env, x[0]+x[1] + x[2] + x[3] + x[4] + x[5]);// Setup model.model.add(x[0] + x[1] + x[4]==8);model.add(x[2] + x[4] + x[5]==10);model.add(x[6] - x[0] - x[1] == 0); // x7 = x1 + x2model.add(-x[6] * x[6]+ x[0] * x[0] + x[1] * x[1] + x[2] * x[2]<=0); //[-x7^2+x1^2+x2^2+x3^2]<=0//equal to model.add(-x[3] * x[3] + x[4] * x[4]<=0), useful for lots of variablesdouble a[] = {0,0,0, -1,1 };IloExpr temp(env);for (IloInt i = 3; i < 5; i++){temp += a[i] * x[i] * x[i];}model.add(temp <= 0);temp.end();model.add(obj);
}int
main(void)
{IloEnv env;int retval = -1;try {// Create the model.IloModel model(env);IloCplex cplex(env);IloObjective obj(env);IloNumVarArray vars(env);IloRangeArray rngs(env);IloIntArray cone(env);createmodel(model, obj, vars, rngs, cone);// Extract model.cplex.extract(model);// Solve the problem. If we cannot find an _optimal_ solution then// there is no point in checking the KKT conditions and we throw an// exception.cplex.setParam(IloCplex::Param::Barrier::QCPConvergeTol, CONVTOL);if (!cplex.solve() || cplex.getStatus() != IloAlgorithm::Optimal)throw string("Failed to solve problem to optimality");IloNumArray vals_x(env);env.out() << "Solution status = " << cplex.getStatus() << endl;env.out() << "Solution value  = " << cplex.getObjValue() << endl;cplex.getValues(vals_x, vars);env.out() << "Values        = " << vals_x << endl;env.end();}catch (IloException &e) {cerr << "IloException: " << e << endl;if (env.getImpl())env.end();::abort();}catch (string& e) {cerr << e << endl;if (env.getImpl())env.end();::abort();}return retval;
}

运行结果如下图:
在这里插入图片描述

这篇关于【漫漫科研路\CC++】CPLEX解SOCP问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/841948

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

idea npm install很慢问题及解决(nodejs)

《ideanpminstall很慢问题及解决(nodejs)》npm安装速度慢可通过配置国内镜像源(如淘宝)、清理缓存及切换工具解决,建议设置全局镜像(npmconfigsetregistryht... 目录idea npm install很慢(nodejs)配置国内镜像源清理缓存总结idea npm in

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

idea突然报错Malformed \uxxxx encoding问题及解决

《idea突然报错Malformeduxxxxencoding问题及解决》Maven项目在切换Git分支时报错,提示project元素为描述符根元素,解决方法:删除Maven仓库中的resolv... 目www.chinasem.cn录问题解决方式总结问题idea 上的 maven China编程项目突然报错,是

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

前端导出Excel文件出现乱码或文件损坏问题的解决办法

《前端导出Excel文件出现乱码或文件损坏问题的解决办法》在现代网页应用程序中,前端有时需要与后端进行数据交互,包括下载文件,:本文主要介绍前端导出Excel文件出现乱码或文件损坏问题的解决办法,... 目录1. 检查后端返回的数据格式2. 前端正确处理二进制数据方案 1:直接下载(推荐)方案 2:手动构造

Python绘制TSP、VRP问题求解结果图全过程

《Python绘制TSP、VRP问题求解结果图全过程》本文介绍用Python绘制TSP和VRP问题的静态与动态结果图,静态图展示路径,动态图通过matplotlib.animation模块实现动画效果... 目录一、静态图二、动态图总结【代码】python绘制TSP、VRP问题求解结果图(包含静态图与动态图

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2