Getting started with Java-based Cplex

Cplex is a mathematical optimization technique. Primarily used to increase efficiency, implement strategies quickly and increase profitability. Cplex provides flexible high-performance optimization procedures to solve linear programming (Linear Programming), quadratic programming (Quadratic Programming), quadratically constrained programming (Quadratically Constrained Programming) and mixed integer programming (Mixed Integer Programming) problems.

Configure Cplex environment reference under Eclipse: Call Cplex environment configuration under Ecplise

I. Introduction

At present, there are not many articles or tutorials on solving planning problems based on Java-based Cplex, and beginners can only summarize and explore through official documents and a small number of other programs. I am also working on planning-related projects recently, and here I will share some of my learning experience and coding skills with you.

The interface of the official website is shown in the figure below. You can select the corresponding version of the tutorial on the left according to your Cplex version. When you get started, you can start from Getting Started with CPLEXthe beginning, and then you can browse it casually, but I think the most important part is the following CPLEX Java Reference Manual, which contains the usage methods and instructions of all APIs:

insert image description here
The ilog.concertlibrary includes things related to the definition of variables, such as the definition of optimization variables, the definition of expressions, etc.; the ilog.cplexlibrary includes things related to models, such as the definitions of various models, algorithms, etc. There are many APIs given in the document, but those are the ones that are commonly used. Next, I will introduce the general process and common interfaces of Cplex programming.

2. Getting Started with Cplex

2.1 Program template

The template of the Cplex program is usually as follows, we only need to fill in the corresponding position:

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

public class Cplex{
    
     //类的名字必须跟.java的名字一样
 
	public static void main(String[] args) {
    
    
		try {
    
    
			// 1. 创建模型
			
			// 2. 定义优化参数
			
			// 3. 设置目标函数

			// 4. 设置约束
			
			// 5. 模型求解及输出
						
		} catch (IloException e) {
    
    
			System.err.println("Concert exception caught: " + e);
		}
	}
}

2.2 Create a model

IloCplex cplex = new IloCplex(); // creat a model

2.3 Define optimization parameters

The optimization parameters to be solved are defined here, and the parameter types include single variable, one-dimensional and two-dimensional array types.

//1.单个变量
//1.1 实数型变量
IloNumVar x= cplex.numVar(0, 5); 
//1.2 整型变量
IloIntVar x= cplex.intVar(0, 5); 
/*括号中的参数表示变量的取值范围,例如该变量的取值范围为0≤x≤5,若不想定义范围可以设置为-Double.MAX_VALUE和Double.MAX_VALUE,表示负无穷到正无穷*/

//2. 一维数组
// 2.1 实数型变量
IloNumVar[] x = cplex.numVarArray(3, 0.0, 5.0);
// 2.2 整型变量
IloIntVar[] x = cplex.intVarArray(3, 0, 5);
/*括号中的参数表示数组的大小、最小值和最大值*/
// 2.3 每个变量设置不同的范围
double[] rg = {
    
    0,5,1,2,4,5}; //每个变量的最小值和最大值
IloNumVar[] a = new IloNumVar[3];
for(int i=0;i<3;i++)
{
    
    
	a[i] = cplex.numVar(rg[2*i], rg[2*i+1]);
}
/*这种方式就将数组中的三个变量设置了不同的取值范围,分别为0-5,1-2,4-5*/

