コード例 #1
0
def obtainWassersteinProblem( roadnet, length='length', weight1='weight1', weight2='weight2' ) :
    """
    input: a road network, with weights on its elements
    output:
    returns a graph summarizing the network optimization problem instance;
    roadnets are multi-digraph, where edge 'keys' are assumed to be unique,
    i.e., road names; and should be different from node labels too;
    """
    
    # for convenience
    #ROADS = [ key for u,v,key in roadnet.edges_iter( keys=True ) ]
    class node : pass
    node_s = node() ; node_t = node()
    
    digraph = nx.DiGraph()
    digraph.add_node( node_s )
    digraph.add_node( node_t )
    
    """ insert supply and demand of roads """
    for u,v, road, data in roadnet.edges_iter( keys=True, data=True ) :
        roadlen = data.get( length, 1. )
        assert roadlen >= 0.
        
        oneway = data.get( 'oneway', False )
        
        surplus = data.get( weight1, 0. ) - data.get( weight2, 0. )
        deficit = -surplus
        
        # supply layer
        if surplus > 0. :
            digraph.add_edge( node_s, road, capacity=surplus )
            
            w = roadlen / surplus
            if oneway : ends = [ v ]
            else : ends = [ u, v ]
            for node in ends :
                digraph.add_edge( road, node, decision_weight=w )
                
        # demand layers
        if deficit > 0. :
            digraph.add_edge( road, node_t, capacity=deficit )
            
            w = roadlen / deficit
            if oneway : ends = [ u ]
            else : ends = [ u, v ]
            for node in ends :
                digraph.add_edge( node, road, decision_weight=w )
                
    """ insert supply and demand of nodes """
    for u, data in roadnet.nodes_iter( data=True ) :
        surplus = data.get( weight1, 0. ) - data.get( weight2, 0. )
        deficit = -surplus
        
        # supply layer
        if surplus > 0. :
            digraph.add_edge( node_s, u, capacity=surplus )
        if deficit > 0. :
            digraph.add_edge( u, node_t, capacity=deficit )
            
    """ setup the network flow structure """
    conns = roadmap_basic.connectivity_graph( roadnet, length_in=length )
    for u, v, data in conns.edges_iter( data=True ) :
        w = data.get( 'length', 1 )
        digraph.add_edge( u, v, weight=w )
    
    #return digraph, node_s, node_t        # this *just* produced a flowgraph; no problem
    flowgraph = flownets.obtainFlowNetwork( digraph, node_s, node_t )
    costgraph = flownets.obtainWeightedCosts( flowgraph, digraph )        # cute trick
    
    #return flowgraph, costgraph
    
    for u,v, data in digraph.edges_iter( data=True ) :
        dec_weight = data.get( 'decision_weight', None )
        if dec_weight is None : continue
        #
        fdata = flowgraph.get_edge_data( u, v, 0 )   # key=0, because we have tightly controlled this construction
        flow = fdata.get( 'flow' )
        
        cost = .5 * dec_weight * cvxpy.square( flow )
        #print dec_weight, flow, cost
        
        cdata = costgraph.get_edge_data( u, v, 0 )
        #print cdata
        cdata['cost'] = cost
    
    return flowgraph, costgraph
コード例 #2
0
def measurenx_to_approxnx(roadnet, epsilon, length="length", weight1="weight1", weight2="weight2"):
    """
    input: a road network, with weights on its elements
    output:
    returns a graph summarizing the network optimization problem instance;
    roadnets are multi-digraph, where edge 'keys' are assumed to be unique,
    i.e., road names; and should be different from node labels too;
    """
    digraph = nx.DiGraph()
    digraph.add_node("s")
    digraph.add_node("t")

    """ insert supply and demand of roads """
    for u, v, road, data in roadnet.edges_iter(keys=True, data=True):
        roadlen = float(data.get(length, 1))  # float() just in case
        assert roadlen >= 0.0

        oneway = data.get("oneway", False)

        surplus = float(data.get(weight1, 0.0)) - data.get(weight2, 0.0)
        deficit = -surplus

        """
        split the road into equal-length segments;
        create a node for each segment;
        """
        N = int(np.ceil(roadlen / epsilon))
        eps = roadlen / N

        if surplus > 0.0:
            NODES = [(road, k, "supply") for k in range(N)]
            for node in NODES:
                digraph.add_edge(
                    "s", node, flow=cvxpy.variable(), minflow=0.0, maxflow=surplus / N, w_lo=-eps, w_hi=0.0
                )

            SEQ = [u] + NODES + [v]
            for lnode, rnode in zip(SEQ[:-1], SEQ[1:]):
                digraph.add_edge(lnode, rnode, flow=cvxpy.variable(), minflow=0.0, w_lo=eps, w_hi=eps)
                if not oneway:
                    digraph.add_edge(rnode, lnode, flow=cvxpy.variable(), minflow=0.0, w_lo=eps, w_hi=eps)

        if deficit > 0.0:
            NODES = [(road, k, "demand") for k in range(N)]
            for node in NODES:
                digraph.add_edge(
                    node, "t", flow=cvxpy.variable(), minflow=0.0, maxflow=deficit / N, w_lo=-eps, w_hi=0.0
                )

            SEQ = [u] + NODES + [v]
            for lnode, rnode in zip(SEQ[:-1], SEQ[1:]):
                digraph.add_edge(lnode, rnode, flow=cvxpy.variable(), minflow=0.0, w_lo=eps, w_hi=eps)
                if not oneway:
                    digraph.add_edge(rnode, lnode, flow=cvxpy.variable(), minflow=0.0, w_lo=eps, w_hi=eps)

    """ insert supply and demand of nodes """
    for u, data in roadnet.nodes_iter(data=True):
        surplus = data.get(weight1, 0.0) - data.get(weight2, 0.0)
        deficit = -surplus

        # supply layer
        if surplus > 0.0:
            digraph.add_edge("s", u, flow=cvxpy.variable(), minflow=0.0, maxflow=surplus)
        if deficit > 0.0:
            digraph.add_edge(u, "t", flow=cvxpy.variable(), minflow=0.0, maxflow=deficit)

    """ setup the network flow structure """
    conns = roadmaps.connectivity_graph(roadnet)
    for u, v, data in conns.edges_iter(data=True):
        weight = data.get(length, 1)
        flowvar = cvxpy.variable()
        digraph.add_edge(u, v, flow=cvxpy.variable(), minflow=0.0, w_lo=weight, w_hi=weight)

    """ turn the weights into costs """
    for _, __, data in digraph.edges_iter(data=True):
        flowvar = data["flow"]
        if "w_lo" in data:
            data["cost_lo"] = data["w_lo"] * flowvar
        if "w_hi" in data:
            data["cost_hi"] = data["w_hi"] * flowvar

    nxopt.attach_flownx_constraints(digraph)
    return digraph  # a flownx