Exemple #1
0
    // To populate by row, we first create the variables, and then use them to
    // create the range constraints and objective.  The model we create is:
    //
    // Minimize
    //  obj:   - 0.5 (-3 * xˆ2 - 3 * yˆ2 - 1 * x * y)
    // Subject To
    //  c1: -x + y >= 0
    //  c2:  x + y >= 0
    // Bounds
    //  -1 <= x <= 1
    //   0 <= y <= 1
    // End

    internal static ILPMatrix PopulateByRow(IMPModeler model)
    {
        ILPMatrix lp = model.AddLPMatrix();

        double[]  lb = { -1.0, 0.0 };
        double[]  ub = { 1.0, 1.0 };
        INumVar[] x  = model.NumVarArray(model.ColumnArray(lp, 2), lb, ub);

        double[]   lhs = { 0.0, 0.0 };
        double[]   rhs = { System.Double.MaxValue, System.Double.MaxValue };
        double[][] val = { new double[] { -1.0, 1.0 },
                           new double[] {  1.0, 1.0 } };
        int[][]    ind = { new int[] { 0, 1 },
                           new int[] { 0, 1 } };
        lp.AddRows(lhs, rhs, ind, val);

        INumExpr x00 = model.Prod(-3.0, x[0], x[0]);
        INumExpr x11 = model.Prod(-3.0, x[1], x[1]);
        INumExpr x01 = model.Prod(-1.0, x[0], x[1]);
        INumExpr Q   = model.Prod(0.5, model.Sum(x00, x11, x01));

        model.Add(model.Minimize(Q));

        return(lp);
    }
Exemple #2
0
    internal static ILPMatrix PopulateByRow(IMPModeler model)
    {
        ILPMatrix lp = model.AddLPMatrix();

        double[]  lb = { 0.0, 0.0, 0.0 };
        double[]  ub = { 40.0, System.Double.MaxValue, System.Double.MaxValue };
        INumVar[] x  = model.NumVarArray(model.ColumnArray(lp, 3), lb, ub);

        // - x0 +   x1 + x2 <= 20
        //   x0 - 3*x1 + x2 <= 30
        double[]   lhs = { -System.Double.MaxValue, -System.Double.MaxValue };
        double[]   rhs = { 20.0, 30.0 };
        double[][] val = { new double[] { -1.0,  1.0, 1.0 },
                           new double[] {  1.0, -3.0, 1.0 } };
        int[][]    ind = { new int[] { 0, 1, 2 },
                           new int[] { 0, 1, 2 } };
        lp.AddRows(lhs, rhs, ind, val);

        // Q = 0.5 ( 33*x0*x0 + 22*x1*x1 + 11*x2*x2 - 12*x0*x1 - 23*x1*x2 )
        INumExpr x00 = model.Prod(33.0, model.Square(x[0]));
        INumExpr x11 = model.Prod(22.0, model.Square(x[1]));
        INumExpr x22 = model.Prod(11.0, model.Square(x[2]));
        INumExpr x01 = model.Prod(-12.0, model.Prod(x[0], x[1]));
        INumExpr x12 = model.Prod(-23.0, model.Prod(x[1], x[2]));
        INumExpr Q   = model.Prod(0.5, model.Sum(x00, x11, x22, x01, x12));

        // maximize x0 + 2*x1 + 3*x2 + Q
        double[] objvals = { 1.0, 2.0, 3.0 };
        model.Add(model.Maximize(model.Diff(model.ScalProd(x, objvals), Q)));

        return(lp);
    }
