Esempio n. 1
1
def get_mapping(PG, VG):
    vnodes, vhosts = multidict({n: len(VG.node[n]['host_ports']) for n in VG.nodes()})
    pnodes, phosts = multidict({n: len(PG.node[n]['host_ports']) for n in PG.nodes()})
    parcs, pcapacity = multidict({(m, n): PG.edge[m][n]['weight'] for (m, n) in PG.edges()})
    parcs = tuplelist(parcs)

    varcs, vcapacity = multidict({(m, n): VG.edge[m][n]['weight'] for (m, n) in VG.edges()})
    varcs = tuplelist(varcs)

    m = Model('mapping')

    # Create variables
    node_mapping = {}
    for i in vnodes:
        for j in pnodes:
            node_mapping[i, j] = m.addVar(vtype=GRB.BINARY, name="x_%s_%s" % (i, j))


    edge_mapping = {}
    for i in vnodes:
        for p in VG.neighbors(i):
            for (j, q) in parcs:
                edge_mapping[i, p, j, q] = m.addVar(vtype=GRB.BINARY, name="y_%s_%s_%s_%s" % (i, p, j, q))

    m.update()

    # Arc capacity constraints
    for i in vnodes:
        m.addConstr(quicksum(node_mapping[i, j] for j in pnodes) == 1, 'node_%s' % i)

    for i in vnodes:
        for p in VG.neighbors(i):
            for (j, q) in parcs:
                m.addConstr(edge_mapping[i, p, j, q] <= ( node_mapping[i, j] + node_mapping[p, q] )/2, 'edge_%s_%s_%s_%s' % (i, p, j, q))

    for (j, q) in parcs:
        m.addConstr(quicksum(edge_mapping[i, p, j, q] + edge_mapping[p, i, j, q]for (i, p) in varcs) <= pcapacity[j, q], 'pcap_%s_%s' % (j, q))

    for (i, p) in varcs:
        m.addConstr(quicksum(edge_mapping[i, p, j, q] + edge_mapping[p, i, j, q] for (j, q) in parcs) >= vcapacity[i, p], 'vcap_%s_%s' % (i, p))

    for j in pnodes:
        m.addConstr(quicksum(node_mapping[i, j] * vhosts[i] for i in vnodes) <= phosts[j], 'phosts_%s' % j)
    for i in vnodes:
        m.addConstr(quicksum(node_mapping[i, j] * phosts[j] for j in pnodes) >= vhosts[i], 'vhosts_%s' % i)
    # Compute optimal solution
    m.optimize()

    # Print solution
    if m.status == GRB.status.OPTIMAL:
        mapping = {}
        mapping2 = {}
        portlist = {}

        for n in PG:
            if 'host_ports' in PG.node[n]:
                portlist[n] = PG.node[n]['host_ports']

        solution = m.getAttr('x', edge_mapping)
        for h in solution:
            if solution[h] == 1.0:
                vid1, vid2, pid1, pid2 = h
                vport1, vport2 = list(VG.node[vid1]['links'][vid2])[0]

                if (vid1, pid1) not in mapping:
                    mapping[(vid1, pid1)] =[vid1, pid1]
                if (pid1, vid1) not in mapping2:
                    mapping2[(pid1, vid1)] =[pid1, vid1]
                (pport1, pport2) = PG.node[pid1]['links'][pid2].pop()
                # print vid1, vid2, pid1, pid2, pport1, pport2
                if pid1 != pid2:
                    PG.node[pid2]['links'][pid1].remove((pport2, pport1))
                mapping[(vid1, pid1)].append(vport1)
                mapping[(vid1, pid1)].append(pport1)
                mapping2[(pid1, vid1)].append(pport1)
                mapping2[(pid1, vid1)].append(vport1)

                if (vid2, pid2) not in mapping:
                    mapping[(vid2, pid2)] =[vid2, pid2]
                if (pid2, vid2) not in mapping2:
                    mapping2[(pid2, vid2)] =[pid2, vid2]
                mapping[(vid2, pid2)].append(vport2)
                mapping[(vid2, pid2)].append(pport2)
                mapping2[(pid2, vid2)].append(pport2)
                mapping2[(pid2, vid2)].append(vport2)

        solution2 = m.getAttr('x', node_mapping)
        print [h for h in solution2 if solution2[h] == 1.0]
        for h in solution2:
            if solution2[h] == 1.0:
                vid, pid = h
                if len(VG.node[vid]['host_ports']) == 0:
                    continue

                for vport in VG.node[vid]['host_ports']:
                    pport = portlist[pid].pop()
                    mapping[(vid, pid)].append(vport)
                    mapping[(vid, pid)].append(pport)
                    mapping2[(pid, vid)].append(pport)
                    mapping2[(pid, vid)].append(vport)

    return mapping, mapping2


def main():
    args = parse_args()

    VG = gen_graph(args.target_topology)
    if not networkx.is_connected(VG):
        print 'Target topology is not connected'
        sys.exit(1)

    PG = gen_graph(args.host_topology, int_idx=True)

    mapping, mapping2 = get_mapping(PG, VG)

    f = open(args.output, "w")
    print >>f, "P2Vmap"
    for id in mapping2:
        for id2 in mapping2[id]:
            print >>f, id2,
        print>>f, "65535 65535"
    print >>f, "V2Pmap"
    for id in mapping:
        for id2 in mapping[id]:
            print >>f, id2,
        print>>f, "65535 65535"


if __name__ == "__main__":
    main()
Esempio n. 2
0
def calculate_min_flow(graph, objective, supply, num_goods):
    result = {}
    try:
        model = gp.Model("Network optimization")
        model.setParam(GRB.Param.OutputFlag, False)
        flow_indices = gp.tuplelist(
            (i, j) for i in range(graph.num_edges) for j in range(num_goods))
        pos_flow = model.addVars(flow_indices, name='pf')
        neg_flow = model.addVars(flow_indices, name='nf')
        mu_indices = gp.tuplelist(range(graph.num_edges))
        pos_mu = model.addVars(mu_indices, name='p_mu')
        neg_mu = model.addVars(mu_indices, name='n_mu')
        subdiff = objective.subdifferential0()
        #Add mu >= f(x)
        for i in range(graph.num_edges):
            (v, w) = graph.edges[i]
            length = graph.edge_lengths[v][w]
            for a in subdiff:
                pos_eq = 0
                neg_eq = 0
                for j in range(num_goods):
                    pos_eq += length * a[j] * pos_flow[i, j]
                    neg_eq += length * a[j] * neg_flow[i, j]
                model.addConstr(pos_mu[i] >= pos_eq)
                model.addConstr(neg_mu[i] >= neg_eq)

        #Add divergence constraints
        div_constraints = [[] for _ in range(graph.num_vertices)]
        for k in range(graph.num_vertices):
            for j in range(num_goods):
                eq = 0
                for i in graph.vertex_to_edges[k]:
                    edge = graph.edges[i]
                    if k == edge[0]:
                        eq += pos_flow[i, j] - neg_flow[i, j]
                    else:
                        eq += neg_flow[i, j] - pos_flow[i, j]
                div_constraints[k].append(model.addConstr(eq == supply[k][j]))

        #Define objective
        eq = 0
        for i in range(graph.num_edges):
            eq += pos_mu[i] + neg_mu[i]
        model.setObjective(eq, GRB.MINIMIZE)
        model.optimize()

        result['flow'] = np.array(
            [[pos_flow[i, j].x - neg_flow[i, j].x for j in range(num_goods)]
             for i in range(graph.num_edges)])
        result['phi'] = np.array(
            [[div_constraints[k][j].pi for j in range(num_goods)]
             for k in range(graph.num_vertices)])
        result['value'] = model.ObjVal
        return result
    except gp.GurobiError as e:
        print('Error code ' + str(e.errno) + ': ' + str(e))
    except AttributeError:
        print('Attribute error (WTF??)')
Esempio n. 3
0
    def assignFromRTVGraph(self, rtvGraph):
        m = gp.Model("rtv-assignment")
        # m.setParam(GRB.Param.OutputFlag, 0)
        m.setParam(GRB.Param.LogToConsole, 0)
        m.setParam(GRB.Param.LogFile, "output/gurobi/log.txt")

        e_ij = gp.tuplelist([(edge.source, edge.target) for edge in rtvGraph.es.select(etype="veh_trip")])
        x_k = gp.tuplelist([(v.index) for v in rtvGraph.vs.select(vtype="request")])

        req_trips = gp.tupledict({
            req.index: [rtvGraph.es[edge].target for edge in rtvGraph.incident(req, ig.ALL)]
            for req in rtvGraph.vs.select(vtype="request")})

        cost_ij = gp.tupledict({(edge.source, edge.target): edge["cost"] for edge in rtvGraph.es.select(etype="veh_trip")})
        cost_ko = 1e6

        trips = gp.tuplelist([(v.index) for v in rtvGraph.vs.select(vtype="trip")])
        vehs = gp.tuplelist([(v.index) for v in rtvGraph.vs.select(vtype="vehicle")])
        reqs = gp.tuplelist([(v.index) for v in rtvGraph.vs.select(vtype="request")])

        veh_trip_flow = m.addVars(e_ij, vtype=GRB.BINARY, name="e")
        req_ignored = m.addVars(x_k, vtype=GRB.BINARY, name="x")

        m.setObjective(veh_trip_flow.prod(cost_ij) + cost_ko * req_ignored.sum(), GRB.MINIMIZE)
        m.addConstrs((veh_trip_flow.sum(i, "*") <= 1 for i in vehs), "one_veh_per_trip")
        for k in reqs:
            m.addConstr(sum([veh_trip_flow.sum("*", j) for j in req_trips[k]]) + req_ignored[k] == 1,
                "one_veh_max_per_req[{}]".format(k))

        m.optimize()

        if m.status == GRB.OPTIMAL:
            veh_trips = m.getAttr('x', veh_trip_flow)
            veh_routes = dict()
            for edge in rtvGraph.es.select(etype="veh_trip"):
                veh = rtvGraph.vs[edge.source]
                vehID = veh.index
                tripID = edge.target
                if veh_trips[vehID, tripID] > 0:
                    veh_routes[veh["vid"]] = edge["route"]

            ignored_reqs = m.getAttr('x', req_ignored)
            rejected_reqs = set()
            for req in reqs:
                if ignored_reqs[req] > 0:
                    rejected_reqs.add(rtvGraph.vs[req]["rid"])
        else:
            return None, None

        return veh_routes, rejected_reqs
Esempio n. 4
0
 def __init__(self, iter_of_iters):
     """
     Construct a multi-index Slicer object
     :param iter_of_iters An iterable of iterables. Usually a list of lists, or a list
     of tuples. Each inner iterable must be the same size. The "*" string has a special
     flag meaning and cannot be a member of any of the inner iterables.
     """
     verify(hasattr(iter_of_iters, "__iter__"),
            "need an iterator of iterators")
     copied = tuple(iter_of_iters)
     verify(all(hasattr(_, "__iter__") for _ in copied),
            "need iterator of iterators")
     self._indicies = tuple(map(tuple, copied))
     if self._indicies:
         verify(
             min(map(len, self._indicies)) == max(map(len, self._indicies)),
             "each inner iterator needs to have the same number of elements"
         )
         verify(not any("*" in _ for _ in self._indicies),
                "The '*' character cannot itself be used as an index")
     self._gu = None
     if gu:
         self._gu = gu.tuplelist(self._indicies)
         self._indicies = None
     self.clear()
