我正在尝试按照 Erzsebet Ravasz 和 Albert-Laszlo Barabasi 的论文“复杂网络中的分层组织”(2003 年)使用 NetLogo 编写分层网络。
我首先想在第二部分(分层网络模型)中构建模型,然后在第三部分(真实网络中的分层组织)中构建模型,但由于 NetLogo 中缺乏面向对象编程,我很难找到实现它的方法。
到目前为止,这是我的第二节(分层网络模型)的代码:
globals [ dist help generation-count ]
turtles-own [
center-node?
generation
model?
]
to setup
ca
set dist 1.2
crt num [
create-links-with other turtles
set shape "dot"
set size 1.5
]
let c 0
repeat (num - 1)[
ask one-of turtles with [xcor = 0 and ycor = 0][
set heading 360 / (num - 1) * c fd dist
]
set c c + 1
]
ask turtles [
ifelse ( xcor = 0 and ycor = 0 ) [ set center-node? true ][ set center-node? false ]
set color red
set generation 1
set model? true
]
set generation-count 1
; repeat x [ recreate ]
end
to recreate
set generation-count generation-count + 1
let c 0
set help count turtles
loop [
ask turtles with [ model? = true ][
hatch 1 [
set generation generation-count
repeat generation - 1 [
set heading 0
set heading (heading + 360 / (num - 1) * c)
fd generation * dist
]
set model? false
]
]
finish-member ( turtles with [ count link-neighbors = 0 ] )
set c c + 1
ask turtles with [ center-node? = false and generation = generation-count ][ create-links-with other turtles with [ center-node? = true and generation = 1 ] ]
;layout
if ( count turtles = help * num ) [ stop ]
]
end
to finish-member [ people ]
ask people [ create-links-with other people ]
end
to layout
;; the number 3 here is arbitrary; more repetitions slows down the
;; model, but too few gives poor layouts
repeat 100 [
;; Refactoring the link lengths (MODIFY DENSITY HERE?)
;; the more turtles we have to fit into the same amount of space,
;; the smaller the inputs to layout-spring we'll need to use
let factor ((sqrt count turtles) / 3) ;; Here SF-density-mod influences the distance factor across the network - will impact search function...
;; numbers here are arbitrarily chosen for pleasing appearance
layout-spring turtles links (1 / factor) (7 / factor) (1 / factor)
display ;; for smooth animation
]
;;; Centering network ;;;
;; don't bump the edges of the world
let x-offset max [xcor] of turtles + min [xcor] of turtles
let y-offset max [ycor] of turtles + min [ycor] of turtles
;; big jumps look funny, so only adjust a little each time
set x-offset limit-magnitude x-offset 0.1
set y-offset limit-magnitude y-offset 0.1
ask turtles [ setxy (xcor - x-offset / 2) (ycor - y-offset / 2) ]
end
to-report limit-magnitude [ number limit ]
if number > limit [ report limit ]
if number < (- limit) [ report (- limit) ]
report number
end
我无法像在论文中那样定位它们,所以我求助于 NetLogo“布局”程序,但后来我意识到它们的链接方式也是不正确的;外围外部节点未正确链接到外围中心节点。
附图是n = 2时的情况,这是不正确的。
我希望能够以某种方式使用递归,这样我也可以将它用于第三节(真实网络中的层次结构)。
我没有在 NetLogo 上实现它,但如果它对你或其他人将来查看这篇文章仍然有用,我上传了用于构建网络的 Python 代码:
def iter_if(n, nodo):
elementos = nodo.split("_") #Convertimos a los elementos del nodo en una lista, eliminando los "_"
elementos = [int(_) for _ in elementos] #Los convertimos a enteros
res = []
for i in range(1,n+1):
if elementos[-i] == 0:
res.append(False)
else:
res.append(True)
return all(res)
def RavaszBarabasi(n):
G = nx.Graph() #Crear una red vacía para unir las graficas ahí
if n == 0:
return nx.complete_graph(5) #Creamos el bloque base de este fractal, un K5
for i in range(5): #Creamos cuatro copias del paso anterior
H = RavaszBarabasi(n - 1)
mapping = {node: f"{i}_{node}" for node in H.nodes()} #Renombrar los nodos de H para hacerlos disjuntos
G = nx.compose(G, nx.relabel_nodes(H, mapping)) #Unimos las H_i a G con los nodos renombrados para que sean disjuntos
#Creamos esta lista pues vamos a iterar y cambiar a la vez los nodos de G, si usamos directo G, da error el for
nodes_to_connect = list(G.nodes())
for node in nodes_to_connect[1:]: #Al iniciar en 1, eliminamos el origen y evitamos comparaciones innecesarias
if n < 2:
if node[-1] != "0": #Como solo 4 de cada 5 nodos de una K5 se tienen que unir al "0_0", lo hacemos para todos menos los que terminen en 0
G.add_edge(nodes_to_connect[0], node)
else:
if iter_if(n, node) == True:
G.add_edge(nodes_to_connect[0], node)
return G
node_color = ["#b31237", "#f03813", "#ff8826", "#ffb914", "#2c9fa3"]
colorcin = [node_color[i % len(node_color)] for i in range(len(G_RB.nodes()))]
plt.figure(figsize=(10, 10))
pos = nx.spring_layout(G_RB)
nx.draw(G_RB, pos, node_size=40, node_color=colorcin, edge_color='grey')
plt.show()
注释是西班牙语的,但使用翻译应该足以澄清每一行的作用:) 希望有帮助