测试环境:
vs2019
cplex==12.10.0
winform代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ILOG.Concert;
using ILOG.CPLEX;
using System.Collections;
using static WindowsFormsApp1.AdMIPex1;
namespace WindowsFormsApp1
{
public class AdMIPex1
{
internal class MyBranch : Cplex.BranchCallback
{
internal INumVar[] _vars;
internal MyBranch(INumVar[] vars) { _vars = vars; }
public override void Main()
{
if (!GetBranchType().Equals(Cplex.BranchType.BranchOnVariable))
return;
// Branch on var with largest objective coefficient
// among those with largest infeasibility
double[] x = GetValues(_vars);
double[] obj = GetObjCoefs(_vars);
Cplex.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(Cplex.IntegerFeasibilityStatus.Infeasible))
{
double xj_inf = x[j] - System.Math.Floor(x[j]);
if (xj_inf > 0.5) xj_inf = 1.0 - xj_inf;
if (xj_inf >= maxinf &&
(xj_inf > maxinf || System.Math.Abs(obj[j]) >= maxobj))
{
bestj = j;
maxinf = xj_inf;
maxobj = System.Math.Abs(obj[j]);
}
}
}
if (bestj >= 0)
{
MakeBranch(_vars[bestj], x[bestj],
Cplex.BranchDirection.Up, GetObjValue());
MakeBranch(_vars[bestj], x[bestj],
Cplex.BranchDirection.Down, GetObjValue());
}
}
}
internal class MySelect : Cplex.NodeCallback
{
public override void Main()
{
int remainingNodes = GetNremainingNodes();
int bestnode = -1;
int maxdepth = -1;
double maxiisum = 0.0;
for (int 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 partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
Cplex cplex = new Cplex();
cplex.ImportModel(@"D:\lufiles\CPLEX_Studio\cplex\examples\data\mexample.mps");
IEnumerator matrixEnum = cplex.GetLPMatrixEnumerator();
matrixEnum.MoveNext();
ILPMatrix lp = (ILPMatrix)matrixEnum.Current;
cplex.Use(new MyBranch(lp.NumVars));
cplex.Use(new MySelect());
cplex.SetParam(Cplex.Param.MIP.Strategy.Search, Cplex.MIPSearch.Traditional);
if (cplex.Solve())
{
System.Console.WriteLine("Solution status = " + cplex.GetStatus());
System.Console.WriteLine("Solution value = " + cplex.ObjValue);
}
cplex.End();
}
catch (ILOG.Concert.Exception ex)
{
System.Console.WriteLine("Concert exception caught: " + ex);
}
}
}
}
运行结果:
Selected objective sense: MINIMIZE
Selected objective name: obj
Selected RHS name: rhs
Selected bound name: bnd
Version identifier: 12.10.0.0 | 2019-11-26 | 843d4de2ae
CPXPARAM_Preprocessing_Reduce 1
CPXPARAM_Preprocessing_Linear 0
CPXPARAM_MIP_Strategy_Search 1
Found incumbent of value -46.000000 after 0.00 sec. (0.00 ticks)
Tried aggregator 2 times.
Aggregator did 1 substitutions.
Reduced MIP has 2 rows, 3 columns, and 6 nonzeros.
Reduced MIP has 0 binaries, 1 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.00 sec. (0.00 ticks)
Tried aggregator 1 time.
Reduced MIP has 2 rows, 3 columns, and 6 nonzeros.
Reduced MIP has 0 binaries, 1 generals, 0 SOSs, and 0 indicators.
Presolve time = 0.00 sec. (0.00 ticks)
MIP emphasis: balance optimality and feasibility.
MIP search method: traditional branch-and-cut.
Parallel mode: none, using 1 thread.
Root relaxation solution time = 0.02 sec. (0.00 ticks)
Nodes Cuts/
Node Left Objective IInf Best Integer Best Bound ItCnt Gap Variable B NodeID Parent Depth
* 0+ 0 -46.0000 -163.0000 254.35%
* 0+ 0 -122.5000 -163.0000 33.06%
0 0 -125.2083 1 -122.5000 -125.2083 3 2.21%
0 0 cutoff -122.5000 3 0.00% 0 0
Elapsed time = 0.02 sec. (0.02 ticks, tree = 0.01 MB, solutions = 2)
Root node processing (before b&c):
Real time = 0.02 sec. (0.02 ticks)
Sequential b&c:
Real time = 0.00 sec. (0.00 ticks)
------------
Total (root+branch&cut) = 0.02 sec. (0.02 ticks)
Solution status = Optimal
Solution value = -122.5
注意事项:
1、调用x64库需要选择x64平台进行编译,不能选择x86平台
2、要将DLL路径加入环境变量Path,否则需要将DLL复制到运行目录才可以
拓展:
1、更多C#案例可以参考官方安装包中的CPLEX_Studio\cplex\examples\src\cs
2、所有官方测试数据在路径CPLEX_Studio\cplex\examples\data
3、C#官方安装教程参考CPLEX_Studio\cplex\dotnet.html