Esempio n. 5
0
def build(inst, patterns=None, bound=None, relaxed=False):
    threshold, lvec, bvec = inst
    m = len(lvec)
    assert m == len(bvec)
    is_active, arcs = create_arcflow_arcs(inst)
    arcs = gp.tuplelist(arcs)

    model = gp.Model()
    x = model.addVars(
        arcs,
        name='x',
        vtype=gp.GRB.CONTINUOUS if relaxed else gp.GRB.INTEGER,
        ub=[gp.GRB.INFINITY if arc[2] == -1 else bvec[arc[2]] for arc in arcs])

    # set start values
    if patterns is not None:
        for arc, count in create_variable_start(inst, patterns).items():
            x[arc].start = count

    for j in is_active:
        if j == 0 or j == threshold:
            continue
        model.addConstr(x.sum(j, '*', '*') == x.sum('*', j, '*'))

    for i in range(m):
        model.addConstr(x.sum('*', '*', i) <= bvec[i])

    obj = x.sum(0, '*', '*')
    model.setObjective(obj, sense=gp.GRB.MAXIMIZE)

    if bound is not None:
        model.addConstr(obj <= bound)
    return model
    def _add_initial_heading(self, times, initial_heading):
        if get_array_greater_zero(initial_heading):
            # create degrees for all initial headings
            degrees = grb.tupledict()
            arcs = grb.tuplelist()
            for index in range(len(self.graph.vertices)):
                v_a = np.array(self.graph.vertices[index])
                ad_indexes = [
                    j for j in range(len(self.graph.vertices))
                    if self.graph.ad_matrix[index, j] > 0
                ]
                vert_arr = np.array(
                    [self.graph.vertices[i] for i in ad_indexes])
                l = len(vert_arr)
                degrees = np.array([
                    get_angle(v_a, vert, initial_heading[index])
                    for vert in vert_arr
                ])
                tuple_list = [((index, ad_indexes[i]), degrees[i])
                              for i in range(l)]
                # Correct entries with NaN
                for i in range(len(tuple_list)):
                    if tuple_list[i] == np.NaN:
                        tuple_list[i][-1] = 0

                arcs_i, multidict_i = grb.multidict(
                    tuple_list) if tuple_list else (None, None)
                degrees.update(multidict_i)
                arcs.extend(arcs_i)

            for arc in arcs:
                self.model.addConstr(times[arc] >= degrees[arc],
                                     name="degree_constraint_init")
Esempio n. 7
0
def exact_gurobi(tsp):

	global n
	points, n = tsp.points, tsp.n

	# Dictionary of Euclidean distance between each pair of points
	dist = {(i,j) : math.sqrt(sum((points[i][k]-points[j][k])**2 for k in range(2))) for i in range(n) for j in range(i)}

	with stdout_redirected(), stderr_redirected():

		m = gbp.Model()

		# Create variables
		vars = m.addVars(dist.keys(), obj=dist, vtype=gbp.GRB.BINARY, name='e')
		for i,j in vars.keys():
			vars[j,i] = vars[i,j] # edge in opposite direction

		# Add degree-2 constraint
		m.addConstrs(vars.sum(i,'*') == 2 for i in range(n))

		# Optimize model
		m._vars = vars
		m.Params.lazyConstraints = 1
		m.optimize(subtourelim)

		vals = m.getAttr('x', vars)
		selected = gbp.tuplelist((i,j) for i,j in vals.keys() if vals[i,j] > 0.5)

	tour = subtour(selected)
	assert len(tour) == n

	tour.append(tour[0])
	tour_len = tsp.tour_length(tour)

	return tour, tour_len
Esempio n. 8
0
    def createWeightReductionLPWithSetGraph(self,projective,setGraphEdges):
        model = gp.Model(self.modelName)
        self.edges = gp.tuplelist(self.g.graph.edges())
        self.nodes = self.g.graph.nodes()

        # add the new variables:
        # new weights
        w = {}
        # incidence vector for the new graph
        y = {}
        # diff edges counters
        d = {}
        
        # declare varuables
        for (u,v) in self.edges:
            w[u,v]      = model.addVar(lb=-1e21,vtype=gp.GRB.CONTINUOUS, name='w_%s_%s' % (u,v))
            y[((u,v),)] = model.addVar(vtype=gp.GRB.BINARY,     name='y_%s_%s' % (u,v))
            d[u,v]      = model.addVar(vtype=gp.GRB.BINARY,     name='d_%s_%s' % (u,v))
            
        
        model.update()
        
        # incoming edges constraints - every node except for 0 has one incoming edge
        self.addIncomingEdgesConstrs(self.nodes,self.edges,model,y,'Y')
                
        if projective:
            #  non projectivie constrs
            self.addProjectiveConstrs(self.nodes,model,y,'Y')
        else:
            # non proj constrs and vars
            self.newLPFlowVars = self.addNonProjectiveConstrs(self.nodes,self.edges,y,model,'Y')
        
        # diff edges constraints
        for (u,v) in self.edges:
            isEdge = 0;
            if (setGraphEdges.has_key((u,v))):
                isEdge =1;
                
            model.addConstr(d[u,v] + y[((u,v),)], gp.GRB.GREATER_EQUAL,isEdge,'d_z_y_%s_%s' % (u,v))
            model.addConstr(d[u,v] + isEdge, gp.GRB.GREATER_EQUAL,y[((u,v),)],'d_y_z_%s_%s' % (u,v))
        
        # lower bounds on w constraints
        for feature in self.g.allWeights:
            allSubsets = allNonEmptySubsets(feature)
            allW = 0
            for f in allSubsets:
                if self.g.allWeights.has_key(f):
                    allW += self.g.allWeights[f]
                else:
                    print('Oh no! subset is %s, expected to find %s' % (feature,f))
            operator = gp.GRB.GREATER_EQUAL;
            if (allW < 0):
                operator = gp.GRB.LESS_EQUAL
            # print(self.g.graph.edges())
            model.addConstr(gp.quicksum(w[u,v] for (u,v) in feature),operator,allW,'subset_%s' % '_'.join([str(u) + '_' + str(v) for (u,v) in feature])) 
                 
        self.WeightReductionLPModelWithSetGraph = model
        self.newWeightsVars = w
        self.newLPVars = y
        self.diffEdges = d
 def subtourelim(model, where):
     global var_x, lazy_glob, callbacks_glob, houses_per_period
     n = houses_per_period
     if where == GRB.Callback.MIPSOL:
         vals = model.cbGetSolution(var_x)
         selected = tuplelist()
         for i in range(houses_per_period):
             for j in range(houses_per_period):
                 if vals[i, j, 0, 0] > 0.5 :
                     selected.append((i,j))
         tour = subtour(selected)
         if len(tour) < n:
             combinationF = list(combinations(tour, 2))
             if len(combinationF) == 1:
                 expr = len(tour) - 1
                 model.cbLazy(var_x[combinationF[0][1], combinationF[0][0], 0, 0] + var_x[combinationF[0][0], combinationF[0][1], 0, 0] <= expr)
                 lazy_glob += 1
             else:
                 expr = len(tour) - 1
                 sumarapida = 0 
                 for i in tour:
                     for j in tour:
                         sumarapida += var_x[i, j, 0, 0] + var_x[j, i, 0, 0]
                 model.cbLazy(sumarapida <= expr)
                 lazy_glob += 1
         callbacks_glob += 1
Esempio n. 10
0
 def createLP(self,projective):
     
     model = gp.Model(self.modelName)
     
     edges = gp.tuplelist(self.g.graph.edges())
     nodes = self.g.graph.nodes()
     
     # Create variables and objective
     z = {}
     for feature in self.g.allWeights:
         z[feature] = model.addVar(vtype=gp.GRB.BINARY, name='z_%s' % '_'.join([str(u) + '_' + str(v) for (u,v) in feature]))
     model.update()
     
     # incoming edges constraints - every node except for 0 has one incoming edge
     self.addIncomingEdgesConstrs(nodes,edges,model,z,'Z')        
     
     if (projective):
         # projectivity + no circles constraints
         self.addProjectiveConstrs(nodes,model,z,'Z')
     else:
         # non proj constrs and vars
         self.LPFlowVars = self.addNonProjectiveConstrs(nodes,edges,z,model,'Z')
     
     self.LPModel = model
     self.LPVars = z
     self.edges = edges
     self.nodes = nodes
Esempio n. 11
0
def solveLP(area,coord):
    m=grb.Model('ILP')
    modes=[1,2,3,4]
    allpath=grb.tuplelist()
    cost={}
    for cell1 in area:
        for cell2 in area[cell1]:
            for mode in modes:
                allpath.append((cell1,cell2,mode))
                if(mode==1):
                    cost[(cell1,cell2,mode)]=distance(coord[cell1-1][0],coord[cell2-1][0])
                elif(mode==2):
                    cost[(cell1,cell2,mode)]=distance(coord[cell1-1][0],coord[cell2-1][1])
                elif(mode==3):
                    cost[(cell1,cell2,mode)]=distance(coord[cell1-1][1],coord[cell2-1][0])
                else:
                    cost[(cell1,cell2,mode)]=distance(coord[cell1-1][1],coord[cell2-1][1])
    pathvar=m.addVars(allpath,vtype=grb.GRB.BINARY, name="path") 
    m.setObjective(pathvar.prod(cost), grb.GRB.MINIMIZE)   
    for cell1 in area:
        m.addConstr(
            sum(pathvar.select(cell1,'*',1))+
            sum(pathvar.select(cell1,'*',2))+
            sum(pathvar.select('*',cell1,1))+
            sum(pathvar.select('*',cell1,3))==1,str(cell1)+'a')
        m.addConstr(
            sum(pathvar.select('*',cell1,2))+
            sum(pathvar.select(cell1,'*',3))+
            sum(pathvar.select('*',cell1,4))+
            sum(pathvar.select(cell1,'*',4))==1,str(cell1)+'b')
    m.optimize()
    return (m,pathvar)
Esempio n. 12
0
def subtour_elimination(model, where):
    '''
    Callback que, para uma solução ótima do K-TSP relaxado, verifica se essa
    solução viola restrições de eliminação de subciclo e, se sim, adiciona
    essas restrições ao modelo, que será re-otimizado.

    Args:
        model: o modelo associado a callback.
        where: indica da onde no processo de otimização a callback foi chamada.
    '''

    if where == GRB.Callback.MIPSOL:
        # Analisar cada rota t
        for t in range(model._K):

            # Criar lista de arestas na rota t selecionadas na solução
            x_sol = model.cbGetSolution(model._vars)
            edges_in_tour = gp.tuplelist((i, j)
                                         for i, j, k in model._vars.keys()
                                         if x_sol[i, j, k] > 0.5 and k == t)

            # Encontrar menor ciclo e verificar se viola restrição, i.e., se
            # não percorre todos os vértices, formando um subciclo
            cycle = shortest_cycle(model._n, edges_in_tour)
            if len(cycle) < n:

                # Adicionar restrições de eliminação de subciclo, para cada par
                # de vértices do subciclo encontrado
                model.cbLazy(
                    gp.quicksum(
                        model._vars[i, j, t]
                        for i, j in combinations(cycle, 2)) <= len(cycle) - 1)
