示例#1
0
def waxman_2_topology(n,
                      alpha=0.4,
                      beta=0.1,
                      domain=(0, 0, 1, 1),
                      distance_unit='Km',
                      seed=None):
    r"""Return a Waxman-2 random topology.

    The Waxman-2 random topology models place n nodes uniformly at random
    in a rectangular domain. Two nodes u, v are connected with a link
    with probability

    .. math::
            p = \alpha*exp(-d/(\beta*L)).

    where the distance *d* is the Euclidean distance between the nodes u and v.
    and *L* is the maximum distance between all nodes in the graph.


    Parameters
    ----------
    n : int
        Number of nodes
    alpha : float
        Model parameter chosen in *(0,1]* (higher alpha increases link density)
    beta : float
        Model parameter chosen in *(0,1]* (higher beta increases difference
        between density of short and long links)
    domain : tuple of numbers, optional
         Domain size (xmin, ymin, xmax, ymax)
    seed : int, optional
        Seed for random number generator (default=None).

    Returns
    -------
    G : Topology

    Notes
    -----
    Each edge of G has the attribute *length*

    References
    ----------
    .. [1]  B. M. Waxman, Routing of multipoint connections.
       IEEE J. Select. Areas Commun. 6(9),(1988) 1617-1622.
    """
    # validate input parameters
    if not isinstance(n, int) or n <= 0:
        raise ValueError('n must be a positive integer')
    if alpha > 1 or alpha <= 0 or beta > 1 or beta <= 0:
        raise ValueError('alpha and beta must be float values in (0,1]')
    if not isinstance(domain, tuple) or len(domain) != 4:
        raise ValueError('domain must be a tuple of 4 number')
    (xmin, ymin, xmax, ymax) = domain
    if xmin > xmax:
        raise ValueError('In domain, xmin cannot be greater than xmax')
    if ymin > ymax:
        raise ValueError('In domain, ymin cannot be greater than ymax')
    if seed is not None:
        random.seed(seed)

    G = Topology(type='waxman_2', distance_unit=distance_unit)
    G.name = "waxman_2_topology(%s, %s, %s)" % (n, alpha, beta)
    G.add_nodes_from(range(n))

    for v in G.nodes_iter():
        G.node[v]['latitude'] = (ymin + (ymax - ymin)) * random.random()
        G.node[v]['longitude'] = (xmin + (xmax - xmin)) * random.random()

    l = {}
    nodes = G.nodes()
    while nodes:
        u = nodes.pop()
        for v in nodes:
            x_u = G.node[u]['longitude']
            x_v = G.node[v]['longitude']
            y_u = G.node[u]['latitude']
            y_v = G.node[v]['latitude']
            l[(u, v)] = math.sqrt((x_u - x_v)**2 + (y_u - y_v)**2)
    L = max(l.values())
    for (u, v), d in l.items():
        if random.random() < alpha * math.exp(-d / (beta * L)):
            G.add_edge(u, v, length=d)

    return G
示例#2
0
def waxman_2_topology(n, alpha=0.4, beta=0.1, domain=(0, 0, 1, 1),
                      distance_unit='Km', seed=None):
    r"""Return a Waxman-2 random topology.

    The Waxman-2 random topology models place n nodes uniformly at random
    in a rectangular domain. Two nodes u, v are connected with a link
    with probability

    .. math::
            p = \alpha*exp(-d/(\beta*L)).

    where the distance *d* is the Euclidean distance between the nodes u and v.
    and *L* is the maximum distance between all nodes in the graph.


    Parameters
    ----------
    n : int
        Number of nodes
    alpha : float
        Model parameter chosen in *(0,1]* (higher alpha increases link density)
    beta : float
        Model parameter chosen in *(0,1]* (higher beta increases difference
        between density of short and long links)
    domain : tuple of numbers, optional
         Domain size (xmin, ymin, xmax, ymax)
    seed : int, optional
        Seed for random number generator (default=None).

    Returns
    -------
    G : Topology

    Notes
    -----
    Each edge of G has the attribute *length*

    References
    ----------
    .. [1]  B. M. Waxman, Routing of multipoint connections.
       IEEE J. Select. Areas Commun. 6(9),(1988) 1617-1622.
    """
    # validate input parameters
    if not isinstance(n, int) or n <= 0:
        raise ValueError('n must be a positive integer')
    if alpha > 1 or alpha <= 0 or beta > 1 or beta <= 0:
        raise ValueError('alpha and beta must be float values in (0,1]')
    if not isinstance(domain, tuple) or len(domain) != 4:
        raise ValueError('domain must be a tuple of 4 number')
    (xmin, ymin, xmax, ymax) = domain
    if xmin > xmax:
        raise ValueError('In domain, xmin cannot be greater than xmax')
    if  ymin > ymax:
        raise ValueError('In domain, ymin cannot be greater than ymax')
    if seed is not None:
        random.seed(seed)

    G = Topology(type='waxman_2', distance_unit=distance_unit)
    G.name = "waxman_2_topology(%s, %s, %s)" % (n, alpha, beta)
    G.add_nodes_from(range(n))


    for v in G.nodes_iter():
        G.node[v]['latitude'] = (ymin + (ymax - ymin)) * random.random()
        G.node[v]['longitude'] = (xmin + (xmax - xmin)) * random.random()

    l = {}
    nodes = G.nodes()
    while nodes:
        u = nodes.pop()
        for v in nodes:
            x_u = G.node[u]['longitude']
            x_v = G.node[v]['longitude']
            y_u = G.node[u]['latitude']
            y_v = G.node[v]['latitude']
            l[(u, v)] = math.sqrt((x_u - x_v) ** 2 + (y_u - y_v) ** 2)
    L = max(l.values())
    for (u, v), d in l.items():
        if random.random() < alpha * math.exp(-d / (beta * L)):
            G.add_edge(u, v, length=d)

    return G