2

I used C++ and CPLEX to write a model as following. There is no mistake when writing. However, when I run it, it showed the Error:Using empty handle. I'm puzzled about where is the mistake and how to solve it. Thanks for any help!


This is the major part of this model [enter image description here][1]


this model is to calculate the optimal sequence, distributing different job into sublots and determiner the number of sublots


if could, i want to know how to solve this problem

ILOSTLBEGIN

   //params
   #define I  3   //job classification  
   #define M 1000 //a big number   
   #define K  6   //machine number,0 for dummy machine 
   #define minS 10 //minimum sublot number

   //types of params
   typedef IloArray<IloNumArray> Float2D;
   typedef IloArray<Float2D> Float3D;
   //typedef IloArray<IloNumArray> Float3D;

   //types of vars
   typedef IloArray<IloIntVarArray> IntVar2D;
   typedef IloArray<IloNumVarArray> FloatVar2D;
   typedef IloArray<IloBoolVarArray> BoolVar2D;
   typedef IloArray<FloatVar2D> FloatVar3D;
   typedef IloArray<FloatVar3D> FloatVar4D;
   typedef IloArray<BoolVar2D> BoolVar3D;
   typedef IloArray<BoolVar3D> BoolVar4D;

   int main(int argc, char **argv)
   {
    IloEnv env;
    try
    {
        IloModel model(env);

        //params
        Float2D     processtime(env, I);  
        IloNumArray limit(env, I);       
        Float3D     setuptime(env, I);  
        IloNumArray totalnum(env, I);    


        totalnum[0] = 70; totalnum[1] = 50; totalnum[2] = 100;

        for (int i = 0; i < I; i++)
        {
            limit[i] = totalnum[i] / minS;
        }

        for (int i = 0; i < I; i++)
        {
            processtime[i] = IloNumArray(env, K);
            setuptime[i] = Float2D(env, I);
        }

        for (int i = 0; i < I; i++)
        {
            for (int j = 0; j < I; j++)
            {
                setuptime[i][j] = IloNumArray(env, K);
            }
        }

        processtime[0][0] = 0; processtime[0][1] = 10; processtime[0][2] =20; 
           processtime[0][3] = 0; processtime[0][4] = 30; processtime[0][5] = 0;
        processtime[1][0] = 0; processtime[1][1] = 0;  processtime[1][2] =40; 
           processtime[1][3] = 50; processtime[1][4] = 0; processtime[1][5] =70;
        processtime[2][0] = 0; processtime[2][1] = processtime[2][2] = 
           processtime[2][3] = processtime[2][4] = processtime[2][5] = 45;
            // setuptime for different job
        for (int i = 0; i < I; i++)
        {
            for (int j = 0; j < I; j++)
            {
                for (int k = 1; k < K; k++)
                {
                    setuptime[i][j][k] = abs(i - j)*k / 2;

                }
            }
        }
        //variables
        BoolVar2D   y(env, I);  
        IntVar2D    S(env, I);  
        IntVar2D    n(env, I);  
        BoolVar4D   x(env, I);  
        FloatVar3D  t(env, I); 
        IloNumVar  Cmax(env); 
           //matrix definition
        for (int i = 0; i < I; i++)
        {
            y[i] = IloBoolVarArray(env, limit[i]);
            S[i] = IloIntVarArray(env, limit[i]);
            n[i] = IloIntVarArray(env, limit[i], 0, IloInfinity);
            x[i] = BoolVar3D(env, limit[i]);
            t[i] = FloatVar2D(env, limit[i]);
            for (int j = 0; j < limit[i]; j++)
            {
                x[i][j] = BoolVar2D(env, I);
                t[i][j] = IloNumVarArray(env, K, 0, IloInfinity, ILOFLOAT);
                for (int g = 0; g < I; g++)
                {
                    x[i][j][g] = IloBoolVarArray(env, limit[g]);
                }
            }
        }

        //objective
        IloExpr obj(env);
        obj = Cmax;
        model.add(IloMinimize(env, obj));
        obj.end();


       //constraint
        for (int i = 0; i < I; i++)
        {
            for (int j = 0; j < limit[i]; j++)
            {
                model.add(t[i][j][0] == 0);
                model.add(S[i][j] == n[i][j] * minS);
                model.add(S[i][j] >= y[i][j] * minS);
                model.add(S[i][j] <= y[i][j] * M);
            }
        }
            /constraint
        for (int k = 1; k < K; k++)
        {
            for (int i = 0; i < I; i++)
            {
                for (int j = 0; j < limit[i]; j++)
                {
                    for (int g = 0; g < I; g++)
                    {
                        for (int h = 0; h < limit[g]; h++)
                        {
                            if (g != i && h != j)
                                model.add(x[i][j][g][h] + x[g][h][i][j] == 
               1);
                                model.add(t[i][j][k] >= t[g][h][k] + S[i][j] 
         * processtime[i][k] + setuptime[g][i][k] - 
                                (2 + x[i][j][g][h] - y[i][j] - y[g][h])*M);
                        }
                    }
                }
            }
        }
           //constraint
        for (int i = 0; i < I; i++)
        {
            for (int j = 0; j < limit[i]; j++)
            {
                for (int k = 1; k < K; k++)
                {
                    model.add(t[i][j][k] >= t[i][j][k - 1] + S[i][j] 
                    *processtime[i][k]);
                }
            }
        }
        for (int i = 0; i < I; i++)
        {
            IloExpr con4(env);
            for (int j = 0; j < limit[i]; j++)
            {
                con4 += S[i][j];
            }
            model.add(con4 == totalnum[i]);
            con4.end();
        }

        for (int i = 0; i < I; i++)
        {
            for (int j = 0; j < limit[i]; j++)
            {
                model.add(Cmax >= t[i][j][5]);
            }
        }

        IloCplex cplex(model);

        cplex.solve();

        if (cplex.getStatus() == IloAlgorithm::Infeasible)
            env.out() << "No Solution" << endl;
        else
            for (int i = 0; i < I; i++)
            {
                for (int j = 0; j < limit[i]; j++)
                {
                    for (int g = 0; g < I; g++)
                    {
                        for (int h = 0; h < limit[g]; h++)
                        {
                            env.out() << cplex.getValue(x[i][j][g][h]) << endl;
                        }
                    }
                }
            }

Thanks for any help!

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
Daniel
  • 21
  • 1
  • 2
    Can you use a debugger to get the line number causing "Error:Using empty handle"? – doctorlove Jul 09 '18 at 13:38
  • The problem is that the debugger showed no line number for the mistake. There is no syntax error. When I run the code the screen just occurs and shows the word. I am sure it's not the software's problem because I have try another code. – Daniel Jul 09 '18 at 13:54
  • Does the same happen if you comment out all the contents of your main file? – doctorlove Jul 09 '18 at 14:23
  • 1
    Empty handle errors usually mean that you're trying to use something that wasn't properly initialized, probably something to do with your Int/Float/Bool Vars. – Philippe Olivier Jul 09 '18 at 14:24
  • Thanks for your help! The problem has been solved. I forgot to add the bound for one variable but the debugger didn't show the error. – Daniel Jul 10 '18 at 02:26

1 Answers1

0

At least on Linux, with gdb, you can use catch throw (e.g., see Run an Application in GDB Until an Exception Occurs)

The problem comes from the following block of code:

//variables
BoolVar2D   y(env, I);  
IntVar2D    S(env, I);  
IntVar2D    n(env, I);  
BoolVar4D   x(env, I);  
FloatVar3D  t(env, I); 
IloNumVar  Cmax(env); 
//matrix definition
for (int i = 0; i < I; i++)
{
    y[i] = IloBoolVarArray(env, limit[i]);
    S[i] = IloIntVarArray(env, limit[i]); // <-- HERE
    n[i] = IloIntVarArray(env, limit[i], 0, IloInfinity);
    x[i] = BoolVar3D(env, limit[i]);
    t[i] = FloatVar2D(env, limit[i]);
    for (int j = 0; j < limit[i]; j++)
    {
        x[i][j] = BoolVar2D(env, I);
        t[i][j] = IloNumVarArray(env, K, 0, IloInfinity, ILOFLOAT);
        for (int g = 0; g < I; g++)
        {
            x[i][j][g] = IloBoolVarArray(env, limit[g]);
        }
     }
 }

You need to replace the following line:

S[i] = IloIntVarArray(env, limit[i]);

with something like:

S[i] = IloIntVarArray(env, limit[i], 0, IloIntMax);

The key point is that the two-argument constructor creates an array with empty handles. So you have to initialize each slot or use one of the other constructor overloads (as above).

The documentation for IloIntVarArray(IloEnv, IloInt) says:

This constructor creates an extensible array of n integer variables.

But, it should say:

This constructor creates an extensible array of n integer variables. Initially, the n elements are empty handles.

As it does for IloNumVarArray(IloEnv, IloInt).

rkersh
  • 4,447
  • 2
  • 22
  • 31