//A quadratic interger program for graph matching, //When tuned with the right similarity function it can represent the GED problem. // See Pattern Reocgnition Paper paper On the unification of graph matching and graph edit distance paper. //The directed version has not been tested yet public override void QAPGMGED() { //some important variables int nbNode1 = graph1.ListNodes.Count; int nbNode2 = graph2.ListNodes.Count; int nbvar = nbNode1 * nbNode2; // number of variables int nbcontraintes = nbNode1 + nbNode2; // number of constraints Graphs.Label nodeepslabel; //Adjacency matrices MatrixLibrary.Matrix adj1 = graph1.calculateAdjacencyMatrix(); MatrixLibrary.Matrix adj2 = graph2.calculateAdjacencyMatrix(); //Similarity matrix Double[,] S = new Double[nbvar, nbvar]; //Creation of the Similarity matrix //4 for loops integrated int countrow = -1; for (int i = 0; i < nbNode1; i++) { Node nodei = graph1.ListNodes[i]; for (int k = 0; k < nbNode2; k++) { Node nodek = graph2.ListNodes[k]; countrow = countrow + 1; int countcol = -1; for (int j = 0; j < nbNode1; j++) { Node nodej = graph1.ListNodes[j]; for (int l = 0; l < nbNode2; l++) { Node nodel = graph2.ListNodes[l]; countcol = countcol + 1; if (i == j && k == l) // Similarity between nodes { Type typeLabel = nodei.Label.GetType(); object obj = Activator.CreateInstance(typeLabel); nodeepslabel = (Graphs.Label)obj; nodeepslabel.Id = ConstantsAC.EPS_ID; double costsub = nodei.Label.dissimilarity(nodek.Label); double costdel = nodei.Label.dissimilarity(nodeepslabel); double costins = nodeepslabel.dissimilarity(nodek.Label); double cost = costsub - costdel - costins; cost *= -1; S[countrow, countcol] = cost; } else // Similarity between edges { int connect1 = (int)adj1[i, j]; int connect2 = (int)adj2[k, l]; if (connect1 == 1 && connect2 == 1) // Two edges are connected { Edge ij = findedge(nodei, nodej); Edge kl = findedge(nodek, nodel); Type typeLabel = ij.Label.GetType(); object obj = Activator.CreateInstance(typeLabel); nodeepslabel = (Graphs.Label)obj; nodeepslabel.Id = ConstantsAC.EPS_ID; double costsub = ij.Label.dissimilarity(kl.Label); double costdel = ij.Label.dissimilarity(nodeepslabel); double costins = nodeepslabel.dissimilarity(kl.Label); double cost = costsub - costdel - costins; cost *= -1; //cost *= 0.5; S[countrow, countcol] = cost; } } } } } } //We compute the constant that represents the //deletion and insertion of the nodes and edges //deletions of the nodes of g1 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); } //deletions of the edges of g1 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; } //insertions of the nodes of g2 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); } //insertions of the edges of g2 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; } // the number of variables is the number of columns int nbCols = nbvar; // the number of constraints is the number of rows int nbRows = nbcontraintes; List <string> colNameList = new List <string>(); //We create the name of the vrariables for all couples of nodes in g1 and g2 for (int i = 0; i < nbNode1; i++) { for (int k = 0; k < nbNode2; k++) { colNameList.Add("x_" + graph1.ListNodes[i].Id + "," + graph2.ListNodes[k].Id + ""); } } try { cplex = new Cplex(); // creation du modèle CPLEX this.ilpMatrix = cplex.AddLPMatrix(); // matrice du pb (initialisée à 0 colonnes et 0 lignes) ColumnArray colonnes = cplex.ColumnArray(ilpMatrix, nbCols); // définition des variables-colonnes du pb // ajout des variables-colonnes dans la matrice du pb // y is a vector INumVar[] y = cplex.NumVarArray(colonnes, 0, 1, NumVarType.Bool, colNameList.ToArray()); #region création fonction objectif // CALCUL DES COEFFICIENTS // We create the ojective function INumExpr[] coeffs_expr = new INumExpr[nbvar * nbvar]; // vecteur des coeffs des coûts des arrêtes int count = 0; for (int ik = 0; ik < nbvar; ik++) { for (int jl = 0; jl < nbvar; jl++) { coeffs_expr[count] = cplex.Prod(y[ik], y[jl]); coeffs_expr[count] = cplex.Prod(S[ik, jl], coeffs_expr[count]); count = count + 1; } } INumExpr ff = cplex.Sum(coeffs_expr); INumExpr gg = cplex.Sum(ff, cplex.Constant(-constante)); cplex.AddMaximize(gg); #endregion #region définition des contraintes du pb // We create the constraints // The sum of x variables by rows for (int i = 0; i < nbNode1; i++) { INumVar[] sommeLignes = new INumVar[nbNode2]; for (int k = 0; k < nbNode2; k++) { string nameVarik = "x_" + i + "," + k; int indexik = SolverCPLEX.GetIndexByName(y, nameVarik); sommeLignes[k] = y[indexik]; } cplex.AddLe(cplex.Sum(sommeLignes), 1); } // The sum of x variables by columns for (int k = 0; k < nbNode2; k++) { INumVar[] sommeLignes = new INumVar[nbNode1]; for (int i = 0; i < nbNode1; i++) { string nameVarik = "x_" + i + "," + k; int indexik = SolverCPLEX.GetIndexByName(y, nameVarik); sommeLignes[i] = y[indexik]; } cplex.AddLe(cplex.Sum(sommeLignes), 1); } #endregion } catch (ILOG.Concert.Exception e) { System.Console.WriteLine("Concert exception `" + e + "` caught"); } }
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"); } }
//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"); } }