//3. 二维数组
//3.1 实数型变量
IloNumVar[][] x = new IloNumVar[2][];
for (int i=0; i<2; i++) 
{
    
    
	x[i] = cplex.numVarArray(2, 0.0, 5.0);
}
//3.2 整型变量
IloIntVar[][] x = new IloIntVar[2][];
for (int i=0; i<2; i++) 
{
    
    
	x[i] = cplex.intVarArray(2, 0, 5);
}
/*以上这种方式定义了2行2列的变量,变量范围为0-5,若像设置不同的取值范围,按照一维数组的方式修改即可

2.4 Setting the objective function and constraints

The objective function generally takes the maximum or minimum value of an expression, and the constraint generally sets the value range of an expression. They have one thing in common that they all need to define the expression first, and the way they define the expression is exactly the same.

2.4.1 Defining expressions

As shown in the figure, Exprthe method with the last four letters is the expression type that can be defined:

insert image description here
The official provides different interfaces according to different expression types, including:

interface describe
PleasureIntExpr/PleasureNumExpr Base public interface for integer/real expressions
IloLinearIntExpr/IloLinearNumExpr Interface for linear expressions of integer/real type variables
IloLQIntExpr/IloLQNumExpr General expressions with linear and quadratic terms
IloQuadIntExpr/IloQuadNumExpr Quadratic numeric expression of integer/real number type

You can choose the interface form that suits you according to the type of your expression. For example, my expression x1+2*x2+3*x3is a linear type, so you can use the interface of a linear expression:

//定义变量
IloNumVar[] x = cplex.numVarArray(3, -5, 5);

IloLinearNumExpr cs= cplex.linearNumExpr();
cs.addTerm(1, x[0]);
cs.addTerm(2, x[1]); 
cs.addTerm(3, x[2]);

Each interface provides a lot of methods. You can check the usage and description of each interface in the official documentation.

Although the official provides different interfaces for expressions of different forms, there are certain problems, such as you cannot add quadratic terms to a linear expression, and when the expression is more complex, there is usually more than one type. Therefore, I am more accustomed to using the most basic formula interface IloNumExpr, in which you can use the addition, subtraction, multiplication, and division in the cplex model library to add any form of expression.

After creating the model first IloCplex cplex = new IloCplex();, you can cplex.XXXuse various calculation methods in the model. The commonly used methods include:

method illustrate method illustrate
sum to sum diff Find the difference
prod product abs absolute value

With the above four methods, you can basically deal with most of the expressions. For example, the expression above is x1+2*x2+3*x3represented by the basic public interface as:

IloNumVar[] x = cplex.numVarArray(3, -5.0, 5.0);
					
double[] a = {
    
    1,2,3};
IloNumExpr cs = cplex.numExpr();
for(int i=0;i<3;i++)
{
    
    
	cs = cplex.sum(cs,cplex.prod(x[i], a[i]));
}

Although this method increases the amount of code, the readability of the code is enhanced, so I prefer to define expressions in this way.

Let me give another example to find the sum of squares and absolute values ​​of variable x:

IloNumVar[] x = cplex.numVarArray(3, -5.0, 5.0);

IloNumExpr cs1 = cplex.numExpr();
IloNumExpr cs2 = cplex.numExpr();
for(int i=0;i<3;i++)	
{
    
    
	cs1= cplex.sum(cs1,cplex.abs(x[i])); //绝对值之和
	cs2= cplex.sum(cs2,cplex.prod(x[i], x[i])); //平方和
}	

After the expression is defined, the objective function and constraints can be added.

2.4.2 Define the objective function

Suppose the expression of the objective function after definition is represented by obj:

function meaning
cplex.addMinimize(obj) Find the minimum value of obj
cplex.addMaximize(obj) Find the maximum value of obj

2.4.3 Defining Constraints

Assume that the expression for the post-constraint is defined in cs:

function meaning function meaning
cplex.addEq(cs,a) cs=a cplex.addGe(cs,a) cs≥a
cplex.addLe(cs,a) cs≤a cplex.addRange(a,cs,b) a≤cs≤b

After adding the constraints, we can cplex.diff(cs,cs)clear the expression cs, and then add new expressions in cs.

2.4.4 Empty expressions

Sometimes when defining the objective function and constraints, it is necessary to define a new expression through a loop. It is troublesome to reinitialize the expression each time. At this time, the expression needs to be cleared:

  • cplex.diff(cs,cs)
  • cs = cplex.numExpr()

The first method sometimes reports a memory overflow error, so the second method is recommended.

2.5 Model solution and output

The template for model solving and output is as follows:

if (cplex.solve()) {
    
    
cplex.output().println("Solution status = " + cplex.getStatus());
cplex.output().println("Solution value = " + cplex.getObjValue());
double[] val = cplex.getValues(x);
for (int j = 0; j < val.length; j++)
	System.out.println("x" + (j+1) + "  = " + val[j]);
}
cplex.end();

in:

function meaning
cplex.getStatus() Get the status of the model solver
cplex.getObjValue() Get the value of the objective function
cplex.getValues(x) Get the value of the optimization variable
cplex.end() end model

Model solving includes the following states:

state meaning state meaning
Optimal found an optimal solution Feasible found a working solution
Infeasible the model is not feasible Error Encountered an error
Bounded Model is not unbounded Unbounded model is unbounded

3. Case presentation

insert image description here

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

public class test {
    
    
	public static void main(String[] args) {
    
    
		try {
    
    
			IloCplex cplex = new IloCplex(); // create a model
			
			IloNumVar[] x = cplex.numVarArray(3, -Double.MAX_VALUE, Double.MAX_VALUE);
			
			IloNumExpr cs1 = cplex.numExpr();
			for(int i=0;i<3;i++)
			{
    
    
				cs1 = cplex.sum(cs1,cplex.prod(x[i], x[i]));
			}
				
			cplex.addMinimize(cs1);
			
			cplex.addEq(cplex.sum(x[0], x[1]),1);
			cplex.addEq(cplex.sum(x[0], x[2]),1);
			cplex.addEq(cplex.sum(x[1], x[2]),1);
					
			if (cplex.solve()) {
    
    
				cplex.output().println("Solution status = " + cplex.getStatus());
				cplex.output().println("Solution value = " + cplex.getObjValue());
				double[] val = cplex.getValues(x);
				for (int j = 0; j < val.length; j++)
					System.out.println("x" + (j+1) + "  = " + val[j]);
			}
			cplex.end();
			
		} catch (IloException e) {
    
    
			System.err.println("Concert exception caught: " + e);
		}
	}
}

The result of the operation is:
insert image description here

The program is relatively simple and will not be described here. You can understand it in conjunction with the content of the second part.

All in all, other people's programs, official documents and official cases are the best tutorials for learning Cplex. I hope you will explore more!

Guess you like

Origin blog.csdn.net/cyj972628089/article/details/125453696