• 1 reply
  • Latest Post - ‏2012-10-31T08:57:54Z by SystemAdmin
6 Posts

Pinned topic Different optimal value when using CP optimizer and CPLEX

‏2012-10-31T00:12:41Z |
I am getting different objective values when using CP optimizer and CPLEX to solve the same model.

Below is a small test function that reproduces the problem. When Test(false) is called it uses CPLEX and prints the correct optimal value of 10876, but when Test(true) is called it uses the CP optimizer and prints 10875 which is incorrect.

enum {S, E, N, D, M, O, T, Y};

void Test(bool use_cp) {
IloEnv env;
IloModel mod(env);
IloIntVarArray d(env, Y + 1, 0, 9);
IloIntVar money(env, IloIntMin, IloIntMax);
mod.add(money == 10000 * d[M] + 1000 * d[O] + 100 * d[N] + 10 * d[E] + d[Y]);
IloObjective obj(env, money, IloObjective::Maximize);
mod.add(d[S] != 0);
mod.add(d[M] != 0);
mod.add(1000 * d[S] + 100 * d[E] + 10 * d[N] + d[D] +
1000 * d[M] + 100 * d[O] + 10 * d[S] + d[T] == money);
for (int i = S; i <= Y; i++)
for (int j = i + 1; j <= Y; j++)
mod.add(d[i] != d[j]);
//mod.add(IloAllDiff(env, d));
std::auto_ptr<IloAlgorithm> alg(use_cp ?
static_cast<IloAlgorithm*>(new IloSolver(env)) : new IloCplex(env));
std::cout << "Obj: " << alg->getValue(obj) << std::endl;

Updated on 2012-10-31T08:57:54Z at 2012-10-31T08:57:54Z by SystemAdmin
  • SystemAdmin
    554 Posts

    Re: Different optimal value when using CP optimizer and CPLEX


    There is RelativeOptimalityTolerance parameters in play. When CP Optimizer reports an optimal solution found, then there is no solution which improves the objective by more than the absolute value of the objective times the value of this parameter. The default value of this parameter is 1e-4.

    You can change value of this parameter the following way:
    IloCP cp(env); ... cp.setParameter(IloCP::RelativeOptimalityTolerance, 0);

    Then CP Optimizer reports solution 10876.

    Note that value of this parameter may affect performance since it allows CP Optimizer to be a bit more aggressive when it search for a better solution.

    I would also recommend to use IloCP class instead of IloSolver. IloSolver is there just for backward compatibility. By default IloCP (but not IloSolver) prints a log that contains effective optimality tolerance. In your case, you would see the following in the log:
    ! Search terminated normally, 1 solution found. ! Best objective         : 10875 (optimal - effective tol. is 1)

    what gives a hint that the optimum actually can be 10876.

    Of course, it is possible to turn log off using LogVerbosity parameter.

    Best regards, Petr