public void callback(glp_tree tree) { if (GLPK.glp_ios_reason(tree) == GLPK.GLP_IROWGEN) { string prt = ""; for (int i = 0; i < data.nodeList.Count; i++) { for (int j = 0; j < data.nodeList.Count - 1; j++) { int j2 = j; if (j >= i) { j2++; } prt += i + "->" + j2 + " : " + GLPK.glp_get_col_prim(problem, arc[i, j2]) + " ;"; } } Console.WriteLine(prt); remove_inactive(tree); generate_rows(); } }
/** * write simplex solution * @param lp problem */ static void write_lp_solution(glp_prob lp) { int i; int n; String name; double val; name = GLPK.glp_get_obj_name(lp); val = GLPK.glp_get_obj_val(lp); Console.Write(name); Console.Write(" = "); Console.WriteLine(val); n = GLPK.glp_get_num_cols(lp); for (i = 1; i <= n; i++) { name = GLPK.glp_get_col_name(lp, i); val = GLPK.glp_get_col_prim(lp, i); Console.Write(name); Console.Write(" = "); Console.WriteLine(val); } }
public int[] getNextPointFromIndex(int index, bool mip) { for (int i = 0; i < data.nodeList.Count; i++) { if (i != index) { if (mip) { if (GLPK.glp_mip_col_val(problem, arc[index, i]) == 1) { return(new int[] { i, (data.nodeList.Count - 1) * index + i }); } } else { if (GLPK.glp_get_col_prim(problem, arc[index, i]) == 1) { return(new int[] { i, (data.nodeList.Count - 1) * index + i }); } } } } return(new int[] { -1, -1 }); }
public double this[int index] { get { return(GLPK.glp_get_col_prim(mip.problem, index + 1)); } }
/** * Generates violated transitivity constraints and adds them to the current * subproblem. As suggested by Juenger et al., only only arc-disjoint * violated constraints are considered. * * @return number of generated constraints */ private int generate_rows() { int i, j, k, cnt, row; int[,] u; SWIGTYPE_p_int ind = GLPK.new_intArray(1 + 3); SWIGTYPE_p_double val = GLPK.new_doubleArray(1 + 3); double r; /* u[i,j] = 1, if arc (i->j) is covered by some constraint */ u = new int[1 + n, 1 + n]; cnt = 0; for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { for (k = 1; k <= n; k++) { if (i == j) { } else if (i == k) { } else if (j == k) { } else if (u [i, j] != 0 || u [j, i] != 0) { } else if (u [i, k] != 0 || u [k, i] != 0) { } else if (u [j, k] != 0 || u [k, j] != 0) { } else { /* check if x[i,j] + x[j,k] + x[k,i] <= 2 */ r = GLPK.glp_get_col_prim(prob, x [i, j]) + GLPK.glp_get_col_prim(prob, x [j, k]) + GLPK.glp_get_col_prim(prob, x [k, i]); /* should note that it is not necessary to add to the * current subproblem every violated constraint (3), for * which r > 2; if r < 3, we can stop adding violated * constraints, because for integer feasible solution * the value of r is integer, so r < 3 is equivalent to * r <= 2; on the other hand, adding violated * constraints leads to tightening the feasible region * of LP relaxation and, thus, may reduce the size of * the search tree */ if (r > 2.15) { /* generate violated transitivity constraint */ row = GLPK.glp_add_rows(prob, 1); GLPK.glp_set_row_bnds(prob, row, GLPK.GLP_UP, 0, 2); GLPK.intArray_setitem(ind, 1, x [i, j]); GLPK.doubleArray_setitem(val, 1, 1); GLPK.intArray_setitem(ind, 2, x [j, k]); GLPK.doubleArray_setitem(val, 2, 1); GLPK.intArray_setitem(ind, 3, x [k, i]); GLPK.doubleArray_setitem(val, 3, 1); GLPK.glp_set_mat_row(prob, row, 3, ind, val); u [i, j] = u [j, i] = 1; u [i, k] = u [k, i] = 1; u [j, k] = u [k, j] = 1; cnt++; } } } } } GLPK.delete_intArray(ind); GLPK.delete_doubleArray(val); Console.WriteLine(cnt + " violated constraints were generated"); return(cnt); }
public List <Route> getSubroutes(bool mip) { List <Route> subs = new List <Route>(); List <int> indexes = new List <int>(Enumerable.Range(0, data.nodeList.Count)); while (indexes.Count != 0) { Route route = new Route(); int index = indexes[0]; int firstIndex = index; route.addNode(index, data); indexes.Remove(index); for (int i = 0; i < data.nodeList.Count; i++) { if (i != index) { if (mip) { if (GLPK.glp_mip_col_val(problem, arc[index, i]) == 1) { index = i; break; } } else { if (GLPK.glp_get_col_prim(problem, arc[index, i]) == 1) { index = i; break; } } } } if (index == -1) { continue; } bool brk = false; while (index != firstIndex) { route.addNode(index, data); indexes.Remove(index); index = getNextPointFromIndex(index, mip)[0]; if (index == -1) { brk = true; break; } } if (!brk) { subs.Add(route); } } return(subs); }
/// <summary> /// Génère les contraintes violées /// </summary> /// <returns></returns> private int generate_rows() { int row; int cnt = 0; int n = data.nodeList.Count; List <Route> subs = getSubroutes(false); //Calcule les sous routes SWIGTYPE_p_int ind; SWIGTYPE_p_double val; if (subs.Count > 1) { OnPartialSolutionFound(new SolutionFoundEventArgs(subs)); //On retourne une solution partielle foreach (Route sub in subs) { //Si la sous route a plus de deux noeuds if (sub.nodesIndex.Count >= 2) { double constraintValue = 0; for (int i = 0; i < sub.nodesIndex.Count - 1; i++) { constraintValue += GLPK.glp_get_col_prim(problem, arc[sub.nodesIndex[i], sub.nodesIndex[i + 1]]); } constraintValue += GLPK.glp_get_col_prim(problem, arc[sub.nodesIndex[sub.nodesIndex.Count - 1], sub.nodesIndex[0]]); if (constraintValue > sub.nodesIndex.Count - 1) { cnt++; ind = GLPK.new_intArray(sub.nodesIndex.Count + 1); val = GLPK.new_doubleArray(sub.nodesIndex.Count + 1); row = GLPK.glp_add_rows(problem, 1); GLPK.glp_set_row_bnds(problem, row, GLPK.GLP_UP, 0, sub.nodesIndex.Count - 1); for (int i = 0; i < sub.nodesIndex.Count - 1; i++) { GLPK.intArray_setitem(ind, i + 1, arc[sub.nodesIndex[i], sub.nodesIndex[i + 1]]); GLPK.doubleArray_setitem(val, i + 1, 1); } GLPK.intArray_setitem(ind, sub.nodesIndex.Count - 1 + 1, arc[sub.nodesIndex[sub.nodesIndex.Count - 1], sub.nodesIndex[0]]); GLPK.doubleArray_setitem(val, sub.nodesIndex.Count - 1 + 1, 1); GLPK.glp_set_mat_row(problem, row, sub.nodesIndex.Count, ind, val); GLPK.delete_intArray(ind); GLPK.delete_doubleArray(val); } } } } ind = GLPK.new_intArray(n - 1 + 1); val = GLPK.new_doubleArray(n - 1 + 1); for (int i = 0; i < n; i++) { double cVal = 0; for (int j = 0; j < n - 1; j++) { int j2 = j; if (j >= i) { j2++; } cVal += GLPK.glp_get_col_prim(problem, arc[i, j2]); } if (Math.Abs(cVal - 1) > Math.Pow(10, -5)) { cnt++; row = GLPK.glp_add_rows(problem, 1); //On créé la ligne du simplexe for (int k = 0; k < n - 1; k++) { int k2 = k; //Exclusion de l'arc i->i if (k >= i) { k2++; } GLPK.glp_set_row_bnds(problem, row, GLPK.GLP_FX, 1, 1); //On affecte la contrainte d'égalité GLPK.intArray_setitem(ind, k + 1, arc[i, k2]); //On considere la variable l'arc allant de i à j2 GLPK.doubleArray_setitem(val, k + 1, 1.0); //On lui associe la valeur 1 dans la matrice du simplexe } GLPK.glp_set_mat_row(problem, row, n - 1, ind, val); //On ajoute la ligne au problème } } ind = GLPK.new_intArray(n - 1 + 1); val = GLPK.new_doubleArray(n - 1 + 1); for (int i = 0; i < n; i++) { double cVal = 0; for (int j = 0; j < n - 1; j++) { int j2 = j; if (j >= i) { j2++; } cVal += GLPK.glp_get_col_prim(problem, arc[j2, i]); } if (Math.Abs(cVal - 1) > Math.Pow(10, -5)) { cnt++; row = GLPK.glp_add_rows(problem, 1); //On créé la ligne du simplexe for (int k = 0; k < n - 1; k++) { int k2 = k; //Exclusion de l'arc i->i if (k >= i) { k2++; } GLPK.glp_set_row_bnds(problem, row, GLPK.GLP_FX, 1, 1); //On affecte la contrainte d'égalité GLPK.intArray_setitem(ind, k + 1, arc[k2, i]); //On considere la variable l'arc allant de i à j2 GLPK.doubleArray_setitem(val, k + 1, 1.0); //On lui associe la valeur 1 dans la matrice du simplexe } GLPK.glp_set_mat_row(problem, row, n - 1, ind, val); //On ajoute la ligne au problème } } GLPK.delete_intArray(ind); GLPK.delete_doubleArray(val); logger.log(cnt + " violated constraints were generated", Message.Level.Normal); Console.WriteLine(cnt + " violated constraints were generated"); return(cnt); }
/// <summary> /// Génère les contraintes violées /// </summary> /// <returns></returns> private int generate_rows() { //On répète le processus de génération en ajoutant //la contrainte que si elle est violée if (sol.varsIdList.Count < 2) { int n = nodeCount; int cnt = 0; SWIGTYPE_p_int ind = GLPK.new_intArray(n - 1 + 1); SWIGTYPE_p_double val = GLPK.new_doubleArray(n - 1 + 1); for (int i = 0; i < nodeCount; i++) { int arcCount = 0; for (int j = 0; j < nodeCount - 1; j++) { int j2 = j; if (j >= i) { j2++; } if (GLPK.glp_get_col_prim(problem, arc[i, j2]) == 1) { arcCount++; } } if (arcCount != 1) { cnt++; regenerateConstraint1Low(i, ind, val, out ind, out val); } } for (int i = 0; i < nodeCount; i++) { int arcCount = 0; for (int j = 0; j < nodeCount - 1; j++) { int j2 = j; if (j >= i) { j2++; } if (GLPK.glp_get_col_prim(problem, arc[j2, i]) == 1) { arcCount++; } } if (arcCount != 1) { cnt++; regenerateConstraint2Low(i, ind, val, out ind, out val); } } return(cnt); } else { double arcCount; int row; int n = data.nodeList.Count - sol.varsIdList.Count + 2; SWIGTYPE_p_int ind = GLPK.new_intArray(n - 2 + 1); SWIGTYPE_p_double val = GLPK.new_doubleArray(n - 2 + 1); int cnt = 0; for (int i = 0; i < n - 2; i++) { arcCount = 0; for (int j = 0; j < n - 3; j++) { int j2 = j; if (j >= i) { j2++; } arcCount += GLPK.glp_get_col_prim(problem, arc[i, j2]); } arcCount += GLPK.glp_get_col_prim(problem, arc[i, n - 2]); if (Math.Abs(arcCount - 1) > Math.Pow(10, -6)) { regenerateConstraint1High(i, ind, val, out ind, out val); } } arcCount = 0; for (int j = 0; j < n - 2; j++) { arcCount += GLPK.glp_get_col_prim(problem, arc[j, n - 2]); } if (Math.Abs(arcCount - 1) > Math.Pow(10, -6)) { row = GLPK.glp_add_rows(problem, 1); for (int i = 0; i < n - 2; i++) { GLPK.glp_set_row_bnds(problem, row, GLPK.GLP_FX, 1, 1); //On affecte la contrainte d'égalité GLPK.intArray_setitem(ind, i + 1, arc[i, n - 2]); //On considere la variable l'arc allant de i à j2 GLPK.doubleArray_setitem(val, i + 1, 1.0); //On lui associe la valeur 1 dans la matrice du simplexe } GLPK.glp_set_mat_row(problem, row, n - 2, ind, val); //On ajoute la ligne au problème } for (int i = 0; i < n - 2; i++) { arcCount = 0; for (int j = 0; j < n - 3; j++) { int j2 = j; if (j >= i) { j2++; } arcCount += GLPK.glp_get_col_prim(problem, arc[j2, i]); } arcCount += GLPK.glp_get_col_prim(problem, arc[n - 1, i]); if (Math.Abs(arcCount - 1) > Math.Pow(10, -6)) { regenerateConstraint2High(i, ind, val, out ind, out val); } } arcCount = 0; for (int j = 0; j < n - 2; j++) { arcCount += GLPK.glp_get_col_prim(problem, arc[n - 1, j]); } if (Math.Abs(arcCount - 1) > Math.Pow(10, -6)) { row = GLPK.glp_add_rows(problem, 1); //On créé la ligne du simplexe for (int j = 0; j < n - 2; j++) { GLPK.glp_set_row_bnds(problem, row, GLPK.GLP_FX, 1, 1); //On affecte la contrainte d'égalité GLPK.intArray_setitem(ind, j + 1, arc[n - 1, j]); //On considere la variable l'arc allant de j2 à i GLPK.doubleArray_setitem(val, j + 1, 1.0); //On lui associe la valeur 1 dans la matrice du simplexe } GLPK.glp_set_mat_row(problem, row, n - 2, ind, val); } return(cnt); } }
private int generate_rows() { int row; List <Route> subs = getSubroutes(false); if (subs.Count <= 1) { return(0); } else { int n = nodeCount; int cnt = 0; SWIGTYPE_p_int ind = GLPK.new_intArray(n - 1 + 1); SWIGTYPE_p_double val = GLPK.new_doubleArray(n - 1 + 1); for (int i = 0; i < nodeCount; i++) { int arcCount = 0; for (int j = 0; j < nodeCount - 1; j++) { int j2 = j; if (j >= i) { j2++; } if (GLPK.glp_get_col_prim(problem, arc[i, j2]) == 1) { arcCount++; } } if (arcCount != 1) { cnt++; row = GLPK.glp_add_rows(problem, 1); //On créé la ligne du simplexe for (int k = 0; k < n - 1; k++) { int k2 = k; //Exclusion de l'arc i->i if (k >= i) { k2++; } GLPK.glp_set_row_bnds(problem, row, GLPK.GLP_FX, 1, 1); //On affecte la contrainte d'égalité GLPK.intArray_setitem(ind, k + 1, arc[i, k2]); //On considere la variable l'arc allant de i à j2 GLPK.doubleArray_setitem(val, k + 1, 1.0); //On lui associe la valeur 1 dans la matrice du simplexe } GLPK.glp_set_mat_row(problem, row, n - 1, ind, val); //On ajoute la ligne au problème } } for (int i = 0; i < nodeCount; i++) { cnt++; int arcCount = 0; for (int j = 0; j < nodeCount - 1; j++) { int j2 = j; if (j >= i) { j2++; } if (GLPK.glp_get_col_prim(problem, arc[j2, i]) == 1) { arcCount++; } } if (arcCount != 1) { row = GLPK.glp_add_rows(problem, 1); //On créé la ligne du simplexe for (int k = 0; k < n - 1; k++) { int k2 = k; //Exclusion de l'arc i->i if (k >= i) { k2++; } GLPK.glp_set_row_bnds(problem, row, GLPK.GLP_FX, 1, 1); //On affecte la contrainte d'égalité GLPK.intArray_setitem(ind, k + 1, arc[k2, i]); //On considere la variable l'arc allant de i à j2 GLPK.doubleArray_setitem(val, k + 1, 1.0); //On lui associe la valeur 1 dans la matrice du simplexe } GLPK.glp_set_mat_row(problem, row, n - 1, ind, val); //On ajoute la ligne au problème } } GLPK.delete_intArray(ind); GLPK.delete_doubleArray(val); //logger.log(cnt + " violated constraints were generated", Message.Level.Normal); //Console.WriteLine(cnt + " violated constraints were generated"); return(cnt); } }