【问题标题】:What are good alternatives to measure clusters in large square grids?在大型方形网格中测量集群的好方法是什么?
【发布时间】:2025-11-21 20:15:02
【问题描述】:

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

我用 Hoshen-Kopelman 算法尝试了 Union-Find,但我实际的 NetLogo 实现花费了大约 5 小时来获得 500 x 500 阶的补丁网格。

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

如果我不使用补丁和 Netlogo,我可以改用 C/C++ 或其他编程语言吗?

有什么建议吗?

提前致谢, 美好的一天

【问题讨论】:

  • 我们可以看看您的 NetLogo 代码吗?我认为您不需要任何算法,您应该可以使用 NetLogo 原语来做到这一点,但我不清楚您在这个问题中所说的集群是什么意思。
  • 感谢@JenB 的评论,是的,我想,我最后一次尝试是从link 中的模型创建一个模型(这正是我需要的两种颜色和大补丁世界),它基本上在其 4 个邻居中使用递归和广度搜索。不幸的是,我仍然对巨大的世界(至少 1000000 个补丁)感到复杂,因为模型需要检测大型集群,然后递归过程通知“递归太深”,感谢您的信息。问候

标签: c++ c algorithm data-structures netlogo


【解决方案1】:

我的代码基本就是这个型号Clusters with Recursion

当集群大小适中时,模型可以很好地找到集群,但是如果您的设置过程生成大型集群,那么递归会说“递归太深”并且不报告结果,现在我最初的问题可以改写,如何避免这个“递归太深”与 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

【讨论】:

    最近更新 更多