Esempio n. 13
0
def update_gurobi_model(model, linksNode):
    # set new best solution
    model._preprocessingSolution['Path_Disutility'] = model._best

    # determine all reachable nodes, as in preprocessing
    feasibleNodes, listOfReachableNodes = get_all_feasible_nodes(
        model._graphInstance.Graph_for_Preprocessing.subgraph(
            model._FeasibleNodes), model._graphOrigin,
        model._graphInstance.Graph_for_Preprocessing_Reverse.subgraph(
            model._FeasibleNodes), model._graphDestination,
        model._preprocessingSolution)

    # remove all edge variables, who contain a node, that is no part of the reduced Graph
    node_remain = gb.tuplelist()
    remove_link = []
    for i, j, m in linksNode:
        var_name = 'y[' + str(i) + ',' + str(j) + ',' + str(m) + ']'
        if i not in feasibleNodes:
            remove_link.append(var_name)
        else:
            if j not in feasibleNodes:
                remove_link.append(var_name)
            else:
                node_remain.append((i, j, m))

    print('Removed ' + str(len(remove_link)) +
          ' variables based on the new identified feasible solution')

    # remove links
    for link in remove_link:
        model.remove(model.getVarByName(link))

    return node_remain
 def _calculate_degrees(self) -> (grb.tuplelist, grb.tupledict):
     # Calculate degrees
     degrees = grb.tupledict()
     arcs = grb.tuplelist()
     for i in range(len(self.graph.vertices)):
         arcs_i, degrees_i = self._get_angles(i)
         if arcs_i:
             degrees.update(degrees_i)
             arcs.extend(arcs_i)
     return arcs, degrees
Esempio n. 15
0
def subtourelim(model, where):
	if where == gbp.GRB.Callback.MIPSOL:
		# make a list of edges selected in the solution
		vals = model.cbGetSolution(model._vars)
		selected = gbp.tuplelist((i,j) for i,j in model._vars.keys() if vals[i,j] > 0.5)
		# find the shortest cycle in the selected edge list
		tour = subtour(selected)
		if len(tour) < n:
			# add subtour elimination constraint for every pair of cities in tour
			model.cbLazy(gbp.quicksum(model._vars[i,j] for i,j in itertools.combinations(tour, 2)) <= len(tour)-1)
def NormalBackupModelExample(plot_options, num_nodes,p,invstd,mip_gap, time_limit):
    
    #######################################
    #        Generating graphs
    #######################################
    
    #Generates a complete indirect graph 
    H = nx.complete_graph(num_nodes)
    # transforms the indirect graph in directed one
    G = H.to_directed()
    
    #Generates a list with all links (edges) in the graph
    links = G.edges()
    #Generates a list with all nodes (vertex) in the graph
    nodes = G.nodes() 
    
    capacity={}
    mean={}
    std={}

    Aux=1
    for s,d in links:
        #generating capacity for each s,d link
        capacity[s,d] = Aux
        #Generate mean for each s,d link based on Bernouilli distribution 
        mean[s,d] = Aux*p
        #Generate std for each s,d link based on Bernouilli distribution 
        std[s,d]=math.sqrt(Aux*p*(1-(Aux*p)))
        if capacity[s,d] > 0:
            G.add_weighted_edges_from([(s,d,capacity[s,d])])
        else:
            G.add_weighted_edges_from([(s,d,capacity[s,d])])
    
    if plot_options == 1:
        pos = plotGraph(G, option=0, position=None)
    
    ################################
    #
    #          optimization
    #
    ################################
    links = tuplelist(links)
    BackupNet = Backup(nodes,links,capacity,mean,std,invstd)
    solution = BackupNet.optimize(mip_gap,time_limit)
    
    #penalizes the links chosen to be backup links
    for i,j in links:
        if solution[i,j] < 0.1:
            G.remove_edge(i, j)
       
    
    if plot_options == 1:
        option=1
        plotGraph(G, option, pos)
Esempio n. 17
0
    def __init__(self, nodes=None, patients=None, mutations=None, interactions=None,
                 node_mutations=None, node_neighbors=None):
        """
        :param nodes: ([str])                   gene nodes
        :param patients: ([str])                patient ids
        :param mutations: ([(str, str)])        node-patient links
        :param interactions: ([(str, str)])     node-node links
        :param node_mutations: ({str: {str,}})  node to patient adjacency list
        :param node_neighbors: ({str: {str,}})  node adjacency list
        :return
        """
        self.nodes = list() if nodes is None else nodes
        self.patients = list() if patients is None else patients
        self.interactions = tuplelist([]) if interactions is None else interactions
        self.mutations = tuplelist([]) if mutations is None else mutations

        # auxiliary data structures
        self.node_mutations = OrderedDict() if node_mutations is None else node_mutations
        self.node_neighbors = OrderedDict() if node_neighbors is None else node_neighbors
        self.weights = dict()
Esempio n. 18
0
def subtourelim(model, where):
    if where == GRB.Callback.MIPSOL:
        vals = model.cbGetSolution(model._vars)
        selected = gp.tuplelist(
            (i, j) for i, j in model._vars.keys() if vals[i, j] > 0.5)
        tour = subtour(selected)
        if len(tour) < n:
            model.cbLazy(
                gp.quicksum(
                    model._vars[i, j]
                    for i, j in combinations(tour, 2)) <= len(tour) - 1)
Esempio n. 19
0
    def permute_mutations(self, seed):
        print "shuffling keys"
        original = copy.deepcopy(self)

        index_dictionary = {n: n for n in self.nodes}
        keys = copy.deepcopy(self.nodes)
        random.seed(seed)
        random.shuffle(keys)
        shuffled_dictionary = dict(zip(keys, index_dictionary.values()))

        self.mutations = tuplelist()
        self.interactions = tuplelist()
        self.node_mutations = OrderedDict()
        self.node_neighbors = OrderedDict()

        for n in original.nodes:
            if n in original.node_mutations:
                for p in original.node_mutations[n]:
                    self.append_mutation(p, shuffled_dictionary[n])
            for u in original.node_neighbors[n]:
                self.append_interaction(shuffled_dictionary[n], shuffled_dictionary[u])
Esempio n. 20
0
 def subtourelim(model, where):
     if (where == grb.GRB.Callback.MIPSOL):
         x_sol = model.cbGetSolution(model._x)
         arcs = grb.tuplelist(
             (i, j) for i, j in model._x.keys() if x_sol[i, j] > 0.9)
         components = getGraphComponents(arcs)
         for component in components:
             if (len(component) < n):
                 model.cbLazy(
                     grb.quicksum(x[i, j] for i in component
                                  for j in component
                                  if i != j) <= len(component) - 1)
Esempio n. 21
0
def subTour_eliminator(model, where):
    if where == GRB.Callback.MIPSOL:                                                # possible solution
        values = model.cbGetSolution(model._vars)
        selected_nodes = guro.tuplelist((i_1, i_2)
                                  for (i_1, i_2) in model._vars.keys()
                                  if values[i_1, i_2] > 0.5)

        sol_tour = get_cycle(selected_nodes)
        all_tours.append(sol_tour)

        if len(sol_tour) < len(locations):
            model.cbLazy(guro.quicksum(model._vars[i_1, i_2]
                                       for (i_1, i_2) in combinations(sol_tour, 2)) <= len(sol_tour)-1)
Esempio n. 22
0
def elimSubTour(model, where):
    if where == gurobipy.GRB.Callback.MIPSOL:
        vals = model.cbGetSolution(model._xVar)
        selectedPairs = gurobipy.tuplelist(
            (i, j) for i, j in vals.keys() if vals[i, j] > 0.5)
        visited, notVisited = findSubTour(selectedPairs)
        # If there is subtour, add constraint: the cut should have at least 2 edges
        if len(notVisited) > 0:
            model.cbLazy(
                gurobipy.quicksum(model._xVar[i, j] for j in notVisited
                                  for i in visited if i < j) +
                gurobipy.quicksum(model._xVar[j, i] for j in notVisited
                                  for i in visited if i > j) >= 2)
Esempio n. 23
0
    def tsp_compute(dist_matrix: np.ndarray):
        # Dictionary of Euclidean distance between each pair of points
        n = len(dist_matrix)
        dist = {(i, j): dist_matrix[i, j]
                for i in range(dist_matrix.shape[0]) for j in range(i)}

        m = grb.Model()

        # Create variables

        vars = m.addVars(dist.keys(), obj=dist, vtype=grb.GRB.BINARY, name="e")
        for i, j in vars.keys():
            vars[j, i] = vars[i, j]  # edge in opposite direction

        # You could use Python looping constructs and m.addVar() to create
        # these decision variables instead.  The following would be equivalent
        # to the preceding m.addVars() call...
        #
        # vars = tupledict()
        # for i,j in dist.keys():
        #   vars[i,j] = m.addVar(obj=dist[i,j], vtype=GRB.BINARY,
        #                        name='e[%d,%d]'%(i,j))

        # Add degree-2 constraint

        m.addConstrs(vars.sum(i, "*") == 2 for i in range(n))

        # Using Python looping constructs, the preceding would be...
        #
        # for i in range(n):
        #   m.addConstr(sum(vars[i,j] for j in range(n)) == 2)

        # Optimize model

        m._vars = vars
        m.Params.lazyConstraints = 1
        m.optimize(subtourelim)

        vals = m.getAttr("x", vars)
        selected = grb.tuplelist(
            (i, j) for i, j in vals.keys() if vals[i, j] > 0.5)

        tour = subtour(selected)
        assert len(tour) == n

        print("")
        print("Optimal tour: %s" % str(tour))
        print("Optimal cost: %g" % m.objVal)
        print("")
        return tour
Esempio n. 24
0
 def __init__(self, *initial_data, **kwargs):
     self.syllabus_ID = None
     self.name = None
     self.organization_ID = None
     self.device_type_ID = None
     self.precedence = None
     self.event_arcs = tuplelist(
     )  # Tuplelist of arcs (parent event id, child event id)
     self._ancestors = {}
     self.events = {}  # Set of event objects
     for dictionary in initial_data:
         for key in dictionary:
             setattr(self, key, dictionary[key])
     for key in kwargs:
         setattr(self, key, kwargs[key])
Esempio n. 25
0
    def fix_sub(self):
        global var_x
        n = self.HOUSES_PER_PERIOD
        self.m.Params.lazyConstraints = 1
        self.m.optimize(self.subtourelim)
        selected = tuplelist()
        for i in range(self.HOUSES_PER_PERIOD):
            for j in range(self.HOUSES_PER_PERIOD):
                if var_x[i, j, 0, 0].X > 0.5:
                    selected.append((i,j))

        tour = subtour(selected)
        assert len(tour) == n
        self.tourfinal = tour
        self.m.write('sols/SolutionForID_'+ str(self.result_id) + '.sol')
 def subtourelim(model, where):
     if where == grp.GRB.Callback.MIPSOL:
         # make a list of edges selected in the solution
         vals = model.cbGetSolution(model._vars)
         selected = grp.tuplelist((i,j) for i,j in model._vars.keys() if vals[i,j] > 0.5)
         # find the shortest cycle in the selected edge list
         tour = subtour(selected)
         if len(tour) < n:
             tour_sum = grp.LinExpr()
             for tour_index, tour_stop in enumerate(tour):
                 if tour_index < len(tour)-1:
                     tour_sum += model._vars[tour[tour_index], tour[tour_index+1]]
                 else:
                     tour_sum += model._vars[tour[tour_index], tour[0]]
             model.cbLazy(tour_sum <= len(tour)-1)
