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

时间:2017-10-09 23:01:29

标签: netlogo

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

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

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

1 个答案:

答案 0 :(得分:4)

这取决于您如何定义群集间距离。有很多方法可以做到。

  

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

虽然这对于K-means聚类来说是一种很好的技术,但它对于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: https://stackoverflow.com/questions/24786908/get-mean-heading-of-neighboring-turtles
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