forked from xiongwq16/cplex-java-api-tutorial-zh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AdMIPex1.java
129 lines (113 loc) · 4.8 KB
/
AdMIPex1.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package examples;
/* --------------------------------------------------------------------------
* File: AdMIPex1.java
* Version 12.9.0
* --------------------------------------------------------------------------
* Licensed Materials - Property of IBM
* 5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55 5655-Y21
* Copyright IBM Corporation 2001, 2019. All Rights Reserved.
*
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with
* IBM Corp.
* --------------------------------------------------------------------------
*
* AdMIPex1.java -- Use the node and branch callbacks to optimize
* a MIP problem
*
* To run this example, command line arguments are required.
* i.e., java AdMIPex1 filename
*
* Example:
* java AdMIPex1 example.mps
*/
import ilog.concert.*;
import ilog.cplex.*;
public class AdMIPex1 {
static class MyBranch extends IloCplex.BranchCallback {
IloNumVar[] _vars;
MyBranch(IloNumVar[] vars) {
_vars = vars;
}
public void main() throws IloException {
if (!getBranchType().equals(IloCplex.BranchType.BranchOnVariable))
return;
// Branch on var with largest objective coefficient
// among those with largest infeasibility
double[] x = getValues(_vars);
double[] obj = getObjCoefs(_vars);
IloCplex.IntegerFeasibilityStatus[] feas = getFeasibilities(_vars);
double maxinf = 0.0;
double maxobj = 0.0;
int bestj = -1;
int cols = _vars.length;
for (int j = 0; j < cols; ++j) {
if (feas[j].equals(IloCplex.IntegerFeasibilityStatus.Infeasible)) {
double xj_inf = x[j] - Math.floor(x[j]);
if (xj_inf > 0.5)
xj_inf = 1.0 - xj_inf;
// 选择距离整数最远的变量进行分支(如果有多个则选择其中最大目标函数系数最大的变量)
if (xj_inf >= maxinf && (xj_inf > maxinf || Math.abs(obj[j]) >= maxobj)) {
bestj = j;
maxinf = xj_inf;
maxobj = Math.abs(obj[j]);
}
}
}
if (bestj >= 0) {
// 添加分支,可以以数组形式批量添加
makeBranch(_vars[bestj], x[bestj], IloCplex.BranchDirection.Up, getObjValue());
makeBranch(_vars[bestj], x[bestj], IloCplex.BranchDirection.Down, getObjValue());
}
}
}
static class MySelect extends IloCplex.NodeCallback {
public void main() throws IloException {
// 获取tree中激活的节点数量
long remainingNodes = getNremainingNodes64();
long bestnode = -1;
int maxdepth = -1;
double maxiisum = 0.0;
// 选择违反整数约束最多(非整数变量最多)的节点
for (long i = 0; i < remainingNodes; ++i) {
int depth = getDepth(i);
// 获取不满足整数约束的变量的数量
double iisum = getInfeasibilitySum(i);
if ((depth >= maxdepth) && (depth > maxdepth || iisum > maxiisum)) {
bestnode = i;
maxdepth = depth;
maxiisum = iisum;
}
}
if (bestnode >= 0)
selectNode(bestnode);
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: AdMIPex1 filename");
System.out.println(" where filename is a file with extension ");
System.out.println(" MPS, SAV, or LP (lower case is allowed)");
System.out.println(" Exiting...");
System.exit(-1);
}
try {
IloCplex cplex = new IloCplex();
cplex.importModel(args[0]);
IloLPMatrix lp = (IloLPMatrix) cplex.LPMatrixIterator().next();
// 使用use调用callBack类函数
cplex.use(new MyBranch(lp.getNumVars()));
cplex.use(new MySelect());
// 设置搜索策略
// Traditional: Use traditional branch-and-cut search.
cplex.setParam(IloCplex.Param.MIP.Strategy.Search, IloCplex.MIPSearch.Traditional);
if (cplex.solve()) {
System.out.println("Solution status = " + cplex.getStatus());
System.out.println("Solution value = " + cplex.getObjValue());
}
cplex.end();
} catch (IloException e) {
System.err.println("Concert exception caught: " + e);
}
}
}