Esempio n. 27
0
def solve_model(m, vars):
    # Optimize model
    m._vars = vars
    m.Params.lazyConstraints = 1
    m.optimize(subtourelim)
    #m.optimize()

    vals = m.getAttr('x', vars)
    selected = gp.tuplelist((i, j) for i, j in vals.keys() if vals[i, j] > 0.5)

    tour = subtour(selected)
    assert len(tour) == n
    print('')
    print('Optimal tour: %s' % str(tour))
    print('Optimal cost: %g' % m.objVal)
    print('')
    return tour
Esempio n. 28
0
def exact_dual_LP(mdp):
	"""
	Construct an exponentially large LP to solve the MDP with Gurobi.

	This LP follows the standard construction given, for example, on
	p.25 of 'Competitive Markov Decision Processes' by Filar & Vrieze.

	The solution to this LP is the value of the initial state. After
	optimize() has been called, the variables of the LP indicate the
	optimal policy as follows: if the variable v has v.name=s_a, then
	action a is optimal in state s iff v.x > 0.
	"""
	lp = G.Model() # Throws a NameError if gurobipy wasn't loaded
	sa_vars = G.tuplelist()

	for s in mdp.reachable_states:
		sa_vars.append((s, "STOP", lp.addVar(name=str(s)+"_STOP", lb=0)))
		for a in mdp.actions:
			if a.prereq <= s:
				sa_vars.append((s, a, lp.addVar(name=str(s)+"_"+a.name, lb=0)))
	lp.update()

	# set objective
	obj = G.LinExpr()
	for s,a,var in sa_vars:
		rew = mdp.terminal_reward(s)
		if a == "STOP":
			obj += rew * var
		else:
			obj += (a.stop_prob * rew - a.cost) * var
	lp.setObjective(obj, G.GRB.MAXIMIZE)

	# set constraints
	for s in mdp.reachable_states:
		constr = G.quicksum([v for _,__,v in sa_vars.select(s)])
		for parent,action in mdp.reachable_states[s]:
			prob = action.trans_prob(parent, s, mdp.variables)
			var = sa_vars.select(parent,action)[0][2]
			constr -= prob * var
		if s == mdp.initial:
			lp.addConstr(constr, G.GRB.EQUAL, G.LinExpr(1))
		else:
			lp.addConstr(constr, G.GRB.EQUAL, G.LinExpr(0))
	lp.update()
	lp.optimize()	
	return lp, sa_vars
Esempio n. 29
0
def two_cycle(A, C, gap):
    """
    Solve high-vertex dense graphs by reduction to
    weighted matching ILP.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 60 * 60

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    # model as undirected graph
    for i in range(n):
        for j in range(i + 1, n):
            if A[i, j] == 1 and A[j, i] == 1:
                e = (i, j)
                edges.append(e)
                w_i = 2 if i in C else 1
                w_j = 2 if j in C else 1
                w = w_i + w_j
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # 2 cycle constraint <=> undirected flow <= 1
    for i in range(n):
        lhs = LinExpr()
        lhs_vars = [
            vars[e] for e in chain(edges.select(i, _), edges.select(_, i))
        ]
        ones = [1.0] * len(lhs_vars)
        lhs.addTerms(ones, lhs_vars)

        m.addConstr(lhs <= 1)

    m.optimize()
    m.update()

    cycles = [list(e) for e in edges if vars[e].x == 1.0]
    return cycles, m.objval
def graph_parameter(node_file="Nodes_Revised.csv",
                    arc_file="Arcs.csv",
                    commodities_file="Commodities.csv"):
    # data setup into pandas df's
    node_df = pd.read_csv(node_file)
    arc_df = pd.read_csv(arc_file)
    commodities_df = pd.read_csv(commodities_file)

    # comodities and quantity {commodity:quantity}
    commodity_quantity = {
        k: g['weight'].values[0]
        for k, g in commodities_df.groupby('name')
    }

    # nodes
    nodes = node_df['nodes'].tolist()

    # arcs (tuplelist)
    arcs = tuplelist([tuple(pair) for pair in arc_df.values])

    # sources {commodity:source}
    commodity_source = {
        k: g['source'].values[0]
        for k, g in commodities_df.groupby('name')
    }

    # sinks {commodity:sink}
    commodity_sink = {
        k: g['sink'].values[0]
        for k, g in commodities_df.groupby('name')
    }

    # m_distance {(arc pair): euclidean distance}
    m_distance = {}
    for x, y in arcs:
        x1, y1 = node_df.loc[node_df['nodes'] == x].values[0][1:3]
        x2, y2 = node_df.loc[node_df['nodes'] == y].values[0][1:3]
        distance = np.sqrt((x2 - x1)**2 + (y2 - y1)**2)
        m_distance[(x, y)] = distance

    final_list = [
        commodity_quantity, nodes, arcs, commodity_source, commodity_sink,
        m_distance
    ]
    return final_list
    def subtourelim(model, where):
        if where == GRB.Callback.MIPSOL:

            # Chọn ra tập các cạnh trong solution hiện tại
            vals = model.cbGetSolution(model._vars)
            selected = gp.tuplelist(
                (i, j) for i, j in model._vars.keys() if vals[i, j] > 0.5)

            # Tìm ra chu trình có trọng số nhỏ nhất dựa trên các tập cạnh đã được chọn
            tour = subtour(selected)

            # Nếu như chu trình này không đi qua n đỉnh
            if len(tour) < n:
                # thêm ràng buộc loai bỏ các subtour
                model.cbLazy(
                    gp.quicksum(
                        model._vars[i, j]
                        for i, j in combinations(tour, 2)) <= len(tour) - 1)
Esempio n. 32
0
def maximizeMarginalRate(bounds, A, b, noLog=True):
    # A is a matrix and b is a column vector
    # bounds = ((min_f1, max_f1), ..., (min_fk, max_fk))
    # A f <= b
    # return (throughput_f1, ... throughput_fk) > (0, ..., 0) if feasible;
    # otherwise (0, ..., 0)
    numFlow = len(bounds)
    (numRow, numCol) = A.shape
    assert numRow == len(b) and numCol == numFlow

    model = gp.Model()
    # define variables
    flows = gp.tuplelist(t for t in range(numFlow))
    t = model.addVars(flows, vtype=gp.GRB.CONTINUOUS, name="t_")
    for f in flows:
        (minRate, maxRate) = bounds[f]
        t[f].setAttr(gp.GRB.Attr.LB, minRate)
        t[f].setAttr(gp.GRB.Attr.UB, maxRate)
    model.update()

    # define the objective function
    model.setObjective(t.sum(), gp.GRB.MAXIMIZE)

    # define constraints
    for row in range(numRow):
        expr = 0
        for f in flows:
            expr += A[row, f] * t[f]
        model.addConstr(expr <= b[row], name="c_{0}".format(row))

    # solve optimization problem (LP)
    if noLog:
        model.setParam("LogToConsole", 0)
    model.optimize()
    status = model.status
    throughputs = [0] * numFlow
    if status == gp.GRB.Status.OPTIMAL:
        for f in flows:
            throughputs[f] = t[f].X
    elif status == gp.GRB.Status.INFEASIBLE:
        pass
    else:
        assert False, "Solver returns neither OPTIMAL nor INFEASIBLE."
    return tuple(throughputs)
Esempio n. 33
0
def subtourelim(model, where):
    if where == gp.GRB.Callback.MIPSOL:
        # make a list of edges selected in the solution
        vals = model.cbGetSolution(model._vars)
        selected = gp.tuplelist(
            (i, j) for i, j in model._vars.keys() if vals[i, j] > 0.5)
        # find the shortest cycle in the selected edge list
        tour, tours = subtour(selected)

        if len(tour) < n:
            model._subtours += 1
            # add subtour elimination constraint for every pair of cities in tour
            model.cbLazy(
                gp.quicksum(
                    model._vars[i, j]
                    for i, j in itertools.combinations(tour, 2)) <= len(tour) -
                1)
            #st.write(tour)
        current_length = round(model.cbGet(gp.GRB.Callback.MIPSOL_OBJ))
        best = round(model.cbGet(gp.GRB.Callback.MIPSOL_OBJBST))
        bound = max(0, round(model.cbGet(gp.GRB.Callback.MIPSOL_OBJBND)))
        model._summary.markdown(
            "**Sub tour elimination constraints** {:d} **Lower bound** {:d}km  \n**Current Solution**  {:d}km  - {:d} subtour(s)"
            .format(model._subtours, bound, current_length, len(tours)))
        #TODO update bound in other callback. Structure output
        plt.plot([x[0] for x in points], [x[1] for x in points], 'o')
        #print("total tours " + str(sum(len(t) for t in tours)))
        for tour in tours:
            tour.append(tour[0])
            points_tour = [points[i] for i in tour]
            i = [x[0] for x in points_tour], [x[1] for x in points_tour], '-'
            #     plt.plot([x[0] for x in points_tour], [x[1] for x in points_tour], '-')
            fig1, ax = plt.subplots()
            ax.plot([x[0] for x in points_tour], [x[1] for x in points_tour],
                    '-')

        # plt.axis([0, 105, 0, 105])
        # plt.xlabel("km")
        # plt.ylabel("km")
        # model._plot.pyplot()

        ax.set_xlabel('km')
        ax.set_ylabel('km')
        model._plot.pyplot(fig1)
Esempio n. 34
0
def two_cycle(A, C, gap):
    """
    Solve high-vertex dense graphs by reduction to
    weighted matching ILP.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 60 * 60

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    # model as undirected graph
    for i in range(n):
        for j in range(i+1, n):
            if A[i, j] == 1 and A[j, i] == 1:
                e = (i, j)
                edges.append(e)
                w_i = 2 if i in C else 1
                w_j = 2 if j in C else 1
                w = w_i + w_j
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # 2 cycle constraint <=> undirected flow <= 1
    for i in range(n):
        lhs = LinExpr()
        lhs_vars = [vars[e] for e in chain(edges.select(i, _), edges.select(_, i))]
        ones = [1.0]*len(lhs_vars)
        lhs.addTerms(ones, lhs_vars)

        m.addConstr(lhs <= 1)

    m.optimize()
    m.update()

    cycles = [list(e) for e in edges if vars[e].x == 1.0]
    return cycles, m.objval
def get_edges_in_tour(tour_id, x_sol, all_edges):
    '''
    Função que, dado o conjunto de variáveis na solução, retorna as arestas
    (i, j) que estão presentes em uma rota.

    Args:
        tour_id: identificador da rota.
        x_sol: valores de 'x' (variáveis que indicam presença das arestas) na 
            solução.
        all_edges: lista de arestas (i,j) no grafo de entrada.

    Returns:
        Lista de arestas (i,j) na rota 'tour_id'.
    '''

    return gp.tuplelist(
        (i, j) 
        for i, j, k in all_edges
        if x_sol[i, j, k] > 0.5 and k == tour_id
    )       
