相关文章推荐
爱旅游的木瓜  ·  SQl ...·  1 年前    · 
气宇轩昂的竹笋  ·  Issue in adding ...·  1 年前    · 
风流倜傥的台灯  ·  error MSB3027: Could ...·  1 年前    · 

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
 //  End
static 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 variables
	double 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);
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
 //  End
static 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 + x2
	model.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 variables
	double 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);
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;

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

IBM CPLEX可以解SOCP问题,但是需要先将这个SOCP问题化为指定的格式。本文首先介绍SOCP问题,然后举例介绍如何将SOCP问题转化为CPLEX认可的输入格式并求解。SOCP的介绍关于SOCP问题的介绍,可以参考CPLEX求解SOCP问题...
文件夹1是最基本的原对偶问题,只有包含支潮流约束 文件夹2是包含储能的原对偶问题,去除了储能的时间耦合约束,使用我自己的方法进行推导,虽然复杂但是可以问题,理了我的这个做法,也就掌握了对偶的使用方法; 文件夹3是文件夹1的矩阵形式,作为补充,有千分之一的误差,但是满足要求; 文档《子问题的对偶形式推导》包含SVC,ESS的推导过程,标点符号我没细扣,能看懂自己手写推即可。 程序清晰,注释明了,可用于决配网两阶段鲁棒,加上源荷不确定性即可; 有运行问题可以帮忙决,有问题私我留言即可,认准电气111》
https://zhuanlan.zhihu.com/p/349906368 https://blog.csdn.net/cmdtth/article/details/101448122 https://www.cnblogs.com/whiterwater/p/11425364.html optimize()。用于区间内的一维无约束函数优化(对于一维求根,使用uniroot())。 f <- function(x) exp(-0.5*x) * sin(10*pi*x) f(0.5)
凸优化学习笔记:QP及SOCP问题QP问题定义是什么几何意义QP、QCQP、LP之间的关系例子最小二乘及回归问题多面体间距离方差定界问题基于随机费用的线性规划(考虑随机变量的优化问题以及讨论多目标函数时的权衡问题SOCP问题定义例子鲁棒线性规划 本文是针对Boyd凸优化教材在QP、SOCP问题部分的学习笔记。 QP问题 目标函数的凸的二次函数,约束是仿射的,为QP问题。有如下形式:minimize⁡ subject to (1/2)xTPx+qTx+rGx
个人博客Glooow,欢迎各位老师来踩踩 文章目录1. 二阶锥1.1 二阶锥定义1.2 二阶锥约束2. 优化问题建模3. 类似问题转化3.1 二次规划3.2 随机线性规划4. 问题求解 1. 二阶锥 1.1 二阶锥定义 在此之前,先给出二阶锥的定义。 在 kkk 维空间中二阶锥 (Second-order cone) 的定义为 Ck={[ut]∣u∈Rk−1,t∈R,∥u∥≤t} \mathc...
官方中文JAVA手册:https://www.ibm.com/docs/zh/icos/12.9.0?topic=application-structure cplex是IBM开发的一款线性规划问题求解器。 一、适用范围 cplex适用于求解问题类型: CPLEX的适用范围: 1.适用于一般的线性规划(LP)问题. 2.CPLEX 还可对 LP 的多个扩展求解: 2.1.网络流问题,是 LP 的一种特殊情况,CPLEX 可以通过利用问题结构以快得多的速度对其求解
C++用户的Cplex使用指南-1在VS2019中运行Cplex程序 Cplex是IBM开发并仍在维护更新的商业求解器,也是目前使用人数最多的求解器,类似的还有Gurobi,两者各有各的特点(两家颇有渊源,感兴趣的可以了一下)。 Cplex的一些基本概念 求解问题类型 线性规划问题(Linear Programming,LP) 网络流问题,是 LP 的一种特殊情况,CPLEX 可以通过利...
2. 导入CPLEX库 在MATLAB中使用CPLEX求解问题,需要先导入CPLEX库。可以使用MATLAB自带的addpath函数,将CPLEX库所在的文件夹径添加到MATLAB的搜索径中。 3. 创建模型 在MATLAB中使用CPLEX求解问题,需要先创建一个模型。可以使用cplexoptimset函数来设置模型的参数。 4. 定义变量 在CPLEX中,需要先定义变量。可以使用cplex在MATLAB中提供的函数cplexvar来定义变量。 5. 添加约束 在CPLEX中,需要添加约束条件。可以使用cplex在MATLAB中提供的函数cplexcon来添加约束条件。 6. 设置目标函数 在CPLEX中,需要设置目标函数。可以使用cplex在MATLAB中提供的函数cplexobjective来设置目标函数。 7. 求解模型 在CPLEX中,完成以上步骤后就可以求解模型了。可以使用cplex在MATLAB中提供的函数cplexsolve来求解模型。 总体上,使用CPLEX在MATLAB中求解问题需要遵循以上几个步骤。在每一个步骤中,需要使用cplex在MATLAB中提供的函数来完成相应的任务。同时,需要注意设置参数和变量的约束条件。