在 netlogo 中使用 dbscan 确定簇间距离

Determining the Inter-cluster distance using dbscan in netlogo

假设您有以下代码(由@Nicolas-Payette 提供),您将如何使用 netlog 中的 dbscan 查找平均集群间距离:

extensions [ dbscan ]

to setup
  clear-all
  ask patches [ set pcolor white ]
  create-turtles 1000 [
    set color black
    set label-color blue
    setxy random-xcor random-ycor
  ]
  ask n-of 5 turtles [
    ask turtles in-radius 3 [
      set color one-of [red grey]
    ]
  ]
end

to find-clusters
  let red-grey-turtles turtles with [ member? color [red grey] ]
  let clusters dbscan:cluster-by-location red-grey-turtles 3 3
  (foreach clusters range length clusters [ [c i] ->
    foreach c [ t ->
      ask t [ set label i ]
    ]
  ])
end

让我们将被测距离的端点作为海龟群的中心。

这取决于您如何定义簇间距离。有多种方法可以做到这一点。

Let us take a the endpoints of the distances being measured to be the centers of the clusters of turtles.

虽然这对于 K 均值聚类来说是一种很好的技术,但对于 DBSCAN 来说效果不佳,因为聚类可能是凹的。因此,中心可能在集群之外!无论如何,我会作为一个选项包括在内。

首先,让我们定义距离度量:

簇中点之间的平均距离:

to-report cluster-distance [ cluster1 cluster2 ]
  report mean [ mean [ distance myself ] of cluster2 ] of cluster1
end

簇中点之间的最小距离:

to-report cluster-distance [ cluster1 cluster2 ]
  report min [ min [ distance myself ] of cluster2 ] of cluster1
end

质心之间的距离

假设世界环绕关闭:

to-report cluster-distance [ cluster1 cluster2 ]
  let x1 mean [ xcor ] of cluster1
  let y1 mean [ ycor ] of cluster1
  let x2 mean [ xcor ] of cluster2
  let y2 mean [ ycor ] of cluster2
  report sqrt ((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
end

如果世界环绕开启

; This is super complicated because, with wrapping on, xcor and ycor are
; more like angles rather than cartesian coordinates. So, this converts
; them to angles, gets the mean of those angles, and converts them back.
; Related SO question: 
to-report xcor-mean [ xcors ]
  let angles map [ x -> 360 * (x - (min-pxcor - 0.5)) / world-width ] xcors
  let mean-x mean map cos angles
  let mean-y mean map sin angles
  report (atan mean-y mean-x) / 360 * world-width + (min-pxcor - 0.5)
end

to-report ycor-mean [ ycors ]
  let angles map [ y -> 360 * (y - (min-pycor - 0.5)) / world-height ] ycors
  let mean-x mean map cos angles
  let mean-y mean map sin angles
  report (atan mean-y mean-x) / 360 * world-height + (min-pycor - 0.5)
end

to-report cluster-distance [ cluster1 cluster2 ]
  let x1 xcor-mean [ xcor ] of cluster1
  let y1 ycor-mean [ ycor ] of cluster1
  let x2 xcor-mean [ xcor ] of cluster2
  let y2 ycor-mean [ ycor ] of cluster2
  report sqrt ((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
end

平均距离

一旦我们有了距离度量,使用 map 获得平均距离就相对简单了。请注意,下面的 remove 是必需的,因为我们不想在均值中包括集群到自身的距离。另请注意,这段代码效率有点低,因为它计算了所有距离两次,但这也大大简化了它:

...
; This line is modified so that we get a list of turtle sets rather than
; a list of lists. 
let clusters map turtle-set dbscan:cluster-by-location red-grey-turtles 3 3
let avg-distance mean map [ c1 ->
  mean map [ c2 ->
    cluster-distance c1 c2
  ] remove c1 clusters ; Get distance to all other clusters but c1
] clusters