Esempio n. 36
0
def make_transfers(players):
    m = Model("make_transfers")
    m.params.OutputFlag = 0
    cur_lu = lineup.Lineup().connect(players)
    new_xs, cur_xs = [], []
    team_pos = tuplelist()
    teams = [[] for _ in xrange(players.shape[0])]
    gks, defs, mids, fors = [], [], [], []
    assigns = [gks, defs, mids, fors]
    tcodes = set()

    for i in xrange(players.shape[0]):
        obj = pick_team.player_objective(players.iloc[i], 75)
        v = m.addVar(vtype=GRB.BINARY, obj=obj)
        if players.iloc[i]["code"] in cur_lu:
            cur_xs.append((v, players.iloc[i]))
        else:
            new_xs.append((v, players.iloc[i]))
        ptype = players.iloc[i]["element_type"]
        tcode = players.iloc[i]["team_code"]
        assigns[ptype - 1].append(v)
        teams[tcode - 1].append(v)
        tcodes.add(tcode)
        team_pos.append((v, ptype, tcode))

    m.update()

    money_in, money_out = compute_money_diff(cur_lu, cur_xs, new_xs)

    pick_team.per_pos_team_constr(m, tcodes, team_pos)
    pick_team.total_team_constr(m, teams)

    m.addConstr(quicksum(gks) == 2)
    m.addConstr(quicksum(defs) == 5)
    m.addConstr(quicksum(mids) == 5)
    m.addConstr(quicksum(fors) == 3)
    m.addConstr(quicksum(money_out) <= quicksum(money_in))

    m.optimize()
    return construct_new_team(cur_lu, cur_xs, new_xs)
Esempio n. 37
0
def WassersteinDualSimplex(h1, h2, M):
    """ Find the Wasserstein distance using the dual simplex """
    n = len(h1)

    # Build model
    m = Model()
    m.setParam(GRB.Param.NumericFocus, 3)
    #m.setParam(GRB.Param.TimeLimit, 300)
    #m.setParam(GRB.Param.Presolve,    0)
    #m.setParam(GRB.Param.Threads,     1)
    #  Options are:
    #      -1=automatic, 0=primal simplex, 1=dual simplex, 2=barrier,
    #                    3=concurrent, 4=deterministic concurrent.
    #m.setParam(GRB.Param.Method, 0)
    print('1. Start building model')
    # Create variables
    x = {}
    P = set()
    D = []
    for i in range(n):
        if h1[i] > 0:
            x[i] = {}
            for j in range(n):
                if h2[j] > 0:
                    x[i][j] = m.addVar(ub=min(h1[i], h2[j]), obj=M[i][j])
                    D.append((i, j))
                    P.add(j)
    D = tuplelist(D)
    m.update()
    print('2. Add initial constraint sets')
    for i in x:
        m.addConstr(quicksum(x[i][j] for j in x[i]) <= h1[i])

    for j in P:
        m.addConstr(quicksum(x[i][j] for i, j in D.select('*', j)) >= h2[j])
    print('3. Start solution phase')
    # Solve the model
    m.optimize()

    return m.getAttr(GRB.Attr.ObjVal)
Esempio n. 38
0
def main(N, dist):
    global n
    n = N
    m = gp.Model()
    m.setParam('OutputFlag', 0)

    vars = m.addVars(dist.keys(), obj=dist, vtype=GRB.BINARY, name='e')
    for i, j in vars.keys():
        vars[j, i] = vars[i, j]

    m.addConstrs(vars.sum(i, '*') == 2 for i in range(n))
    m._vars = vars
    m.Params.lazyConstraints = 1
    m.optimize(subtourelim)

    vals = m.getAttr('x', vars)
    selected = gp.tuplelist((i, j) for i, j in vals.keys() if vals[i, j] > 0.5)

    tour = subtour(selected)
    assert len(tour) == n

    return tour, m.objVal
def main(budget=3):
    data = read_csv('temp.csv')
    s = data.groupby('fbus').p.sum()
    d = -data.groupby('tbus').p.sum()
    b = s.add(d, fill_value=0)

    x = data.set_index(['fbus', 'tbus'])
    capacities = x.to_dict()['p']
    x['costs'] = 1
    c = x.to_dict()['costs']

    buses = list(b.index)
    lines, u = multidict(capacities)
    lines = tuplelist(lines)
    S = set(b[b>0].index)
    D = set(b[b<=0].index)
    b = b.to_dict()

    w, v, y, m = solve(budget, buses, lines, u, c, b, S, D)
    if not m.status == GRB.status.OPTIMAL:
        raise RuntimeError('Gurobi did not converge, status %d' % m.status)
    for i, j in y:
        if y[i, j].x > 0:
            print('%d %d' % (i, j))
Esempio n. 40
0
    def createAndSolveOriginalLP(self,projective):
        
        model = gp.Model(self.modelName)
        graph = self.g.graph
        partsManager = self.g.partsManager
        edges = gp.tuplelist(graph.edges())
        nodes = graph.nodes()
        
        # Create variables and objective
        z = {}
        sibs = {}
        gpnt = {}
        edge2val = {}
        sibs2val = {}
        gpnt2val = {}
        # slack variables
        for p in partsManager.getAllParts():
            if p.type == 'arc':
                u = p.u
                v = p.v
                z[u,v]       = model.addVar(vtype=gp.GRB.BINARY,     name=('z_%s_%s' % (u,v)))
                edge2val[u,v] = p.val
            elif p.type == 'sibl':
                u = p.u
                v1 = p.v1
                v2 = p.v2
                sibs[u,v1,v2] = model.addVar(vtype=gp.GRB.BINARY,     name=('sibs_%s_%s_%s' % (u,v1,v2)))
                sibs2val[u,v1,v2] = p.val
            elif p.type == 'grandParant':
                g = p.g
                u = p.u
                v = p.v
                gpnt[g,u,v] = model.addVar(vtype=gp.GRB.BINARY,     name=('gpnt_%s_%s_%s' % (g,u,v)))
                gpnt2val[g,u,v] = p.val
        model.update()
        
        # incoming edges constraints - every node except for 0 has one incoming edge
        self.addIncomingEdgesConstrs(nodes,edges,model,z,'Z')        
        
        if (projective):
            # projectivity + no circles constraints
            self.addProjectiveConstrs(nodes,model,z,'Z',partsManager)
        else:
            # non proj constrs and vars
            self.LPFlowVars = self.addNonProjectiveConstrs(nodes,edges,z,model,'Z')
        
        # high order parts
        for (u,v1,v2) in sibs:
            model.addConstr(sibs[u,v1,v2], gp.GRB.LESS_EQUAL,z[u,v1])
            model.addConstr(sibs[u,v1,v2], gp.GRB.LESS_EQUAL,z[u,v2])
            model.addConstr(sibs[u,v1,v2], gp.GRB.GREATER_EQUAL,z[u,v1] + z[u,v2] - 1)
        
        for (g,u,v) in gpnt:
            model.addConstr(gpnt[g,u,v], gp.GRB.LESS_EQUAL,z[g,u])
            model.addConstr(gpnt[g,u,v], gp.GRB.LESS_EQUAL,z[u,v])
            model.addConstr(gpnt[g,u,v], gp.GRB.GREATER_EQUAL,z[g,u] + z[u,v] - 1)
        
        
        model.update()
                
        # define objective 
        model.setObjective(gp.quicksum(z[u,v]*edge2val[u,v]             for (u,v) in edges) + \
                           gp.quicksum(sibs[u,v1,v2]*sibs2val[u,v1,v2]  for (u,v1,v2) in sibs2val.keys()) + \
                           gp.quicksum(gpnt[u,v1,v2]*gpnt2val[u,v1,v2]  for (u,v1,v2) in gpnt2val.keys()) \
                           ,gp.GRB.MAXIMIZE) 
        
        model.update()
         
        model.setParam('OutputFlag', False )
        # solve the model
        model.optimize()

        if model.status == gp.GRB.status.OPTIMAL:
            optEdges = []
            for (u,v) in edges:
                if z[u,v].x > 0:
                    optEdges.append((u,v))    
        return optEdges
Esempio n. 41
0
def constantino(A, C, k, gap):
    """
    Polynomial-sized CCMcP Edge-Extended Model
    See Constantino et al. (2013)
    """
    t_0 = time.clock()
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    # m.params.timelimit = 60 * 60
    # m.params.nodefilestart = 1.0
    # m.params.nodefiledir = './.nodefiledir'
    # m.params.presparsify = 0
    # m.params.presolve = 0

    n = A.shape[0]
    vars = {}
    edges = tuplelist()

    print('[%.1f] Generating variables...' % (time.clock() - t_0))

    # Variables
    for l in range(n):
        for i in range(l, n):
            for j in range(l, n):
                if A[i, j] == 1:
                    e = (l, i, j)
                    edges.append(e)
                    w = 2 if j in C else 1
                    var = m.addVar(vtype=GRB.BINARY, obj=w)
                    vars[e] = var

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    m.update()

    print('[%.1f] Generated variables' % (time.clock() - t_0))
    print('[%.1f] Adding flow constraints...' % (time.clock() - t_0))

    # Constraint (2): Flow in = Flow out
    for l in range(n):
        for i in range(l, n):
            # Flow in
            lhs_vars = [vars[e] for e in edges.select(l, _, i)]
            ones = [1.0]*len(lhs_vars)
            lhs = LinExpr()
            lhs.addTerms(ones, lhs_vars)

            # Flow out
            rhs_vars = [vars[e] for e in edges.select(l, i, _)]
            ones = [1.0]*len(rhs_vars)
            rhs = LinExpr()
            rhs.addTerms(ones, rhs_vars)

            # Flow in = Flow out
            m.addConstr(lhs == rhs)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added flow constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle vertex constraints...' % (time.clock() - t_0))

    # Constraint (3): Use a vertex only once per cycle
    for i in range(n):
        c_vars = [vars[e] for e in edges.select(_, i, _)]
        ones = [1.0]*len(c_vars)
        expr = LinExpr()
        expr.addTerms(ones, c_vars)
        m.addConstr(expr <= 1.0)

        if i % 100 == 0 and i != 0:
            print('[%.1f] V_i = %d' % (time.clock() - t_0, i))

    print('[%.1f] Added cycle vertex constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle cardinality constraints...' % (time.clock() - t_0))

    # Constraint (4): Limit cardinality of cycles to k
    for l in range(n):
        c_vars = [vars[e] for e in edges.select(l, _, _)]
        ones = [1.0]*len(c_vars)
        expr = LinExpr()
        expr.addTerms(ones, c_vars)
        m.addConstr(expr <= k)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added cycle cardinality constraints' % (time.clock() - t_0))
    print('[%.1f] Adding cycle index constraints...' % (time.clock() - t_0))

    # Constraint (5): Cycle index is smallest vertex-index
    for l in range(n):
        rhs_vars = [vars[e] for e in edges.select(l, l, _)]
        ones = [1.0]*len(rhs_vars)
        rhs = LinExpr()
        rhs.addTerms(ones, rhs_vars)

        for i in range(l+1, n):
            lhs_vars = [vars[e] for e in edges.select(l, i, _)]
            if len(lhs_vars) > 0:
                ones = [1.0]*len(lhs_vars)
                lhs = LinExpr()
                lhs.addTerms(ones, lhs_vars)

                m.addConstr(lhs <= rhs)

        if l % 100 == 0 and l != 0:
            print('[%.1f] l = %d' % (time.clock() - t_0, l))

    print('[%.1f] Added cycle index constraints...' % (time.clock() - t_0))
    print('[%.1f] Begin Optimizing %d vertex model' % (time.clock() - t_0, n))

    m.optimize()
    m.update()

    print('[%.1f] Finished Optimizing' % (time.clock() - t_0))
    print('[%.1f] Building cycles...' % (time.clock() - t_0))

    cycles = []
    for l in range(n):
        c_edges = [(e[1], e[2]) for e in edges.select(l, _, _) if vars[e].x == 1.0]
        cycles.extend(cycles_from_edges(c_edges))

    print('[%.1f] Finished building cycles' % (time.clock() - t_0))

    return cycles, m.objval
