CPLEX + JAVA:启发式回调中的检索解决方案行为异常

问题描述 投票:0回答:1

我有以下问题:我使用集成了启发式组件的CPLEX解决了具有许多同步约束的大型VRP,以改善现有设备。通用算法如下:如果在CPLEX中找到了新任职者,或者达到了时间限制,那么我将进行启发式尝试,并尝试改善当前任职者。前者使用现任回调完成,后者使用启发式回调完成。虽然我可以查询现有回调中的所有变量,但在启发式回调中却得到了一些奇怪的行为:当我查询

this.getStatus().toString()

这将返回“ Optimal”,即使解决方案还不是最优的(现有的,但仍然存在较大的完整性差距)。我确保模型通过查询目标值和当前完整性差距来查询正确的cplex对象,它们与对数匹配。然后,

this.getIncumbentValue(v[n][i][j]);

失败(如果我使用this.getIncumbentValues(v[n][i]);查询值,也会失败)。

[当我检入模型时(使用cplex.exportModel(String filename),所有变量都存在。

我以为这可能与我将CPLEX用作单例的事实有关,但是当我第一次使用单例时,状态已经是“最佳”的(但是在第一次迭代中,可以查询所有变量。 ,此问题仅在第二次迭代中存在)。

我这样创建单例:

public static IloCplex getCplex() {
    if (cplex == null) {
        try {
            cplex = new IloCplex();
        } catch (IloException e) {
            e.printStackTrace();
        }
    } else {
        try {
            cplex.clearModel();
            cplex.setDefaults();
        } catch (IloException e) {
            e.printStackTrace();
        }
    }
    return cplex;
}

我可能在这里做错了吗?

编辑:包括回溯的确切错误消息是:

ilog.cplex.IloCplex$UnknownObjectException: CPLEX Error: object is unknown to IloCplex
 at ilog.cplex.CpxNumVar.getVarIndexValue(CpxNumVar.java:295)
 at ilog.cplex.IloCplex$MIPInfoCallback.getIndex(IloCplex.java:13648)
 at ilog.cplex.IloCplex$MIPInfoCallback.getIncumbentValues(IloCplex.java:13807)
 at ilog.cplex.IloCplex$MIPInfoCallback.getIncumbentValues(IloCplex.java:13785)
 at SolverHybridCRP$InsertSolution.getV(SolverHybridCRP.java:2091)
 at SolverHybridCRP$InsertSolution.improveIncumbent(SolverHybridCRP.java:2054)
 at SolverHybridCRP$InsertSolution.main(SolverHybridCRP.java:2024)
 at ilog.cplex.CpxCallback.callmain(CpxCallback.java:160)
 at ilog.cplex.CpxHeuristicCallbackFunction.callIt(CpxHeuristicCallbackFunction.java:48)
 at ilog.cplex.Cplex.CPXmipopt(Native Method)
 at ilog.cplex.CplexI$SolveHandle.start(CplexI.java:2837)
 at ilog.cplex.CplexI.solve(CplexI.java:2963)
 at ilog.cplex.IloCplex.solve(IloCplex.java:10254)
 at SolverHybridCRP.solveModel(SolverHybridCRP.java:1525)
 at AppHelp.runtimeTest4(AppHelp.java:1218)
 at AppHelp.main(AppHelp.java:61)

它在查询ANY变量时发生,但仅在第二次查询cplex对象之后才发生。 (因此:我启动程序,在很多实例上进行迭代,第一个实例很好,所有启发式回调均有效,在所有后续迭代中,我最终都在catch块中并获得了上面的异常跟踪。)这就是为什么我认为单例可能无法按预期工作的原因,并且并不是所有内容都从第一次迭代中删除。

java cplex
1个回答
0
投票

查看reference documentation可以看到的IloCplex.HeuristicCallback.getStatus()

返回当前节点的解决方案状态。

此方法返回实例找到的解决方案的状态 在最后一次调用该方法期间,当前节点上的IloCplex数量 IloCplex.HeuristicCallback.solve(可能已直接调用 在回调中或通过IloCplex处理节点之前 回调被调用)。

换句话说,该函数不返回全局状态,而仅返回本地节点状态。预计在调用回调时,当前可将节点求解到最佳状态。

关于回调中的异常:您正在尝试访问不在要解决的模型中的变量对象。发生这种情况的典型情况是:

  1. 您创建了变量,但是它没有出现在任何约束或目标中,即,没有在任何地方使用它。您可以通过使用变量作为参数显式调用cplex.add()来强制其使用。
  2. 该变量是在先前的迭代中创建的,并且不再是当前迭代中模型的一部分。调试此错误的一种好方法是为每个变量赋予一个名称,并使该名称包含迭代索引。然后在异常处理程序中打印有问题的变量的名称。这应该可以很好地提示问题所在。
© www.soinside.com 2019 - 2024. All rights reserved.