Model model = solution.getModel();
double bestEval = 0.0;
Vector best = null;
for (Enumeration e=model.variables().elements();e.hasMoreElements();) {
Variable variable = (Variable)e.nextElement();
Value assigned = variable.getAssignment();
double assignedVal = (assigned==null?iConflictWeight:iValueWeight*assigned.toDouble());
for (Enumeration f=variable.values().elements();f.hasMoreElements();) {
Value value = (Value)f.nextElement();
if (value.equals(assigned)) continue;
double eval = iValueWeight*value.toDouble() - assignedVal;
if (acceptConflicts) {
Set conflicts = model.conflictValues(value);
for (Iterator i=conflicts.iterator();i.hasNext();) {
Value conflict = (Value)i.next();
eval -= iValueWeight*conflict.toDouble();
eval += iConflictWeight * (1.0+(iStat==null?0.0:iStat.countRemovals(solution.getIteration(), conflict, value)));
}
} else {
if (model.inConflict(value)) continue;
}
if (iTabu!=null && iTabu.contains(tabuElement(value))) {
int un = model.nrUnassignedVariables()-(assigned==null?0:1);
if (un>model.getBestUnassignedVariables()) continue;
if (un==model.getBestUnassignedVariables() && model.getTotalValue()+eval>=solution.getBestValue()) continue;
}
if (best==null || bestEval>eval) {
if (best==null)
best = new Vector();
else
best.clear();
best.add(value);
bestEval = eval;
} else if (bestEval==eval) {
best.add(value);
}
}
}
if (best==null) {
sLog.debug(" [tabu] --none--");
iFirstIteration=-1;
if (iTabu!=null) iTabu.clear();
return null;
}
Value bestVal = (Value)ToolBox.random(best);
if (sLog.isDebugEnabled()) {
Set conflicts = model.conflictValues(bestVal);
double wconf = (iStat==null?0.0:iStat.countRemovals(solution.getIteration(), conflicts, bestVal));
sLog.debug(" [tabu] "+bestVal+" ("+(bestVal.variable().getAssignment()==null?"":"was="+bestVal.variable().getAssignment()+", ")+"val="+bestEval+(conflicts.isEmpty()?"":", conf="+(wconf+conflicts.size())+"/"+conflicts)+")");
}
if (iTabu!=null)
iTabu.add(tabuElement(bestVal));
return new SimpleNeighbour(bestVal.variable(),bestVal);
}