Esempio n. 42
0
def lazy_cycle_constraint(A, C, k, gap):
    """
    Lazily generate cycle constraints as potential feasible solutions
    are generated.
    """
    _ = '*'
    m = Model()
    m.modelsense = GRB.MAXIMIZE
    m.params.mipgap = gap
    m.params.timelimit = 5 * 60 * 60
    m.params.lazyconstraints = 1

    n = A.shape[0]
    edges = tuplelist()
    vars = {}

    for i in range(n):
        for j in range(n):
            if A[i, j] == 1:
                e = (i, j)
                edges.append(e)
                w = 2 if j in C else 1
                var = m.addVar(vtype=GRB.BINARY, obj=w)
                vars[e] = var

    m.update()

    # flow constraints
    for i in range(n):
        out_vars = [vars[e] for e in edges.select(i, _)]
        out_ones = [1.0]*len(out_vars)
        out_expr = LinExpr()
        out_expr.addTerms(out_ones, out_vars)

        in_vars = [vars[e] for e in edges.select(_, i)]
        in_ones = [1.0]*len(in_vars)
        in_expr = LinExpr()
        in_expr.addTerms(in_ones, in_vars)

        m.addConstr(in_expr <= 1)
        m.addConstr(out_expr == in_expr)

    m.update()

    ith_cycle = 0

    def callback(model, where):
        if where == GRB.Callback.MIPSOL:
            sols = model.cbGetSolution([vars[e] for e in edges])
            c_edges = [edges[i] for i in range(len(edges)) if sols[i] > 0.5]
            cycles = cycles_from_edges(c_edges)
            for cycle in cycles:
                len_cycle = len(cycle)
                if len_cycle > k:
                    cycle_vars = [vars[(cycle[i], cycle[(i+1) % len_cycle])] for i in range(len_cycle)]
                    ones = [1.0]*len(cycle_vars)
                    expr = LinExpr()
                    expr.addTerms(ones, cycle_vars)
                    model.cbLazy(expr <= len_cycle - 1)

    m.optimize(callback)
    m.update()

    c_edges = [e for e in edges if vars[e].x == 1.0]
    cycles = cycles_from_edges(c_edges)

    return cycles, m.objval
Esempio n. 43
0
    def createLP(self,projective,setGraphEdges,applyPositiveSlacks,alpha):
        
        model = gp.Model(self.modelName)
        graph = self.g.graph
        partsManager = self.g.partsManager
        edges = gp.tuplelist(graph.edges())
        nodes = graph.nodes()
        nonEdgeParts = []
        
        M = 1000
        # Create variables and objective
        z = {}
        # weights
        wplus = {}
#         wminus = {}
        # diff edges counters
        d = {}
        # slack variables
        slackVars = {}
        for p in partsManager.getAllParts():
            if p.type == 'arc':
                u = p.u
                v = p.v
                z[u,v]       = model.addVar(vtype=gp.GRB.BINARY,     name=('z_%s_%s' % (u,v)))
                wplus[u,v]   = model.addVar(vtype=gp.GRB.CONTINUOUS, name=('w+_%s_%s' % (u,v)), lb=-1e21)
#                 wminus[u,v]  = model.addVar(vtype=gp.GRB.CONTINUOUS, name=('w-_%s_%s' % (u,v)), lb=-1e21)
                d[u,v]       = model.addVar(vtype=gp.GRB.BINARY,     name=('d_%s_%s' % (u,v)))
            nonEdgeParts.append(p)
            slackVars[p] = model.addVar(vtype=gp.GRB.CONTINUOUS)
        model.update()
        
        # incoming edges constraints - every node except for 0 has one incoming edge
        self.addIncomingEdgesConstrs(nodes,edges,model,z,'Z')        
        
        if (projective):
            # projectivity + no circles constraints
            self.addProjectiveConstrs(nodes,model,z,'Z',partsManager)
        else:
            # non proj constrs and vars
            self.LPFlowVars = self.addNonProjectiveConstrs(nodes,edges,z,model,'Z',partsManager)
        # diff edges constraints
        for (u,v) in edges:
            isEdge = 0;
            if (u,v) in setGraphEdges:
                isEdge =1;
            model.addConstr(d[u,v] + z[u,v], gp.GRB.GREATER_EQUAL,isEdge,'d_z_y_%s_%s' % (u,v))
            model.addConstr(d[u,v] + isEdge, gp.GRB.GREATER_EQUAL,z[u,v],'d_y_z_%s_%s' % (u,v))
        
#         # for z to be the incoming graph 
#         for (u,v) in setGraphEdges:
#             if (u,v) in edges:
#                 model.addConstr(z[u,v], gp.GRB.GREATER_EQUAL,1,'z_%s_%s_eq_1' % (u,v))
        
        # lower bounds on w constraints
        for part in filter(lambda prt: prt.type in ["arc","grandParant"],partsManager.getAllParts()):
            
            allSubparts = part.getAllSubParts()
            allW = part.val
            for p in allSubparts:
                try:
                    partType = p['type']
                except KeyError:
                    print allSubparts
                    print p
                    print part
                    raise
                if partsManager.hasPart(partType,p):
                    allW += partsManager.getPart(partType,p).val
            operator = gp.GRB.GREATER_EQUAL;
            if (allW < 0):
                operator = gp.GRB.LESS_EQUAL
            # print(self.g.graph.edges())
            allExistingEdges = part.getAllExistingEdges()
            allExistingEdges = filter(lambda (u,v): partsManager.hasArc(u,v),allExistingEdges)
            allNonExistingEdges = part.getAllNonExistingEdges(self.g.n)
            allNonExistingEdges = filter(lambda (u,v): partsManager.hasArc(u,v),allNonExistingEdges)
            if (len(allExistingEdges) + len(allNonExistingEdges) > 0):
#                 print "adding constr '" + str(part) + "', allExisting edges are:",allExistingEdges,", all non existing edges are:",allNonExistingEdges
                if allW < 0:
                    model.addConstr(gp.quicksum(wplus[u,v] for (u,v) in allExistingEdges) \
#                                     + gp.quicksum(wminus[u,v] for (u,v) in allNonExistingEdges)\
                                    - slackVars[part],\
                                    operator,allW,str(part))
                elif applyPositiveSlacks:
                    model.addConstr(gp.quicksum(wplus[u,v] for (u,v) in allExistingEdges) \
#                                     + gp.quicksum(wminus[u,v] for (u,v) in allNonExistingEdges) \
                                    + slackVars[part],\
                                    operator,allW,str(part))
                else:
                    model.addConstr(gp.quicksum(wplus[u,v] for (u,v) in allExistingEdges) \
#                                     + gp.quicksum(wminus[u,v] for (u,v) in allNonExistingEdges) \
                                    ,operator,allW,str(part))
        model.update()
                
        # define objective 
        model.setObjective(
#                            gp.quicksum(2*z[u,v]*(wplus[u,v] - wminus[u,v])                   for (u,v) in edges)          \
                            gp.quicksum(2*z[u,v]*wplus[u,v]                                     for (u,v) in edges)        \
                           - gp.quicksum(d[u,v]*alpha                                          for (u,v) in edges)        \
#                            - gp.quicksum((wplus[u,v] - wminus[u,v])*(wplus[u,v] - wminus[u,v]) for (u,v) in edges)        \
                           - gp.quicksum(wplus[u,v]*wplus[u,v]                                 for (u,v) in edges)        \
                           - gp.quicksum(M*slackVars[part]                                     for  part in nonEdgeParts) \
                           - gp.quicksum(z[u,v]*z[u,v]                                         for (u,v) in edges)        \
                           ,gp.GRB.MAXIMIZE) 

#         model.setObjective(- gp.quicksum(wplus[u,v]*wplus[u,v] for (u,v) in edges)\
#                            - gp.quicksum(M*slackVars[part]     for  part in nonEdgeParts),gp.GRB.MAXIMIZE)
        
        model.update()
        
        self.model  = model
        self.LPVars = z
        self.edges  = edges
        self.nodes  = nodes
        self.wplus  = wplus
#         self.wminus = wminus
        self.slack  = slackVars
def PathBackupModelExample(plot_options,num_nodes,p,invstd,mip_gap,time_limit,cutoff):
    ""
    #######################################
    #        Generating graphs
    #######################################
    
    #Generates a complete indirect graph 
    H = nx.complete_graph(num_nodes)
    # transforms the indirect graph in directed one
    G = H.to_directed()
    
    #Generates a list with all links (edges) in the graph
    links = G.edges()
    #Generates a list with all nodes (vertex) in the graph
    nodes = G.nodes() 
    
    capacity={}
    Aux = 1
    for s,d in links:
        #generating capacity for each s,d link
        capacity[s,d] = Aux
        if capacity[s,d] > 0:
            G.add_weighted_edges_from([(s,d,capacity[s,d])])
        else:
            G.add_weighted_edges_from([(s,d,capacity[s,d])])
            
    
    if plot_options == 1:
    ##############################################
    #            Plot Initial Graph
    ##############################################  
        pos = plotGraph(G, option=None, position=None)
        
    #######################################
    #        Optimization Model
    #######################################
    
    #Find all possible paths in the graph for all source -> destination pairs
    paths = getAllPaths(G,cutoff)
 
    #Find all possible paths for each source (s) -> destination (d) pair
    Psd = {}
    for s,d in links:
        Psd[s,d] = nx.all_simple_paths(G, s, d,cutoff)
    
    #Find all s->d paths that uses the i->j link
    Pij={}
    for i,j in links:
        for s,d in links:
            Pij[i,j,s,d] = getLinkPaths(G,i,j,s,d,cutoff)
    
    capacity={}
    mean={}
    std={}
    
    AuxCount = 0
    Aux=1
    for s,d in links:
        #generating capacity for each s,d link
        capacity[s,d] = Aux
        #Generate mean for each s,d link based on Binomial distribution 
        mean[s,d] = Aux*p
        #Generate std for each s,d link based on Binomial distribution 
        std[s,d]=math.sqrt(Aux*p*(1-(Aux*p)))
        AuxCount = AuxCount+1
        
    #optimization
    links = tuplelist(links)
    # Creating a backup network model
    BackupNet = PathBackup(nodes,links,paths,Psd,Pij,capacity,mean,std,invstd)
    # Find a optimal solution
    solution = BackupNet.optimize(mip_gap,time_limit)
         
    #Remove links not chosen as backup link
    for i,j in links:
        if solution[i,j] < 0.1:
            G.remove_edge(i, j)
    
    ##############################################
    #            Plot Solution
    ##############################################     
    if plot_options == 1:
        option=1
        plotGraph(G, option, pos)