Exemple #3
0
    // Creating a simple QP problem
    internal static ILPMatrix CreateQPModel(IMPModeler model)
    {
        ILPMatrix lp = model.AddLPMatrix();

        double[]  lb    = { 0.0, 0.0, 0.0 };
        double[]  ub    = { 40.0, System.Double.MaxValue, System.Double.MaxValue };
        INumVar[] x     = model.NumVarArray(model.ColumnArray(lp, 3), lb, ub);
        int       nvars = x.Length;

        for (int j = 0; j < nvars; ++j)
        {
            x[j].Name = "x" + j;
        }

        // - x0 +   x1 + x2 <= 20
        //   x0 - 3*x1 + x2 <= 30
        double[]   lhs = { -System.Double.MaxValue, -System.Double.MaxValue };
        double[]   rhs = { 20.0, 30.0 };
        double[][] val = { new double[] { -1.0,  1.0, 1.0 },
                           new double[] {  1.0, -3.0, 1.0 } };
        int[][]    ind = { new int[] { 0, 1, 2 },
                           new int[]    { 0, 1, 2 } };
        lp.AddRows(lhs, rhs, ind, val);

        // minimize - x0 - x1 - x2 + x0*x0 + x1*x1 + x0*x1 + x1*x0
        ILQNumExpr objExpr = model.LqNumExpr();

        for (int i = 0; i < nvars; ++i)
        {
            objExpr.AddTerm(-1.0, x[i]);
            for (int j = 0; j < nvars; ++j)
            {
                objExpr.AddTerm(1.0, x[i], x[j]);
            }
        }
        IObjective obj = model.Minimize(objExpr);

        model.Add(obj);

        // Print out the objective function
        PrintObjective(obj);

        return(lp);
    }
Exemple #4
0
    internal static ILPMatrix PopulateByRow(IMPModeler model)
    {
        ILPMatrix lp = model.AddLPMatrix();

        double[]  lb = { 0.0, 0.0, 0.0 };
        double[]  ub = { 40.0, System.Double.MaxValue, System.Double.MaxValue };
        INumVar[] x  = model.NumVarArray(model.ColumnArray(lp, 3), lb, ub);

        double[]   lhs = { -System.Double.MaxValue, -System.Double.MaxValue };
        double[]   rhs = { 20.0, 30.0 };
        double[][] val = { new double[] { -1.0,  1.0, 1.0 },
                           new double[] {  1.0, -3.0, 1.0 } };
        int[][]    ind = { new int[] { 0, 1, 2 },
                           new int[] { 0, 1, 2 } };
        lp.AddRows(lhs, rhs, ind, val);

        double[] objvals = { 1.0, 2.0, 3.0 };
        model.AddMaximize(model.ScalProd(x, objvals));

        return(lp);
    }
Exemple #5
0
    public static void Main(string[] args)
    {
        try {
            int ncols = 12;

            Cplex     cplex = new Cplex();
            ILPMatrix lp    = cplex.AddLPMatrix();

            // add empty corresponding to new variables columns to lp
            INumVar[] x = cplex.NumVarArray(cplex.ColumnArray(lp, ncols), 0, 50);

            // add rows to lp
            double[]   d    = { -1.0, 4.0, 1.0, 1.0, -2.0, -2.0, -1.0 };
            double[][] valH = { new double[] { -1.0, -1.0, -1.0 },
                                new double[] {  1.0,  1.0,  1.0 },
                                new double[] {  1.0,  1.0,1.0, 1.0 },
                                new double[] {  1.0,  1.0,  1.0 },
                                new double[] { -1.0, -1.0,-1.0, 1.0 },
                                new double[] { -1.0, -1.0,  1.0 },
                                new double[] { -1.0, -1.0,-1.0, -1.0 } };
            int[][]    indH = { new int[] { 7, 8,  9 },
                                new int[] { 0, 5,  7 },
                                new int[] { 1, 3,6, 8 },
                                new int[] { 2, 4,  9 },
                                new int[] { 5, 6,10, 11 },
                                new int[] { 3, 4, 10 },
                                new int[] { 0, 1,2, 11 } };

            lp.AddRows(d, d, indH, valH);

            // add the objective function
            double[] objvals = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                                 1.0, 0.0, 0.0, 0.0, 2.0, 2.0 };
            cplex.AddMinimize(cplex.ScalProd(x, objvals));

            // Solve initial problem with the network optimizer
            cplex.SetParam(Cplex.Param.RootAlgorithm, Cplex.Algorithm.Network);
            cplex.Solve();
            System.Console.WriteLine("After network optimization, objective is "
                                     + cplex.ObjValue);

            // add rows from matrix A to lp
            double[]   b    = { 2.0, 3.0 };
            double[][] valA = { new double[] { 2.0, 5.0 },
                                new double[] { 1.0,1.0, 1.0 } };
            int[][]    indA = { new int[] { 10, 11 },
                                new int[] {  0,2, 5 } };
            lp.AddRows(b, b, indA, valA);

            // Because the problem is dual feasible with the rows added, using
            // the dual simplex method is indicated.
            cplex.SetParam(Cplex.Param.RootAlgorithm, Cplex.Algorithm.Dual);
            if (cplex.Solve())
            {
                System.Console.WriteLine("Solution status = " + cplex.GetStatus());
                System.Console.WriteLine("Solution value  = " + cplex.ObjValue);

                double[] sol = cplex.GetValues(lp);
                for (int j = 0; j < ncols; ++j)
                {
                    System.Console.WriteLine("Variable " + j + ": Value = " + sol[j]);
                }
            }
            cplex.End();
        }
        catch (ILOG.Concert.Exception e) {
            System.Console.WriteLine("Concert exception '" + e + "' caught");
        }
    }
