公共抽象静态类IloCplex.NodeEvaluator
扩展java.lang.Object
实现java.lang.Cloneable
IloCplex在分支-切割搜索过程中处理完一个节点后,它会从树中选择一个新的活动节点进行处理。 节点评估器允许你在目标控制的任何子树中实施自己的节点选择策略。节点评估器由 "IloCplex.NodeEvaluator类型的对象表示。 要创建自己的节点评估器,必须子类化类 "IloCplex.NodeEvaluator并实现抽象方法 "evaluate。
The evaluate method is called by IloCplex to compute a value for a given node. 如果有两个节点被同一个评估器评估,默认情况下,"IloCplex会选择数值较低的节点。 不过,可以通过重载方法 "subsume来更改默认行为。
如果 "clone方法的默认实现不够充分,且目标是用于并行优化,则用户还需要实现该方法。 回想一下,默认的 "clone方法执行的是浅拷贝,因此用户的实现通常会对线程本地的对象执行深拷贝,或者在需要同步的地方使用 "synchronize关键字。
如本示例所示,"IloCplex.apply方法用于将节点评估器定义的节点选择策略强加给目标控制的搜索:
IloCplex.GoalevalGoal=cplex.apply(goal,nodeEval);
In this example nodeEval is of type IloCplex.NodeEvaluator and goal is of type IloCplex.Goal. 方法 "apply创建并返回一个新目标,该目标遵循 "nodeEval定义的节点选择规则,同时执行 "goal指定的分支-切割搜索。 这样,"nodeEval定义的节点选择策略只对 "goal生成的搜索子树有效。
这也意味着,一旦目标堆栈变空,"IloCplex开始使用内置搜索策略,通过节点评估器进行的节点选择控制就会失效,取而代之的是使用参数 "IloCplex.IntParam.NodeSel控制的内置策略。 为了在使用 "IloCplex分支策略时,通过节点评估器保持对节点选择的控制,可以采用以下目标:
类DefaultSearchGoal扩展IloCplex.Goal {
publicIloCplex.Goal executeilog.opl.IloCplexcplex) throwsIloException{
如果 (!isIntegerFeasible())
returncplex.andcplex.branchAsCplex(), this);
return null;
}
}
可以使用。
节点评估器和目标之间的对应关系有一个有趣的含义,那就是你可以为不同的子树指定不同的节点选择策略。 如果 "goal1和 "goal2定义了在分支切割搜索树的两个子树中进行搜索,而 "eval1和 "eval2定义了两种不同的节点选择方案,那么目标
cplex.or(cplex.apply(goal1, eval1),
cplex.apply(goal2, eval2));
将把 "goal1定义的子树置于 "eval1的节点选择策略下,把 "goal2定义的子树置于 "eval2的节点选择策略下。
为了更好地了解如何处理多节点评估员,请参考有关评估员管理的补充信息。 当一个评估器应用于一个目标时,评估器就会附加到该目标创建的每个节点上。 这不仅包括由目标本身的 "execute方法创建的节点,还包括由 "execute方法返回的目标创建的节点,以此类推。 由于目标的 "execute方法可以创建并返回应用了其他评估器的目标,因此每个节点都可以附加一个评估器列表。 评价器的顺序是应用评价器的顺序。
每个评估器都会通过调用 "evaluate方法为其连接的每个节点计算一个值。 该方法对一个节点只调用一次,并将结果存储起来。 如果某个节点的评估结果为 "Double.MAX_VALUE(通过评估器的方法 "evaluate),那么该节点就会被从树中剪除,或者换句话说,该节点会被从树中移除,同时被移除的还有可能由它生成的整个子树。
当 "IloCplex选择下一个要处理的节点时,它会从内置节点选择策略提出的候选节点开始。 可以通过参数 "IloCplex.IntParam.NodeSel选择多种策略。
在选择了一个初始候选节点后,"IloCplex会查看分支-切割树中的剩余节点列表,看看是否有节点评估器推翻了这一决定。 因此,对于每个活动节点,"IloCplex都会检查它与当前候选节点共同的所有评价器。 默认情况下,如果共同评估者为某个节点计算出的数字低于当前候选节点的数字,则该节点将被用作新的候选节点。 不过,通过覆盖 "subsume方法,可以实现不同的覆盖标准。 评价器按照候选节点中列出的顺序进行检查。 重复这一操作,直到检查完所有节点。 在这一过程中存活下来的候选节点将被选中,作为分支-切割搜索的处理节点。
| 修饰符 | 构造函数和说明 |
|---|---|
protected |
IloCplex.NodeEvaluator()用户编写的节点评估器的构造函数。
|
| 修饰符和类型 | 方法和说明 |
|---|---|
protected abstract double |
evaluate()IloCplex为调用评估器控制的每个节点调用此方法,以计算节点的评估值。 |
protected IloNumVar |
getBranchVar()返回创建当前节点时的分支变量。
|
protected int |
getDepth()返回当前节点在搜索树中的深度。
|
protected double |
getEstimatedObjValue()返回当前节点的估计目标值。
|
protected double |
getInfeasibilitySum()返回当前节点的整数不可行性总和。
|
protected int |
getNinfeasibilities()返回当前节点的整数不可行变量个数。
|
protected IloCplex.NodeId |
getNodeId()返回当前节点的节点标识符。
|
protected double |
getObjValue()返回当前节点的目标值。
|
protected void |
init()This method is called by
IloCplex right before the first time evaluate is called for a node and allows you to initialize the evaluator based on that node. |
protected boolean |
subsume(double evalNode,
double evalCurrent)在选择下一个要处理的节点时,"
IloCplex会保留一个候选节点。 |
protectedIloCplex.NodeEvaluator()
IloCplex.NodeEvaluator对象。受保护的抽象 double evaluate()
抛出IloException
IloCplex为调用评估器控制的每个节点调用此方法,以计算节点的评估值。 然后利用这些值选择下一个要处理的节点。 如果两个节点由一个评估者控制,默认情况下,评估者会选择评估值较低的节点。 不过,可以通过重载 "subsume方法来更改。IloCplex只对每个节点调用一次 "evaluate方法,并在将该节点与其他节点进行比较时重复使用该节点的返回值。
调用此方法时,评估器已被初始化为要评估的节点,这样就可以调用调用评估器的其他方法来查询此节点的信息。 评估器初始化到的节点称为当前节点。
通过在该函数中返回 "Double.MAX_VALUE,可以指示IloCplex剪除当前节点。
IloExceptionprotected boolean subsume(doubleevalNode,
双evalCurrent)
IloCplex会保留一个候选节点。 然后将该候选节点与所有其他活动节点进行比较。 如果给定节点和候选节点由相同的评估器管理,"IloCplex会调用方法 "subsume来决定该节点是否应成为新的候选节点。 传给 subsume 调用的参数是调用评估器先前通过方法 "evaluate分配给所考虑的节点的值。 默认情况下,如果当前测试节点的评估值小于候选节点的评估值,该方法将返回 "false。 重载该功能后,您可以更改选择方案。evalNode--实际最佳候选节点的评估值。evalCurrent--被考虑替换为实际候选者的节点的评估值。true),还是应由当前测试的节点取而代之(false)。protected void init()
IloCplex right before the first time evaluate is called for a node and allows you to initialize the evaluator based on that node. 调用该方法时,可以查询节点的相关信息。对于一个评估器,"init方法只被调用一次。 由于 "init只在一个子树中被调用,因此无法在另一个子树中正确地初始化评估器,所以一般情况下无法在两个子树中使用一个评估器对象。 使用两个独立的评价器实例来克服这种习惯。
protected finalIloCplex.NodeId getNodeId() 抛出IloException
init和 "evaluate方法中调用。IloExceptionIloCplex.NodeId。protected final doublegetObjValue()
抛出IloException
init和 "evaluate方法中调用。IloExceptionprotected final doublegetEstimatedObjValue()
抛出IloException
init和 "evaluate方法中调用。IloExceptionprotected final intgetDepth()
抛出IloException
init和 "evaluate方法中调用。IloExceptionprotected final doublegetInfeasibilitySum()
抛出IloException
init和 "evaluate方法中调用。IloExceptionprotected final intgetNinfeasibilities()
抛出IloException
init和 "evaluate方法中调用。IloExceptionprotected finalIloNumVar getBranchVar() 抛出IloException
null。 该方法只能从 "init和 "evaluate方法中调用。IloException