Esempio n. 45
0
    def solve(self, objective, constraints, cached_data,
              warm_start, verbose, solver_opts):
        """Returns the result of the call to the solver.

        Parameters
        ----------
        objective : LinOp
            The canonicalized objective.
        constraints : list
            The list of canonicalized cosntraints.
        cached_data : dict
            A map of solver name to cached problem data.
        warm_start : bool
            Not used.
        verbose : bool
            Should the solver print output?
        solver_opts : dict
            Additional arguments for the solver.

        Returns
        -------
        tuple
            (status, optimal value, primal, equality dual, inequality dual)
        """
        import gurobipy

        # Get problem data
        data = self.get_problem_data(objective, constraints, cached_data)

        c = data[s.C]
        b = data[s.B]
        A = dok_matrix(data[s.A])
        # Save the dok_matrix.
        data[s.A] = A

        n = c.shape[0]

        solver_cache = cached_data[self.name()]

        # TODO warmstart with SOC constraints.
        if warm_start and solver_cache.prev_result is not None \
           and len(data[s.DIMS][s.SOC_DIM]) == 0:
            model = solver_cache.prev_result["model"]
            variables = solver_cache.prev_result["variables"]
            gur_constrs = solver_cache.prev_result["gur_constrs"]
            c_prev = solver_cache.prev_result["c"]
            A_prev = solver_cache.prev_result["A"]
            b_prev = solver_cache.prev_result["b"]

            # If there is a parameter in the objective, it may have changed.
            if len(lu.get_expr_params(objective)) > 0:
                c_diff = c - c_prev

                I_unique = list(set(np.where(c_diff)[0]))

                for i in I_unique:
                    variables[i].Obj = c[i]
            else:
                # Stay consistent with Gurobi's representation of the problem
                c = c_prev

            # Get equality and inequality constraints.
            sym_data = self.get_sym_data(objective, constraints, cached_data)
            all_constrs, _, _ = self.split_constr(sym_data.constr_map)

            # If there is a parameter in the constraints,
            # A or b may have changed.
            if self._param_in_constr(all_constrs):
                A_diff = dok_matrix(A - A_prev)
                b_diff = b - b_prev

                # Figure out which rows of A and elements of b have changed
                try:
                    idxs, _ = zip(*[x for x in A_diff.keys()])
                except ValueError:
                    idxs = []
                I_unique = list(set(idxs) | set(np.where(b_diff)[0]))

                nonzero_locs = gurobipy.tuplelist(A.keys())

                # Update locations which have changed
                for i in I_unique:

                    # Remove old constraint if it exists
                    if gur_constrs[i] is not None:
                        model.remove(gur_constrs[i])
                        gur_constrs[i] = None

                    # Add new constraint
                    if nonzero_locs.select(i, "*"):
                        expr_list = []
                        for loc in nonzero_locs.select(i, "*"):
                            expr_list.append((A[loc], variables[loc[1]]))
                        expr = gurobipy.LinExpr(expr_list)
                        if i < data[s.DIMS][s.EQ_DIM]:
                            ctype = gurobipy.GRB.EQUAL
                        elif data[s.DIMS][s.EQ_DIM] <= i \
                                < data[s.DIMS][s.EQ_DIM] + data[s.DIMS][s.LEQ_DIM]:
                            ctype = gurobipy.GRB.LESS_EQUAL
                        gur_constrs[i] = model.addConstr(expr, ctype, b[i])

                model.update()
            else:
                # Stay consistent with Gurobi's representation of the problem
                A = A_prev
                b = b_prev

        else:
            model = gurobipy.Model()
            variables = []
            for i in range(n):
                # Set variable type.
                if i in data[s.BOOL_IDX]:
                    vtype = gurobipy.GRB.BINARY
                elif i in data[s.INT_IDX]:
                    vtype = gurobipy.GRB.INTEGER
                else:
                    vtype = gurobipy.GRB.CONTINUOUS
                variables.append(
                    model.addVar(
                        obj=c[i],
                        name="x_%d" % i,
                        vtype=vtype,
                        # Gurobi's default LB is 0 (WHY???)
                        lb=-gurobipy.GRB.INFINITY,
                        ub=gurobipy.GRB.INFINITY)
                )
            model.update()

            eq_constrs = self.add_model_lin_constr(model, variables,
                                                   range(data[s.DIMS][s.EQ_DIM]),
                                                   gurobipy.GRB.EQUAL,
                                                   A, b)
            leq_start = data[s.DIMS][s.EQ_DIM]
            leq_end = data[s.DIMS][s.EQ_DIM] + data[s.DIMS][s.LEQ_DIM]
            ineq_constrs = self.add_model_lin_constr(model, variables,
                                                     range(leq_start, leq_end),
                                                     gurobipy.GRB.LESS_EQUAL,
                                                     A, b)
            soc_start = leq_end
            soc_constrs = []
            new_leq_constrs = []
            for constr_len in data[s.DIMS][s.SOC_DIM]:
                soc_end = soc_start + constr_len
                soc_constr, new_leq, new_vars = self.add_model_soc_constr(
                    model, variables, range(soc_start, soc_end),
                    A, b
                )
                soc_constrs.append(soc_constr)
                new_leq_constrs += new_leq
                variables += new_vars
                soc_start += constr_len

            gur_constrs = eq_constrs + ineq_constrs + \
                soc_constrs + new_leq_constrs
            model.update()

        # Set verbosity and other parameters
        model.setParam("OutputFlag", verbose)
        # TODO user option to not compute duals.
        model.setParam("QCPDual", True)

        for key, value in solver_opts.items():
            model.setParam(key, value)

        results_dict = {}
        try:
            model.optimize()
            results_dict["primal objective"] = model.ObjVal
            results_dict["x"] = np.array([v.X for v in variables])

            # Only add duals if not a MIP.
            # Not sure why we need to negate the following,
            # but need to in order to be consistent with other solvers.
            if not self.is_mip(data):
                vals = []
                for lc in gur_constrs:
                    if lc is not None:
                        if isinstance(lc, gurobipy.QConstr):
                            vals.append(lc.QCPi)
                        else:
                            vals.append(lc.Pi)
                    else:
                        vals.append(0)
                results_dict["y"] = -np.array(vals)

            results_dict["status"] = self.STATUS_MAP.get(model.Status,
                                                         s.SOLVER_ERROR)
        except gurobipy.GurobiError:
            results_dict["status"] = s.SOLVER_ERROR

        results_dict["model"] = model
        results_dict["variables"] = variables
        results_dict["gur_constrs"] = gur_constrs
        results_dict[s.SOLVE_TIME] = model.Runtime

        return self.format_results(results_dict, data, cached_data)
    def LoadModel(self,Gamma,Nodes,Links,Capacity,Survivability,NumSamples,BackupCapacity, BackupLinks):
        """ Load model.
    
        Parameters
        ----------
        Gamma : importance sampling vector
        
        """         
        self.Links = tuplelist(Links)
        self.Capacity = Capacity
        self.BackupCapacity = BackupCapacity
        self.BackupLinks = tuplelist(BackupLinks)
               
        # Create optimization model
        self.model = Model('Backup')
     
        SumBackupCapacity=0
        SumFloorBackupCapacity=0
        self.HatBackupCapacity={}
        for i,j in self.BackupLinks:
            self.BackupCapacity[i,j]=round(BackupCapacity[i,j],1)
            self.HatBackupCapacity[i,j]=math.floor(self.BackupCapacity[i,j])
            SumBackupCapacity=SumBackupCapacity+BackupCapacity[i,j]
            SumFloorBackupCapacity=SumFloorBackupCapacity+self.HatBackupCapacity[i,j]
        self.BarDelta = math.ceil(SumBackupCapacity-SumFloorBackupCapacity)
        print('barDelta=%g'%self.BarDelta)
        
        # Create variables
        for i,j in self.BackupLinks:
            self.Delta[i,j] = self.model.addVar(vtype=GRB.INTEGER,lb=0, name='Delta[%s,%s]' % (i, j))
        self.model.update()
        
        self.Theta = self.model.addVar(name='Theta')
        self.model.update()
          
        for i,j in self.BackupLinks:
            for s,d in self.Links:
                self.bBackupLink[i,j,s,d] = self.model.addVar(vtype=GRB.BINARY,name='Backup_Link[%s,%s,%s,%s]' % (i, j, s, d))
        self.model.update()
        
        for i,j in self.BackupLinks:
            for k in range(NumSamples):
                self.z[k,i,j] = self.model.addVar(lb=0,name='z[%s][%s][%s]' % (k,i,j))
        self.model.update()
        
        for i,j in self.BackupLinks: 
            self.z0[i,j] = self.model.addVar(lb=-GRB.INFINITY,name='z0[%s][%s]' %(i,j))
        self.model.update()
         
        self.model.modelSense = GRB.MINIMIZE
        
        self.model.setObjective(self.Theta)
        self.model.update()
         
            
        #------------------------------------------------------------------------#
        #                    Constraints definition                              #
        #                                                                        #
        #                                                                        #
        #------------------------------------------------------------------------#
          
        # Buffer probability I
        for i,j in self.BackupLinks:
            self.model.addConstr(self.z0[i,j] + 1/(NumSamples*Survivability)*quicksum(self.z[k,i,j] for (k) in range(NumSamples)) <= self.Theta,'[CONST]Buffer_Prob_I[%s][%s]'%(i,j))
        self.model.update()
         
        # Link capacity constraints
        for i,j in self.BackupLinks:
            for k in range(NumSamples):
                if Gamma == None:
                    self.model.addConstr((quicksum(self.bBackupLink[i,j,s,d]*Capacity[k,s,d] for s,d in self.Links) - (self.Delta[i,j] + self.HatBackupCapacity[i,j]) - self.z0[i,j]) <= self.z[k,i,j],'[CONST]Buffer_Prob_II[%s][%s][%s]' % (k,i,j))
                else:    
                    self.model.addConstr((quicksum(self.bBackupLink[i,j,s,d]*Capacity[k,s,d] for s,d in self.Links) - (self.Delta[i,j] + self.HatBackupCapacity[i,j]) - self.z0[i,j])*Gamma[k] <= self.z[k,i,j],'[CONST]Buffer_Prob_II[%s][%s][%s]' % (k,i,j))
        self.model.update()
        
        # Link capacity constraints
        for i,j in self.BackupLinks:
            for k in range(NumSamples):
                self.model.addConstr(self.z[k,i,j] >= 0,'[CONST]Buffer_Prob_III[%s][%s][%s]' % (k,i,j))
        self.model.update()
        
        for i,j in self.BackupLinks:
            self.model.addConstr(quicksum(self.Delta[i,j] for i,j in self.BackupLinks) <= self.BarDelta, '[CONST]Delta[%s][%s]' % (i,j))
 
        for i in Nodes:
            for s,d in self.Links:
                # Flow conservation constraints
                if i == s:
                    self.model.addConstr(quicksum(self.bBackupLink[i,j,s,d] for i,j in self.BackupLinks.select(i,'*')) - 
                                           quicksum(self.bBackupLink[j,i,s,d] for j,i in self.BackupLinks.select('*',i)) == 1,'Flow1[%s,%s,%s]' % (i,s,d))
                # Flow conservation constraints
                elif i == d:
                    self.model.addConstr(quicksum(self.bBackupLink[i,j,s,d] for i,j in self.BackupLinks.select(i,'*')) - 
                                           quicksum(self.bBackupLink[j,i,s,d] for j,i in self.BackupLinks.select('*',i)) == -1,'Flow2[%s,%s,%s]' % (i,s,d))
                # Flow conservation constraints
                else:    
                    self.model.addConstr(quicksum(self.bBackupLink[i,j,s,d] for i,j in self.BackupLinks.select(i,'*')) - 
                                           quicksum(self.bBackupLink[j,i,s,d] for j,i in self.BackupLinks.select('*',i)) == 0,'Flow3[%s,%s,%s]' % (i,s,d))
        self.model.update()
    def LoadModel(self, Gamma, Nodes, Links, Capacity, Survivability, NumSamples):
        """ Load model.
    
        Parameters
        ----------
        Gamma : importance sampling vector
        
        """
        self.Links = tuplelist(Links)
        self.Capacity = Capacity

        # Create optimization model
        self.model = Model("Backup")

        # Create variables
        for i, j in self.Links:
            self.BackupCapacity[i, j] = self.model.addVar(
                vtype=GRB.CONTINUOUS, lb=0, name="Backup_Capacity[%s,%s]" % (i, j)
            )
            # self.BackupCapacity[i,j] = self.model.addVar(lb=0, name='Backup_Capacity[%s,%s]' % (i, j))
        self.model.update()

        for i, j in self.Links:
            for s, d in self.Links:
                self.bBackupLink[i, j, s, d] = self.model.addVar(
                    vtype=GRB.BINARY, name="Backup_Link[%s,%s,%s,%s]" % (i, j, s, d)
                )
        self.model.update()

        for i, j in self.Links:
            for k in range(NumSamples):
                self.z[k, i, j] = self.model.addVar(lb=0, name="z[%s][%s][%s]" % (k, i, j))
        self.model.update()

        for i, j in self.Links:
            self.z0[i, j] = self.model.addVar(lb=-GRB.INFINITY, name="z0[%s][%s]" % (i, j))
        self.model.update()

        self.model.modelSense = GRB.MINIMIZE

        self.model.setObjective(quicksum(self.BackupCapacity[i, j] for i, j in self.Links))
        self.model.update()

        # ------------------------------------------------------------------------#
        #                    Constraints definition                              #
        #                                                                        #
        #                                                                        #
        # ------------------------------------------------------------------------#

        # Buffer probability I
        for i, j in self.Links:
            self.model.addConstr(
                self.z0[i, j]
                + 1 / (NumSamples * Survivability) * quicksum(self.z[k, i, j] for (k) in range(NumSamples))
                <= 0,
                "[CONST]Buffer_Prob_I[%s][%s]" % (i, j),
            )
        self.model.update()

        # Link capacity constraints
        for i, j in self.Links:
            for k in range(NumSamples):
                if Gamma == None:
                    self.model.addConstr(
                        (
                            quicksum(self.bBackupLink[i, j, s, d] * Capacity[k, s, d] for s, d in self.Links)
                            - self.BackupCapacity[i, j]
                            - self.z0[i, j]
                        )
                        <= self.z[k, i, j],
                        "[CONST]Buffer_Prob_II[%s][%s][%s]" % (k, i, j),
                    )
                else:
                    self.model.addConstr(
                        (
                            quicksum(self.bBackupLink[i, j, s, d] * Capacity[k, s, d] for s, d in self.Links)
                            - self.BackupCapacity[i, j]
                            - self.z0[i, j]
                        )
                        * Gamma[k]
                        <= self.z[k, i, j],
                        "[CONST]Buffer_Prob_II[%s][%s][%s]" % (k, i, j),
                    )
        self.model.update()

        # Link capacity constraints
        for i, j in self.Links:
            for k in range(NumSamples):
                self.model.addConstr(self.z[k, i, j] >= 0, "[CONST]Buffer_Prob_III[%s][%s][%s]" % (k, i, j))
        self.model.update()

        for i in Nodes:
            for s, d in self.Links:
                # Flow conservation constraints
                if i == s:
                    self.model.addConstr(
                        quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*"))
                        - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i))
                        == 1,
                        "Flow1[%s,%s,%s]" % (i, s, d),
                    )
                # Flow conservation constraints
                elif i == d:
                    self.model.addConstr(
                        quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*"))
                        - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i))
                        == -1,
                        "Flow2[%s,%s,%s]" % (i, s, d),
                    )
                # Flow conservation constraints
                else:
                    self.model.addConstr(
                        quicksum(self.bBackupLink[i, j, s, d] for i, j in self.Links.select(i, "*"))
                        - quicksum(self.bBackupLink[j, i, s, d] for j, i in self.Links.select("*", i))
                        == 0,
                        "Flow3[%s,%s,%s]" % (i, s, d),
                    )
        self.model.update()
