在大型方形网格中测量集群的好方法是什么?

What are good alternatives to measure clusters in large square grids?

本文关键字:方法 是什么 方形 大型 网格 测量      更新时间:2023-10-16

我在NetLogo模型的补丁环境(彩色区域)中获得群集的大小(补丁数量)列表时遇到了时间问题。对于较小的网格值(NetLogo中的世界大小),如50 x 50, 100 x 100甚至150 x 150的标准DFS的BFS变得有效,但随着订单的增加,这些程序变得不可行的。我的任务是计算相同的结果,但至少有10000 x 10000个补丁或更高的网格。

我尝试了Hoshen-Kopelman算法的Union-Find,但我实际的NetLogo实现花费了大约5个小时来处理一个订单为500 x 500的补丁网格。

有没有人知道任何算法来计算或标记至少有1000 x 1000个补丁的世界的聚类?

如果我不使用补丁和Netlogo,而改用C/c++或其他编程语言,我能得到一些改进吗?

任何建议吗?

提前感谢,美好的一天

我的代码基本上是这个模型的递归群集。

当集群具有中等大小时,模型可以很好地找到集群,但是如果您的设置过程生成了大型集群,那么递归会说"递归太深"并且不报告结果,现在我最初的问题可以重新表达,如何使用netlogo避免这种"递归太深"?

Netlogo代码:

globals [npixel caux final-participante1 final-participante2 r i j intera2 clist1 clist2 nc1 nc2]
patches-own
[
  partido influencia votoduro
  cluster  
]
to find-clusters
  loop [ 
    let seed one-of patches with [cluster = nobody] 
    if seed = nobody
    [ contarclusvar
      stop ]
    ask seed 
    [ set cluster self 
      grow-cluster ] 
  ] 
  display 
end
to setup1
  __clear-all-and-reset-ticks
ask patches [set partido 0 set influencia 0 set cluster nobody]
set npixel[]
set final-participante1 0
set final-participante2 0
set r  (L + 1)   
set-patch-size ps
resize-world 0 L 0 L
set participante2 (L + 1) * (L + 1) - participante1
set i 0
set j 0
   repeat r
  [
    repeat r
    [
    set npixel sentence npixel patch i j
    set j j + 1
    ]
    set i i + 1
    set j 0
   ]
set Caux npixel
let N r * r
repeat participante1
 [
   let z random N
   ask item z npixel [set pcolor white set partido 1 set influencia 1 set votoduro 1]
   set npixel replace-item z npixel item (N - 1 ) npixel
   set N N - 1
 ]
 repeat participante2
 [
   let z random N
   ask item z npixel [set pcolor gray set partido 2 set influencia 1 set votoduro 1]
   set npixel replace-item z npixel item (N - 1 ) npixel
   set N N - 1
 ]
;------------------- Procedure
set clist1 []
set clist2 []
let ciclos 0
let intera 0
let aux 0
let nulo 0
if participante1 + participante2 > r * r
   [stop]
let C1 participante1
let C2 participante2
repeat 75
[
  set i 0
  set j 0
  set npixel Caux
   set N r * r
   set intera 0
   set aux 0
   let aux2 (((ciclos - 1) * r * r) + intera2)              
  repeat (r * r)
 [
   let z random N 
   ask item z npixel 
   [
        let sum-inf1 sum ([influencia] of neighbors4 with [partido = 1])
        let sum-inf2 sum ([influencia] of neighbors4 with [partido = 2])

   if (sum-inf2 = sum-inf1) and (partido = 1) [ask item z npixel [set pcolor black set partido 0 set influencia 0 ] set Nulo Nulo + 1 set C1 C1 - 1 set aux aux + 1 set intera2 intera] 
   if (sum-inf2 = sum-inf1) and (partido = 2) [ask item z npixel [set pcolor black set partido 0 set influencia 0 ] set Nulo Nulo + 1 set C2 C2 - 1 set aux aux + 1 set intera2 intera]
  if ((sum-inf1 > sum-inf2) and ((partido = 2) or (partido = 0))) [
         set pcolor white set partido 1 set influencia 1
         set C1 C1 + 1 set C2 C2 - 1 set aux aux + 1 set intera2 intera
       ]
 if ((sum-inf2 > sum-inf1) and ((partido = 1) or (partido = 0))) [
       set pcolor gray set partido 2 set influencia 1
       set C2 C2 + 1 set C1 C1 - 1 set aux aux + 1 set intera2 intera
     ]
   set npixel replace-item z npixel item (N - 1 ) npixel
   set N N - 1
   set intera intera + 1
   ] 
  if (intera - aux) > (r * r) - 1  [
  stop
  ]
 ] 
] 
end
to contarclusvar
let comp []
      set comp ([cluster] of patches with [pcolor = white]) 
      set comp remove-duplicates comp 
      set nc1 length comp 
  foreach comp [ set clist1 sentence clist1 count patches with [cluster = ? and pcolor = white]
        ]
   set comp []
      set comp ([cluster] of patches with [pcolor = gray]) 
      set comp remove-duplicates comp 
      set nc2 length comp 
 foreach comp [ set clist2 sentence clist2 count patches with [cluster = ? and pcolor = gray]
      ]
end
to grow-cluster  
  ask neighbors4 with [(cluster = nobody) and (pcolor = [pcolor] of myself)]
  [ set cluster [cluster] of myself
    grow-cluster ] 
end
to show-clusters
  let counter 0
  loop [ 
    let p one-of patches with [plabel = ""] 
    if p = nobody
      [ stop ] 
    ask p
    [ ask patches with [cluster = [cluster] of myself]
      [ set plabel counter ] ]
    set counter counter + 1
  ] 
end