2010-12-01 61 views
8

Estoy tratando de generar un gráfico aleatorio que tenga propiedades de mundo pequeño (exhibe una distribución de ley de potencia). Empecé a usar el paquete networkx y descubrí que ofrece una variedad de generación de gráficos aleatorios. ¿Puede alguien decirme si es posible generar un gráfico donde el grado de un nodo dado sigue una distribución gamma (ya sea en R o usando el paquete networkx de python)?¿Generar un gráfico con cierta distribución de grados?

Respuesta

7

Si desea utilizar el modelo de configuración algo como esto debería funcionar en NetworkX:

import random 
import networkx as nx 
z=[int(random.gammavariate(alpha=9.0,beta=2.0)) for i in range(100)] 
G=nx.configuration_model(z) 

Es posible que tenga que ajustar la media de la secuencia z en función de los parámetros de la distribución gamma. También z no necesita ser gráfico (obtendrá un multigrafo), pero sí necesita una suma par, por lo que podría intentar algunas secuencias aleatorias (o agregar 1) ...

La documentación de NetworkX notas para configuration_model dar otro ejemplo, una referencia y cómo eliminar bordes paralelos y auto bucles:

Notes 
----- 
As described by Newman [1]_. 

A non-graphical degree sequence (not realizable by some simple 
graph) is allowed since this function returns graphs with self 
loops and parallel edges. An exception is raised if the degree 
sequence does not have an even sum. 

This configuration model construction process can lead to 
duplicate edges and loops. You can remove the self-loops and 
parallel edges (see below) which will likely result in a graph 
that doesn't have the exact degree sequence specified. This 
"finite-size effect" decreases as the size of the graph increases. 

References 
---------- 
.. [1] M.E.J. Newman, "The structure and function 
     of complex networks", SIAM REVIEW 45-2, pp 167-256, 2003. 

Examples 
-------- 
>>> from networkx.utils import powerlaw_sequence 
>>> z=nx.create_degree_sequence(100,powerlaw_sequence) 
>>> G=nx.configuration_model(z) 

To remove parallel edges: 

>>> G=nx.Graph(G) 

To remove self loops: 

>>> G.remove_edges_from(G.selfloop_edges()) 

Este es un ejemplo similar a la de http://networkx.lanl.gov/examples/drawing/degree_histogram.html que hace un dibujo que incluye una disposición gráfica de la componente conectado más grande:

#!/usr/bin/env python 
import random 
import matplotlib.pyplot as plt 
import networkx as nx 

def seq(n): 
    return [random.gammavariate(alpha=2.0,beta=1.0) for i in range(100)]  
z=nx.create_degree_sequence(100,seq) 
nx.is_valid_degree_sequence(z) 
G=nx.configuration_model(z) # configuration model 

degree_sequence=sorted(nx.degree(G).values(),reverse=True) # degree sequence 
print "Degree sequence", degree_sequence 
dmax=max(degree_sequence) 

plt.hist(degree_sequence,bins=dmax) 
plt.title("Degree histogram") 
plt.ylabel("count") 
plt.xlabel("degree") 

# draw graph in inset 
plt.axes([0.45,0.45,0.45,0.45]) 
Gcc=nx.connected_component_subgraphs(G)[0] 
pos=nx.spring_layout(Gcc) 
plt.axis('off') 
nx.draw_networkx_nodes(Gcc,pos,node_size=20) 
nx.draw_networkx_edges(Gcc,pos,alpha=0.4) 

plt.savefig("degree_histogram.png") 
plt.show() 
+0

@Aric: Gracias. Entiendo por qué necesita una suma parecida, pero ¿puede explicar por qué un multigraph hará? Desde mi punto de vista, multigraph permite auto-bucles y múltiples bordes de un nodo, así que estoy un poco confundido. – Legend

+0

@Aric: Puedo entender que en un multigrafo, se pueden fusionar varios bordes para formar un solo borde y se borran los bucles, pero ¿esto dará lugar a un gráfico simple? Estoy preguntando esto porque intenté establecer 'z = [3,2,2,1]' para generar un gráfico simple con estos grados, pero en cambio obtuve un gráfico con '1 2 2 1' grados. – Legend

+0

Tiene razón en que los multigrafos pueden tener bucles automáticos y bordes paralelos. – Aric

2

Lo hice hace un tiempo en la base de Python ... IIRC, utilicé el siguiente método. De memoria, por lo que este puede no ser del todo exacto, pero es de esperar vale la pena algo:

  1. Elija el número de nodos, n, en el gráfico, y la densidad (bordes existentes sobre posibles bordes), D. Esto implica el número de aristas, E.
  2. Para cada nodo, asigne su grado eligiendo primero un número aleatorio positivo xy encontrando P (x), donde P es su pdf. El grado del nodo es (P (x) * E/2) -1.
  3. Elija un nodo al azar y conéctelo a otro nodo aleatorio. Si alguno de los nodos ha realizado su grado asignado, elimínelo de una selección adicional. Repite E veces.

N.B. que esto no crea un gráfico conectado en general.

+0

Gracias por esto. Este enfoque es similar (pero no el mismo) a la creación de gráficos aleatorios, pero estaba preocupado porque para una secuencia de grados dada, no hay garantía de que podamos construir un gráfico simple. Pero en cualquier caso, gracias por su tiempo. – Legend

+0

Parece que algo similar al enfoque similar se implementa en networkx: [random_degree_sequence_graph] (https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.generators.degree_seq.random_degree_sequence_graph.html# networkx.generators.degree_seq.random_degree_sequence_graph). –

1

Sé que esto es muy tarde, pero puedes hacer lo mismo, aunque un poco más directo, con la matemática.

RandomGraph [DegreeGraphDistribution [{3, 3, 3, 3, 3, 3, 3, 3}], 4]

Esto generará 4 grafos aleatorios, con cada nodo que tiene un grado prescrito.

+1

+1 Gracias. Mantendré esto en mente. – Legend

0

Incluyendo el mencionado anteriormente, networkx proporciona 4 algoritmos que recibe el degree_distribution como una entrada:

  • configuration_model: explicar por @eric
  • expected_degree_graph: utilizar un enfoque probabilístico basado en el grado esperado de cada nodo . No le dará los grados exactos sino una aproximación.
  • havel_hakimi_graph: éste trata de conectar los nodos con el más alto grado primero
  • random_degree_sequence_graph: por lo que yo puedo ver, esto es similar a lo que sugirió @JonC; tiene un parámetro trials ya que no hay garantía de encontrar una configuración adecuada.

La lista completa (incluidas algunas versiones de los algoritmos para gráficos dirigidos) es here.

También encontré un par de papeles:

Cuestiones relacionadas