Esempio n. 48
0
    def solve(self, objective, constraints, cached_data,
              warm_start, verbose, solver_opts):
        """Returns the result of the call to the solver.

        Parameters
        ----------
        objective : LinOp
            The canonicalized objective.
        constraints : list
            The list of canonicalized cosntraints.
        cached_data : dict
            A map of solver name to cached problem data.
        warm_start : bool
            Not used.
        verbose : bool
            Should the solver print output?
        solver_opts : dict
            Additional arguments for the solver.

        Returns
        -------
        tuple
            (status, optimal value, primal, equality dual, inequality dual)
        """
        import gurobipy

        # Get problem data
        data = self.get_problem_data(objective, constraints, cached_data)

        c = data[s.C]
        b = data[s.B]
        h = data[s.H]
        A = dok_matrix(data[s.A])
        G = dok_matrix(data[s.G])

        n = c.shape[0]

        solver_cache = cached_data[self.name()]

        if warm_start and solver_cache.prev_result is not None:
            model = solver_cache.prev_result["model"]
            variables = solver_cache.prev_result["variables"]
            eq_constrs = solver_cache.prev_result["eq_constrs"]
            ineq_constrs = solver_cache.prev_result["ineq_constrs"]
            c_prev = solver_cache.prev_result["c"]
            A_prev = solver_cache.prev_result["A"]
            b_prev = solver_cache.prev_result["b"]
            G_prev = solver_cache.prev_result["G"]
            h_prev = solver_cache.prev_result["h"]

            # If there is a parameter in the objective, it may have changed.
            if len(lu.get_expr_params(objective)) > 0:
                c_diff = c - c_prev

                I_unique = list(set(np.where(c_diff)[0]))

                for i in I_unique:
                    variables[i].Obj = c[i]
            else:
                # Stay consistent with Gurobi's representation of the problem
                c = c_prev

            # Get equality and inequality constraints.
            sym_data = self.get_sym_data(objective, constraints, cached_data)
            eq_constr, ineq_constr, _ = self.split_constr(sym_data.constr_map)

            # If there is a parameter in the equality constraints,
            # A or b may have changed.
            if self.param_in_constr(eq_constr):
                A_diff = dok_matrix(A - A_prev)
                b_diff = b - b_prev

                # Figure out which rows of A and elements of b have changed
                try:
                    I, _ = zip(*[x for x in A_diff.iterkeys()])
                except ValueError:
                    I = []
                I_unique = list(set(I) | set(np.where(b_diff)[0]))

                A_nonzero_locs = gurobipy.tuplelist([x for x in A.iterkeys()])

                # Update locations which have changed
                for i in I_unique:

                    # Remove old constraint if it exists
                    if eq_constrs[i] != None:
                        model.remove(eq_constrs[i])
                        eq_constrs[i] = None

                    # Add new constraint
                    if len(A_nonzero_locs.select(i, "*")):
                        expr_list = []
                        for loc in A_nonzero_locs.select(i, "*"):
                            expr_list.append((A[loc], variables[loc[1]]))
                        expr = gurobipy.LinExpr(expr_list)
                        eq_constrs[i] = model.addConstr(expr,
                                                        gurobipy.GRB.EQUAL,
                                                        b[i])

                model.update()
            else:
                # Stay consistent with Gurobi's representation of the problem
                A = A_prev
                b = b_prev

            # If there is a parameter in the inequality constraints,
            # G or h may have changed.
            if self.param_in_constr(ineq_constr):
                G_diff = dok_matrix(G - G_prev)
                h_diff = h - h_prev

                # Figure out which rows of G and elements of h have changed
                try:
                    I, _ = zip(*[x for x in G_diff.iterkeys()])
                except ValueError:
                    I = []
                I_unique = list(set(I) | set(np.where(h_diff)[0]))

                G_nonzero_locs = gurobipy.tuplelist([x for x in G.iterkeys()])

                # Update locations which have changed
                for i in I_unique:

                    # Remove old constraint if it exists
                    if ineq_constrs[i] != None:
                        model.remove(ineq_constrs[i])
                        ineq_constrs[i] = None

                    # Add new constraint
                    if len(G_nonzero_locs.select(i, "*")):
                        expr_list = []
                        for loc in G_nonzero_locs.select(i, "*"):
                            expr_list.append((G[loc], variables[loc[1]]))
                        expr = gurobipy.LinExpr(expr_list)
                        ineq_constrs[i] = model.addConstr(expr,
                                            gurobipy.GRB.LESS_EQUAL, h[i])

                model.update()
            else:
                # Stay consistent with Gurobi's representation of the problem
                G = G_prev
                h = h_prev

        else:
            model = gurobipy.Model()
            variables = [
                model.addVar(
                    obj = c[i],
                    name = "x_%d" % i,
                    # Gurobi's default LB is 0 (WHY???)
                    lb = -gurobipy.GRB.INFINITY,
                    ub =  gurobipy.GRB.INFINITY)
                for i in xrange(n)]
            model.update()

            eq_constrs = [None] * b.shape[0]
            if A.nnz > 0 or b.any:
                try:
                    I, _ = zip(*[x for x in A.iterkeys()])
                except ValueError:
                    I = []
                eq_constrs_nonzero_idxs = list(set(I) | set(np.where(b)[0]))
                A_nonzero_locs = gurobipy.tuplelist([x for x in A.iterkeys()])

                for i in eq_constrs_nonzero_idxs:
                    expr_list = []
                    for loc in A_nonzero_locs.select(i, "*"):
                        expr_list.append((A[loc], variables[loc[1]]))
                    expr = gurobipy.LinExpr(expr_list)

                    eq_constrs[i] = model.addConstr(expr,
                                                    gurobipy.GRB.EQUAL,
                                                    b[i])

            ineq_constrs = [None] * h.shape[0]
            if G.nnz > 0 or h.any:
                try:
                    I, _ = zip(*[x for x in G.iterkeys()])
                except ValueError:
                    I = []
                ineq_constrs_nonzero_idxs = list(set(I) | set(np.where(h)[0]))
                G_nonzero_locs = gurobipy.tuplelist([x for x in G.iterkeys()])

                for i in ineq_constrs_nonzero_idxs:
                    expr_list = []
                    for loc in G_nonzero_locs.select(i, "*"):
                        expr_list.append((G[loc], variables[loc[1]]))
                    expr = gurobipy.LinExpr(expr_list)

                    ineq_constrs[i] = model.addConstr(expr,
                                                      gurobipy.GRB.LESS_EQUAL,
                                                      h[i])

            model.update()

        # Set verbosity and other parameters
        if verbose:
            model.setParam("OutputFlag", True)
        else:
            model.setParam("OutputFlag", False)

        for key, value in solver_opts.items():
            if key in self.CUSTOM_OPTS:
                continue
            model.setParam(key, value)

        try:
            model.optimize()

            results_dict = {
                "model": model,
                "variables": variables,
                "eq_constrs": eq_constrs,
                "ineq_constrs": ineq_constrs,
                "c": c,
                "A": A,
                "b": b,
                "G": G,
                "h": h,
                "status": self.STATUS_MAP.get(model.Status, "unknown"),
                "primal objective": model.ObjVal,
                "x": np.array([v.X for v in variables]),
                # Not sure why we need to negate the following,
                # but need to in order to be consistent with other solvers.
                "y": -np.array([lc.Pi if lc != None else 0 for lc in eq_constrs]),
                "z": -np.array([lc.Pi if lc != None else 0 for lc in ineq_constrs]),
                }
        except gurobipy.GurobiError:
            results_dict = {
                "status": s.SOLVER_ERROR
            }



        return self.format_results(results_dict, data[s.DIMS],
                                   data[s.OFFSET], cached_data)