public static double MIP_arc_based(int SAA_m, int SAA_type, int sample_size) { int trial_limit = sample_size; System.Console.WriteLine("Constructing the MIP with Gurobi..."); double solution = -1; try { GRBEnv env = new GRBEnv("mip1.log"); GRBModel model = new GRBModel(env); //model.Parameters.Presolve = 1; GRBVar[] y_j = new GRBVar[E]; GRBVar[,] x_ir = new GRBVar[N, sample_size]; System.Console.WriteLine("Creating y_i (edges)"); for (int i = 0; i < E; i++) { y_j[i] = model.AddVar(0.0, 1.0, 0, GRB.BINARY, "y_" + node_index[unique_arcs[i].Key.Head] + "_" + node_index[unique_arcs[i].Key.Tail]); } System.Console.WriteLine("Creating x_ir"); for (int i = 0; i < N; i++) { for (int r = 0; r < sample_size; r++) { x_ir[i, r] = model.AddVar(0.0, 1.0, 1.0, GRB.CONTINUOUS, "x_" + i + "_" + r); } } model.ModelSense = GRB.MINIMIZE; //---------------------------------------------------------- //--------------- create the constraints int counter = 0; GRBLinExpr temp_exp2; temp_exp2 = 0.0; System.Console.WriteLine("Starting the constraints... Total : " + (trial_limit * N + 1) + " constraints"); // exactly k initial active users for (int i = 0; i < E; i++) { temp_exp2.AddTerm(1.0, y_j[i]); } model.AddConstr(temp_exp2 == K, "constraint_y"); temp_exp2 = 0.0; //--- influence constraints x_i_r <= Sum_j (y_j) j in all accessing nodes to i (total of N.R constraints) //string[] neigh_arr; GRBLinExpr temp_exp; int j = 0; temp_exp = 0.0; int counter2 = 0; ReadData temp_arc = new ReadData(); for (int r = 0; r < trial_limit; r++) { for (int i = 0; i < N; i++) { //if (SAA_tree_list[r][i].Count > 0) //if (x_exist[r, i] == true) { //x_ir[i, r] = model.AddVar(0.0, 1.0, 1.0, GRB.CONTINUOUS, "x_" + i + "_" + r); temp_exp.AddTerm(1.0, x_ir[i, r]); //if (SAA_tree_list[r][i].Count <= N) { foreach (UInt16 node in SAA_pred_list[r][i]) //my predecessors can activate me { var x = unique_arcs.FindIndex(a => a.Key.Head == node_set[(int)node] && a.Key.Tail == node_set[i]); //int arcID=unique_arcs.IndexOf() temp_exp2.AddTerm(-1, x_ir[(int)node, r]); temp_exp2.AddTerm(1, y_j[x]); model.AddConstr(temp_exp + temp_exp2 >= 0, "constraint_2" + (counter + 1)); temp_exp2 = 0.0; counter++; } } } //end of if for null neighbourhood temp_exp = 0.0; } //end of for loop for nodes } //end of for loop for sample size R for (int r = 0; r < trial_limit; r++) { for (int i = 0; i < I; i++) { temp_exp.AddTerm(1.0, x_ir[(int)initial_infected[i], r]); model.AddConstr(temp_exp >= 1, "constraint_3" + (counter + 1)); temp_exp = 0.0; } } //no need for this in edge blocking //for (int i = 0; i < I; i++) //{ // temp_exp.AddTerm(1.0, y_j[(int)initial_infected[i]]); // model.AddConstr(temp_exp == 0, "constraint_3" + (counter + 1)); // temp_exp = 0.0; //} model.Write("model.lp"); //model.Write("modelGRB2" + SAA_m + ".mps"); //model.Write("modelGRB2" + SAA_m + ".lp"); GRBModel p = model.Presolve(); p.Write("presolve.lp"); model.Optimize(); if (model.Status == GRB.Status.OPTIMAL) { Console.WriteLine("Obj: " + model.Get(GRB.DoubleAttr.ObjVal)); solution = model.Get(GRB.DoubleAttr.ObjVal); List <UInt16> SAA_sample_result = new List <UInt16>(K); int isfractional = 0; result_set = new List <ushort>(); for (int jj = 0; jj < y_j.Count(); ++jj) { if (y_j[jj].X > 0.001) { //result_set.Add(node_set[jj]); result_set.Add(node_set[jj]); SAA_sample_result.Add((UInt16)jj); System.Console.WriteLine(y_j[jj].VarName + "=" + y_j[jj].X); if (y_j[jj].X < 0.9) { System.Console.WriteLine("Fractional value found"); System.Console.ReadKey(); isfractional = 1; } } } if (isfractional == 1) { System.Console.WriteLine("To conitnue click..."); System.Console.ReadKey(); } SAA_list.Add(SAA_sample_result); } else { Console.WriteLine("No solution"); solution = 0; } // Dispose of model and env model.Dispose(); env.Dispose(); } catch (GRBException e) { Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message); } return(solution); }
public static Graph RunSolver(Graph graph) { GRBEnv env = new GRBEnv(); env.Set(GRB.IntParam.OutputFlag, 0); env.Set(GRB.IntParam.LogToConsole, 0); env.Set(GRB.IntParam.Presolve, 2); env.Set(GRB.DoubleParam.Heuristics, 0.0); GRBModel model = new GRBModel(env); GRBVar[] variables = new GRBVar[graph.NumberOfEdges]; model.SetCallback(new LPSolverCallback()); Dictionary<Edge, GRBVar> edgeVars = new Dictionary<Edge, GRBVar>(); // Add variables to the LP model for (int i = 0; i < graph.NumberOfEdges; i++) { variables[i] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "x_" + i); edgeVars.Add(graph.Edges[i], variables[i]); } model.Update(); // Add constraints to the LP model Console.Write("\rRunning LP. Creating constraints...\r"); //var nonTerminals = graph.Vertices.Except(graph.Terminals).ToList(); ulong conNr = 0; //var terminalCombinations = new List<List<Vertex>>(); // Assume, without loss of generality, that Terminals[0] is the root, and thus is always included int rootNr = 1; foreach (var rootTerminal in graph.Terminals) //var rootTerminal = graph.Terminals[0]; { Console.Write("\rRunning LP. Creating constraints... {0}/{1}\r", rootNr, graph.Terminals.Count); foreach (var combination in GetBFS(graph, rootTerminal)) { var nodes = combination.ToList(); //new HashSet<Vertex>(combination); if (nodes.Count == graph.NumberOfVertices || graph.Terminals.All(nodes.Contains)) continue; //Debug.WriteLine("Combination: {0}", string.Join(" ", nodes)); //for (int i = 1; i <= nodes.Count; i++) { var edges = nodes//.Take(i) .SelectMany(graph.GetEdgesForVertex) .Distinct() .Where(x => x.WhereOne(y => !nodes.Contains(y))); GRBLinExpr expression = 0; foreach (var edge in edges) expression.AddTerm(1, edgeVars[edge]); model.AddConstr(expression >= 1.0, "subset_" + conNr); conNr++; if (conNr % 100000 == 0) { //model = model.Presolve(); //Pre-solve the model every 1000 constraints. int constrBefore = model.GetConstrs().Length, varsBefore = model.GetVars().Length; Debug.WriteLine("Presolve called."); var presolved = model.Presolve(); Debug.WriteLine("Model has {0} constraints, {1} variables. Presolve has {2} constraints, {3} variables", constrBefore, varsBefore, presolved.GetConstrs().Length, presolved.GetVars().Length); } } } //Debug.WriteLine(" "); //Debug.WriteLine(" "); rootNr++; } //terminalCombinations.Add(new List<Vertex>(new[] { graph.Terminals[0] })); //for (int j = 1; j < graph.Terminals.Count - 1; j++) // terminalCombinations.AddRange(new Combinations<Vertex>(graph.Terminals.Skip(1), j).Select(combination => combination.Union(new[] { graph.Terminals[0] }).ToList())); //long nonTerminalSetsDone = 0; //long nonTerminalSets = 0; //for (int i = 0; i <= nonTerminals.Count; i++) // nonTerminalSets += Combinations<Vertex>.NumberOfCombinations(nonTerminals.Count, i); //for (int i = 0; i <= nonTerminals.Count; i++) //{ // foreach (var nonTerminalSet in new Combinations<Vertex>(nonTerminals, i)) // { // foreach (var nodes in (from a in terminalCombinations // select new HashSet<Vertex>(a.Union(nonTerminalSet)))) // { // var edges = nodes.SelectMany(graph.GetEdgesForVertex) // .Distinct() // .Where(x => x.WhereOne(y => !nodes.Contains(y))); // GRBLinExpr expression = 0; // foreach (var edge in edges) // expression.AddTerm(1, edgeVars[edge]); // model.AddConstr(expression >= 1.0, "subset_" + conNr); // conNr++; // } // nonTerminalSetsDone++; // if (nonTerminalSetsDone % 100 == 0) // Console.Write("\rRunning LP. Creating constraints... {0}/{1} ({2:0.000}%)\r", nonTerminalSetsDone, nonTerminalSets, nonTerminalSetsDone * 100.0 / nonTerminalSets); // } //} // Solve the LP model Console.Write("\rRunning LP. Creating objective & updating... \r"); GRBLinExpr objective = new GRBLinExpr(); for (int i = 0; i < graph.NumberOfEdges; i++) objective.AddTerm(graph.Edges[i].Cost, variables[i]); model.SetObjective(objective, GRB.MINIMIZE); Console.Write("\rRunning LP. Tuning... \r"); model.Tune(); Debug.WriteLine("Presolve called."); model.Presolve(); Console.Write("\rRunning LP. Solving... \r"); Debug.WriteLine("Optimize called."); model.Optimize(); Graph solution = graph.Clone(); HashSet<Edge> includedEdges = new HashSet<Edge>(); for (int i = 0; i < solution.NumberOfEdges; i++) { var value = variables[i].Get(GRB.DoubleAttr.X); if (value == 1) includedEdges.Add(solution.Edges[i]); } foreach (var edge in solution.Edges.ToList()) if (!includedEdges.Contains(edge)) solution.RemoveEdge(edge); Console.Write("\r \r"); return solution; }