Exemple #6
0
        public override void IsoGraphInexactF1b()
        {
            this.nbRows = nbNode1 + nbEdge1 + nbNode2 + nbEdge2 + 3 * nbEdge1 * nbEdge2;                 //ns + ms+ng+mg+3msmg
            this.nbCols = nbNode1 * nbNode2 + nbEdge1 * nbEdge2 + nbNode1 + nbEdge1 + nbNode2 + nbEdge2; //nsng+msmg+ns+ms+ng+mg
            Graphs.Label nodeepslabel;

            #region objectFunction
            List <double> objList     = new List <double>();
            List <string> colNameList = new List <string>();
            List <char>   typeList    = new List <char>();
            List <Double> ubList      = new List <Double>();
            //the objet funcion
            for (int i = 1; i <= nbNode1; i++)
            {
                for (int k = 1; k <= nbNode2; k++)
                {
                    objList.Add(graph1.ListNodes[i - 1].Label.dissimilarity(graph2.ListNodes[k - 1].Label));
                    colNameList.Add("x_" + graph1.ListNodes[i - 1].Id + "," + graph2.ListNodes[k - 1].Id);
                }
            }

            for (int ij = 1; ij <= nbEdge1; ij++)
            {
                for (int kl = 1; kl <= nbEdge2; kl++)
                {
                    double costEdge = graph1.ListEdges[ij - 1].Label.dissimilarity(graph2.ListEdges[kl - 1].Label);
                    if (copyEdge)
                    {
                        objList.Add(costEdge / 2);
                    }
                    else
                    {
                        objList.Add(costEdge);
                    }
                    colNameList.Add("y_" + graph1.ListEdges[ij - 1].Id + "," + graph2.ListEdges[kl - 1].Id);
                }
            }
            for (int i = 1; i <= nbNode1; i++)
            {
                Type   typeLabel = graph1.ListNodes[i - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;

                objList.Add((graph1.ListNodes[i - 1].Label).dissimilarity(nodeepslabel));
                colNameList.Add("u_" + graph1.ListNodes[i - 1].Id + ",Ins_" + graph1.ListNodes[i - 1].Id);
            }

            for (int ij = 1; ij <= nbEdge1; ij++)
            {
                Type   typeLabel = graph1.ListEdges[ij - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                double costEdge = (graph1.ListEdges[ij - 1].Label).dissimilarity(nodeepslabel);
                if (copyEdge)
                {
                    objList.Add(costEdge / 2);
                }
                else
                {
                    objList.Add(costEdge);
                }
                colNameList.Add("e_" + graph1.ListEdges[ij - 1].Id + ",Ins_" + graph1.ListEdges[ij - 1].Id);
            }

            for (int k = 1; k <= nbNode2; k++)
            {
                Type   typeLabel = graph2.ListNodes[k - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                objList.Add((graph2.ListNodes[k - 1].Label).dissimilarity(nodeepslabel));
                colNameList.Add("v_Del_" + graph2.ListNodes[k - 1].Id + "," + graph2.ListNodes[k - 1].Id);
            }

            for (int kl = 1; kl <= nbEdge2; kl++)
            {
                Type   typeLabel = graph2.ListEdges[kl - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                double costEdge = (graph2.ListEdges[kl - 1].Label).dissimilarity(nodeepslabel);
                if (copyEdge)
                {
                    objList.Add(costEdge / 2);
                }
                else
                {
                    objList.Add(costEdge);
                }
                colNameList.Add("f_Del_" + graph2.ListEdges[kl - 1].Id + "," + graph2.ListEdges[kl - 1].Id);
            }
            #endregion

            try
            {
                cplex     = new Cplex();
                ilpMatrix = cplex.AddLPMatrix();

                // add empty corresponding to new variables columns to ilpMatrix
                INumVar[] x = cplex.NumVarArray(cplex.ColumnArray(ilpMatrix, nbCols), 0, 1, NumVarType.Bool, colNameList.ToArray());

                List <Double> lbMatrixList = new List <Double>();
                List <Double> ubMatrixList = new List <Double>();
                Int32[][]     indiceH      = new Int32[nbRows][];
                Double[][]    valeurH      = new Double[nbRows][];
                List <Int32>  jaList; //les indice des valeurs
                List <Double> arList; //les valeurs non zeros dans la ligne

                int rownum = 0;
                #region construir constraintes
                for (int i = 0; i < nbNode1; i++)
                {
                    jaList = new List <int>();
                    arList = new List <Double>();
                    lbMatrixList.Add(1.0);
                    ubMatrixList.Add(1.0);

                    for (int k = 0; k < nbNode2; k++)
                    {
                        jaList.Add(i * nbNode2 + k);
                        arList.Add(1);
                    }
                    jaList.Add(nbNode1 * nbNode2 + nbEdge1 * nbEdge2 + i);
                    arList.Add(1);
                    indiceH[rownum] = jaList.ToArray();
                    valeurH[rownum] = arList.ToArray();
                    rownum++;
                }


                // equation 3
                for (int ij = 0; ij < nbEdge1; ij++)
                {
                    jaList = new List <int>();
                    arList = new List <Double>();
                    lbMatrixList.Add(1.0);
                    ubMatrixList.Add(1.0);
                    for (int kl = 0; kl < nbEdge2; kl++)
                    {
                        jaList.Add(nbNode1 * nbNode2 + ij * nbEdge2 + kl);
                        arList.Add(1);
                    }
                    jaList.Add(nbNode1 * nbNode2 + nbEdge1 * nbEdge2 + nbNode1 + ij);
                    arList.Add(1);

                    indiceH[rownum] = jaList.ToArray();
                    valeurH[rownum] = arList.ToArray();
                    rownum++;
                }

                // contraint: equation [Fb.1]-4
                for (int k = 0; k < nbNode2; k++)
                {
                    jaList = new List <int>();
                    arList = new List <Double>();
                    lbMatrixList.Add(1.0);
                    ubMatrixList.Add(1.0);
                    for (int i = 0; i < nbNode1; i++)
                    {
                        jaList.Add(i * nbNode2 + k);
                        arList.Add(1);
                    }
                    jaList.Add(nbNode1 * nbNode2 + nbEdge1 * nbEdge2 + nbNode1 + nbEdge1 + k);
                    arList.Add(1);

                    indiceH[rownum] = jaList.ToArray();
                    valeurH[rownum] = arList.ToArray();
                    rownum++;
                }


                // equation 5
                for (int kl = 0; kl < nbEdge2; kl++)
                {
                    jaList = new List <int>();    //les indice des valeurs
                    arList = new List <Double>(); //les valeurs non zeros dans la ligne
                    lbMatrixList.Add(1.0);
                    ubMatrixList.Add(1.0);

                    for (int ij = 0; ij < nbEdge1; ij++)
                    {
                        jaList.Add(nbNode1 * nbNode2 + ij * nbEdge2 + kl);
                        arList.Add(1);
                    }
                    jaList.Add(nbNode1 * nbNode2 + nbEdge1 * nbEdge2 + nbNode1 + nbEdge1 + nbNode2 + kl);
                    arList.Add(1);

                    indiceH[rownum] = jaList.ToArray();
                    valeurH[rownum] = arList.ToArray();
                    rownum++;
                }


                //equation 6 7 8
                for (int ij = 0; ij < nbEdge1; ij++)
                {
                    for (int kl = 0; kl < nbEdge2; kl++)
                    {
                        string source_i = graph1.ListEdges[ij].NodeSource.Id;
                        string source_k = graph2.ListEdges[kl].NodeSource.Id;
                        string target_i = graph1.ListEdges[ij].NodeTarget.Id;
                        string target_k = graph2.ListEdges[kl].NodeTarget.Id;

                        string nameVar = "x_" + source_i + "," + source_k;
                        int    colInd  = SolverCPLEX.GetIndexByName(x, nameVar);
                        if (colInd == -1)
                        {
                            throw new InvalidProgramException();
                        }

                        string nameVar2 = "x_" + target_i + "," + target_k;
                        int    colInd2  = SolverCPLEX.GetIndexByName(x, nameVar2);
                        if (colInd2 == -1)
                        {
                            throw new InvalidProgramException();
                        }

                        jaList = new List <int>();
                        arList = new List <Double>();
                        lbMatrixList.Add(0.0);
                        ubMatrixList.Add(1.0);
                        jaList.Add(colInd);
                        arList.Add(1);
                        jaList.Add(nbNode1 * nbNode2 + ij * nbEdge2 + kl);
                        arList.Add(-1);
                        indiceH[rownum] = jaList.ToArray();
                        valeurH[rownum] = arList.ToArray();
                        rownum++;

                        ////////////////////////////////
                        jaList = new List <int>();
                        arList = new List <Double>();
                        lbMatrixList.Add(0.0);
                        ubMatrixList.Add(1.0);


                        jaList.Add(colInd2);
                        arList.Add(1);
                        jaList.Add(nbNode1 * nbNode2 + ij * nbEdge2 + kl);
                        arList.Add(-1);

                        indiceH[rownum] = jaList.ToArray();
                        valeurH[rownum] = arList.ToArray();
                        rownum++;

                        ////////////////////////////////////////

                        /* jaList = new List<int>();
                         * arList = new List<Double>();
                         * lbMatrixList.Add(-1.0);
                         * ubMatrixList.Add(1.0);
                         *
                         * jaList.Add(colInd);
                         * arList.Add(1);
                         * jaList.Add(colInd2);
                         * arList.Add(1);
                         * jaList.Add(nbNode1 * nbNode2 + ij * nbEdge2 + kl);
                         * arList.Add(-1);
                         *
                         * indiceH[rownum] = jaList.ToArray();
                         * valeurH[rownum] = arList.ToArray();
                         * rownum++;*/
                    }
                }
                #endregion
                double[] lb = lbMatrixList.ToArray();
                double[] ub = ubMatrixList.ToArray();

                Int32 res = ilpMatrix.AddRows(lb, ub, indiceH, valeurH);

                // add the objective function
                objCoef = objList.ToArray();
                cplex.AddMinimize(cplex.ScalProd(x, objCoef));
            }
            catch (ILOG.Concert.Exception e)
            {
                System.Console.WriteLine("Concert exception '" + e + "' caught");
            }
        }
Exemple #7
0
        //F2 version with constant and slack variables
        ////Formlation F2 for the GED problem. Very efficient.
        // https://hal.archives-ouvertes.fr/hal-01619313

        public override void IsoGraphInexactF2b()
        {
            int mincst = Math.Min((nbNode2 * nbEdge1), (nbNode1 * nbEdge2));

            this.nbRows = nbNode1 + nbNode2 + 1 * mincst;        //ns +ms+ng+mg+4ngms +4nsmg /contrainte
            this.nbCols = nbNode1 * nbNode2 + nbEdge1 * nbEdge2; //nsng+msmg+ns+ms+ng+mg //variable

            Graphs.Label nodeepslabel;

            #region objectFunction
            List <double> objList     = new List <double>();
            List <string> colNameList = new List <string>();
            List <char>   typeList    = new List <char>();
            List <Double> ubList      = new List <Double>();
            //the objetive funcion

            //variable x
            for (int i = 1; i <= nbNode1; i++)
            {
                for (int k = 1; k <= nbNode2; k++)
                {
                    Type   typeLabel = graph1.ListNodes[i - 1].Label.GetType();
                    object obj       = Activator.CreateInstance(typeLabel);
                    nodeepslabel    = (Graphs.Label)obj;
                    nodeepslabel.Id = ConstantsAC.EPS_ID;

                    double costsub = graph1.ListNodes[i - 1].Label.dissimilarity(graph2.ListNodes[k - 1].Label);
                    double costdel = graph1.ListNodes[i - 1].Label.dissimilarity(nodeepslabel);
                    double costins = nodeepslabel.dissimilarity(graph2.ListNodes[k - 1].Label);
                    double cost    = costsub - costdel - costins;
                    objList.Add(cost);
                    colNameList.Add("x_" + graph1.ListNodes[i - 1].Id + "," + graph2.ListNodes[k - 1].Id);
                }
            }

            //variable y
            for (int ij = 1; ij <= nbEdge1; ij++)
            {
                for (int kl = 1; kl <= nbEdge2; kl++)
                {
                    Type   typeLabel = graph1.ListEdges[ij - 1].Label.GetType();
                    object obj       = Activator.CreateInstance(typeLabel);
                    nodeepslabel    = (Graphs.Label)obj;
                    nodeepslabel.Id = ConstantsAC.EPS_ID;

                    double costsub = graph1.ListEdges[ij - 1].Label.dissimilarity(graph2.ListEdges[kl - 1].Label);
                    double costdel = graph1.ListEdges[ij - 1].Label.dissimilarity(nodeepslabel);
                    double costins = nodeepslabel.dissimilarity(graph2.ListEdges[kl - 1].Label);
                    double cost    = costsub - costdel - costins;
                    objList.Add(cost);

                    colNameList.Add("y_" + graph1.ListEdges[ij - 1].Id + "," + graph2.ListEdges[kl - 1].Id);
                }
            }
            double constante = 0;
            for (int i = 1; i <= nbNode1; i++)
            {
                Type   typeLabel = graph1.ListNodes[i - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                constante      += (graph1.ListNodes[i - 1].Label).dissimilarity(nodeepslabel);
            }

            for (int ij = 1; ij <= nbEdge1; ij++)
            {
                Type   typeLabel = graph1.ListEdges[ij - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                double costEdge = (graph1.ListEdges[ij - 1].Label).dissimilarity(nodeepslabel);
                constante += costEdge;
            }

            for (int k = 1; k <= nbNode2; k++)
            {
                Type   typeLabel = graph2.ListNodes[k - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                constante      += (graph2.ListNodes[k - 1].Label).dissimilarity(nodeepslabel);
                // colNameList.Add("v_Del_" + graph2.ListNodes[k - 1].Id + "," + graph2.ListNodes[k - 1].Id);
            }

            for (int kl = 1; kl <= nbEdge2; kl++)
            {
                Type   typeLabel = graph2.ListEdges[kl - 1].Label.GetType();
                object obj       = Activator.CreateInstance(typeLabel);
                nodeepslabel    = (Graphs.Label)obj;
                nodeepslabel.Id = ConstantsAC.EPS_ID;
                double costEdge = (graph2.ListEdges[kl - 1].Label).dissimilarity(nodeepslabel);
                constante += costEdge;

                //colNameList.Add("f_Del_" + graph2.ListEdges[kl - 1].Id + "," + graph2.ListEdges[kl - 1].Id);
            }
            #endregion

            try
            {
                cplex     = new Cplex();
                ilpMatrix = cplex.AddLPMatrix();

                // add empty corresponding to new variables columns to ilpMatrix
                INumVar[] x = cplex.NumVarArray(cplex.ColumnArray(ilpMatrix, nbCols), 0, 1, NumVarType.Bool, colNameList.ToArray());

                List <Double> lbMatrixList = new List <Double>();
                List <Double> ubMatrixList = new List <Double>();
                Int32[][]     indiceH      = new Int32[nbRows][];
                Double[][]    valeurH      = new Double[nbRows][];
                List <Int32>  jaList; //les indice des valeurs
                List <Double> arList; //les valeurs non zeros dans la ligne

                int rownum = 0;
                #region construire constraintes
                //18.B
                for (int i = 0; i < nbNode1; i++)
                {
                    jaList = new List <int>();
                    arList = new List <Double>();
                    lbMatrixList.Add(0.0);
                    ubMatrixList.Add(1.0);

                    for (int k = 0; k < nbNode2; k++)
                    {
                        jaList.Add(i * nbNode2 + k);
                        arList.Add(1);
                    }
                    indiceH[rownum] = jaList.ToArray();
                    valeurH[rownum] = arList.ToArray();
                    rownum++;
                }


                // contraint: equation [Fb.1]-4
                //18.c
                for (int k = 0; k < nbNode2; k++)
                {
                    jaList = new List <int>();
                    arList = new List <Double>();
                    lbMatrixList.Add(0.0);
                    ubMatrixList.Add(1.0);
                    for (int i = 0; i < nbNode1; i++)
                    {
                        jaList.Add(i * nbNode2 + k);
                        arList.Add(1);
                    }

                    indiceH[rownum] = jaList.ToArray();
                    valeurH[rownum] = arList.ToArray();
                    rownum++;
                }



                if (nbNode2 * nbEdge1 < nbNode1 * nbEdge2)
                {
                    //6 If two vertices are matched together,
                    //an edge originating one of these two vertices must be matched with an edge originating the other vertex)
                    //18.F
                    for (int k = 0; k < nbNode2; k++)
                    {
                        for (int ij = 0; ij < nbEdge1; ij++)
                        {
                            jaList = new List <int>();    //les indice des valeurs
                            arList = new List <Double>(); //les valeurs non zeros dans la ligne
                            lbMatrixList.Add(0.0);
                            ubMatrixList.Add(1.0);


                            string sourcei   = graph1.ListEdges[ij].NodeSource.Id;
                            string nameVarik = "x_" + sourcei + "," + graph2.ListNodes[k].Id;
                            int    colIndxik = SolverCPLEX.GetIndexByName(x, nameVarik);
                            if (colIndxik == -1)
                            {
                                throw new InvalidProgramException();
                            }

                            jaList.Add(colIndxik);
                            arList.Add(1);

                            string sourcej    = graph1.ListEdges[ij].NodeTarget.Id;
                            string nameVarxjk = "x_" + sourcej + "," + graph2.ListNodes[k].Id;
                            int    colIndxjk  = SolverCPLEX.GetIndexByName(x, nameVarxjk);
                            if (colIndxjk == -1)
                            {
                                throw new InvalidProgramException();
                            }

                            jaList.Add(colIndxjk);
                            arList.Add(1);

                            string name1 = graph1.ListEdges[ij].Id;
                            foreach (Edge e in graph2.ListNodes[k].ListEdgesOut)
                            {
                                string name2   = e.Id;
                                string nameVar = "y_" + name1 + "," + name2;
                                int    colInd  = SolverCPLEX.GetIndexByName(x, nameVar);
                                if (colInd == -1)
                                {
                                    throw new InvalidProgramException();
                                }
                                jaList.Add(colInd);
                                arList.Add(-1);
                            }



                            indiceH[rownum] = jaList.ToArray();
                            valeurH[rownum] = arList.ToArray();
                            rownum++;
                        }
                    }
                }
                else
                {
                    //Todo
                    for (int i = 0; i < nbNode1; i++)
                    {
                        for (int kl = 0; kl < nbEdge2; kl++)
                        {
                            jaList = new List <int>();    //les indice des valeurs
                            arList = new List <Double>(); //les valeurs non zeros dans la ligne
                            lbMatrixList.Add(0.0);
                            ubMatrixList.Add(1.0);


                            string sourcei   = graph2.ListEdges[kl].NodeSource.Id;
                            string nameVarik = "x_" + graph1.ListNodes[i].Id + "," + sourcei;
                            int    colIndxik = SolverCPLEX.GetIndexByName(x, nameVarik);
                            if (colIndxik == -1)
                            {
                                throw new InvalidProgramException();
                            }

                            jaList.Add(colIndxik);
                            arList.Add(1);

                            string sourcej    = graph2.ListEdges[kl].NodeTarget.Id;
                            string nameVarxjk = "x_" + graph1.ListNodes[i].Id + "," + sourcej;
                            int    colIndxjk  = SolverCPLEX.GetIndexByName(x, nameVarxjk);
                            if (colIndxjk == -1)
                            {
                                throw new InvalidProgramException();
                            }

                            jaList.Add(colIndxjk);
                            arList.Add(1);

                            string name1 = graph2.ListEdges[kl].Id;
                            foreach (Edge e in graph1.ListNodes[i].ListEdgesOut)
                            {
                                string name2   = e.Id;
                                string nameVar = "y_" + name2 + "," + name1;
                                int    colInd  = SolverCPLEX.GetIndexByName(x, nameVar);
                                if (colInd == -1)
                                {
                                    throw new InvalidProgramException();
                                }
                                jaList.Add(colInd);
                                arList.Add(-1);
                            }

                            indiceH[rownum] = jaList.ToArray();
                            valeurH[rownum] = arList.ToArray();
                            rownum++;
                        }
                    }
                }

                #endregion
                Int32 res = ilpMatrix.AddRows(lbMatrixList.ToArray(), ubMatrixList.ToArray(), indiceH, valeurH);

                // add the objective function
                objCoef = objList.ToArray();
                cplex.AddMinimize(cplex.Sum(cplex.Constant(constante), cplex.ScalProd(x, objCoef)));
            }
            catch (ILOG.Concert.Exception e)
            {
                System.Console.WriteLine("Concert exception '" + e + "' caught");
            }
        }