def solve_lp(graph): points = range(graph.n) lines = graph.lines gamma_lp = set_up_model("connected_components_lp_2d") connected_components = graph.connected_components len_ccs = len(connected_components) edges = list(graph.edges.iter_subset(points)) x = {} for (p, q) in edges: x[p, q] = gamma_lp.addVar(name='edge|%s - %s|' % (p, q)) t = gamma_lp.addVar(obj=1.0) gamma_lp.modelSense = grb.GRB.MINIMIZE gamma_lp.update() # correct number of edges gamma_lp.addConstr(quicksum(x[i, j] for (i, j) in edges) == (len_ccs - 1)) # crossing number range: #gamma_lp.addConstr(0 <= t <= math.sqrt(graph.n)) # crossing constraints for line in lines: s = quicksum(x[p, q] for (p, q) in edges if has_crossing(line, graph.get_line_segment(p, q))) if s != 0.0: gamma_lp.addConstr( s <= t) # connectivity constraint for cc1 in connected_components: gamma_lp.addConstr(quicksum(x[p, q] for (p, q) in edges if p < q and p in cc1 and q not in cc1) + quicksum(x[q, p] for (q, p) in edges if p > q and p in cc1 and q not in cc1) >= 1.) gamma_lp.optimize() if gamma_lp.status == grb.GRB.status.OPTIMAL: add_best_edge(graph, x) return else: format_string = 'Vars:\n' for var in gamma_lp.getVars(): format_string += "%s\n" % var print "number of lines = %s" % len(graph.lines) print '%s\nlp model=%s' % (format_string, gamma_lp) import spanningtree.plotting spanningtree.plotting.plot(graph) raise StandardError('Model infeasible')
def solve_lp_and_round(graph, points): ''' creates a Gurobi model for Sariel LP formulation and round it deterministically return the selection of edges that are in the fractional solution ''' lines = graph.lines gamma_lp = set_up_model("sariels_lp_2d") n = len(points) edges = list(graph.edges.iter_subset(points)) x = {} for (p, q) in edges: x[p, q] = gamma_lp.addVar(obj=graph.euclidean_distance(p, q), name='edge|%s - %s|' % (p, q)) t = gamma_lp.addVar(obj=1.0) gamma_lp.modelSense = grb.GRB.MINIMIZE gamma_lp.update() # crossing number range: gamma_lp.addConstr(0 <= t <= math.sqrt(n)) # crossing constraints for line in lines: s = quicksum(x[p, q] for (p, q) in edges if has_crossing(line, graph.get_line_segment(p, q))) if s != 0.0: gamma_lp.addConstr( s <= t) # connectivity constraint for p in points: gamma_lp.addConstr( quicksum(x[p, q] for q in points if p < q) + quicksum(x[q, p] for q in points if p > q) >= 1) gamma_lp.optimize() if gamma_lp.status == grb.GRB.status.OPTIMAL: round_solution = [] for (p, q) in edges: val = x[p, q].X sample = random.random() if sample <= val: graph.solution.update(p, q, True) round_solution.append((p, q)) return round_solution
def create_lp(graph): ''' create a gurobi model containing LP formulation like that in the Fekete paper ''' lambda_lp = set_up_model("fekete_lp_2d") #lambda_lp.setParam('Cuts', 3) n = graph.n edges = graph.edges for (p, q) in edges: x[p, q] = lambda_lp.addVar(name='edge|%s - %s|' % (p, q)) t = lambda_lp.addVar(obj=1.0) lambda_lp.modelSense = grb.GRB.MINIMIZE lambda_lp.update() # correct number of edges lambda_lp.addConstr(quicksum(x[i, j] for (i, j) in edges) == (n - 1)) # subsets = nonempty_subsets(n) # # connectivity constraints # for subset in subsets: # lambda_lp.addConstr(quicksum(x[i,j] for (i,j) in cut(subset, edges)) # >= 1) # connectivity constraint connected_components = graph.connected_components for cc1 in connected_components: lambda_lp.addConstr(quicksum(x[p, q] for (p, q) in edges if p < q and p in cc1 and q not in cc1) + quicksum(x[q, p] for (q, p) in edges if p > q and p in cc1 and q not in cc1) >= 1.) lines = graph.lines # bound crossing number for line in lines: s = quicksum(x[p, q] for (p, q) in edges if crossing.has_crossing(line, graph.get_line_segment(p, q))) if s != 0.0: lambda_lp.addConstr(s <= t) return lambda_lp