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
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()
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:
- 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.
- 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.
- 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.
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
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). –
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 Gracias. Mantendré esto en mente. – Legend
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:
- 1. Generar números aleatorios con distribución probabilística
- 2. C++: generar distribución gaussiana
- 3. Cómo generar un gráfico de llamadas Java
- 4. Cómo generar números con una distribución normal en SQL Server
- 5. Generar un punto aleatorio en el perímetro de un rectángulo con distribución uniforme
- 6. Mejorar el código para generar una distribución
- 7. Dibujar Gráfico de distribución normal de una muestra en Matlab
- 8. ¿Cómo usar LLVM para generar un gráfico de llamadas?
- 9. ¿Cómo generar un gráfico de impacto similar a Github?
- 10. Necesita ayuda para generar números aleatorios discretos de la distribución
- 11. Genera un gran gráfico plano aleatorio
- 12. Distribución de un contenedor
- 13. Biblioteca Java para generar el Gráfico interactivo
- 14. ¿Girando un CALayer 90 grados?
- 15. Distribución uniforme con Random
- 16. generando un número aleatorio con una distribución específica en c
- 17. Rotar un mapa de bits 90 grados
- 18. Python, SimPy: ¿Cómo generar un valor a partir de una distribución de probabilidad triangular?
- 19. ¿Cómo puedo generar eventos aleatorios discretos con una distribución de Poisson?
- 20. ¿Cómo generar cadenas de cierta longitud para insertarlas en un archivo y cumplir con los criterios de tamaño de archivo?
- 21. Generar gráfico de llamadas para el código de C++
- 22. Distribución de un ejecutable compilado con un paquete R
- 23. ¿Cómo generar un número aleatorio a partir de la distribución discreta especificada?
- 24. Convertir de Grados decimales a Grados Minutos Segundos décimas.
- 25. Decapado de un gráfico con ciclos
- 26. Símbolo de grados (como en grados Celsius/Fahrenheit) en un TextView
- 27. Implementando Django con virtualenv dentro de un paquete de distribución?
- 28. Grados de consulta de separación
- 29. ¿Cómo generar un gráfico de dependencia por clase solo para un proyecto?
- 30. ¿Cómo generar un gráfico de la dependencia entre todos los módulos de un proyecto Maven?
@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
@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
Tiene razón en que los multigrafos pueden tener bucles automáticos y bordes paralelos. – Aric