2012-01-11 154 views
-1

我有结构列表。在结构中有字段x。我想选择那些通过参数x彼此靠近的结构。换句话说,我想通过x来聚合它们。 我想,应该有一个解决方案。 在此先感谢。从结构列表中选择项目

+0

这会不会是图中的意义,在这里如果{A,B},{B,C}和{C,d}都在附近,那么所有四送聚集在一起,即使A和d是集群不是特别密切?或者,群集中的所有成员是否应该彼此靠近? – 2012-01-11 16:58:13

+0

第一个选项。 – Kamerer 2012-01-11 17:08:58

+0

这不是“聚类”。它被称为“分组”。在SQL中:'GROUP BY'。 – 2012-01-12 09:42:49

回答

2

看那GroupBy扩展方法:

var items = mylist.GroupBy(c => c.X); 

This article给出了大量的使用group by例子。

+0

这不会聚类,它将它们分成相等的Xs – flq 2012-01-11 17:00:14

+0

好吧,他可以按X进行分组,然后迭代IGrouping,合并足够“足够”彼此的集合。 – 2012-01-11 17:03:32

4

如果我理解正确的,你想要什么,那么你可能需要通过结构的字段X

+0

是的,我可以对它们进行排序,然后两两比较它们之间的差异,但是我建议,可能有一个标准函数或类似的东西 – Kamerer 2012-01-11 17:23:28

0

排序列表如果你做图式的集群,做最简单的方法是通过建立最初为空的簇列表。然后循环输入,并为每个值查找所有至少有一个元素接近当前值的聚类。所有这些集群都应该与价值合并在一起。如果没有,那么这个值本身就会进入一个簇。

以下是一些简单的整数列表示例代码。

IEnumerable<int> input; 
int threshold; 

List<List<int>> clusters = new List<List<int>>(); 

foreach(var current in input) 
{ 
    // Search the current list of clusters for ones which contain at least one 
    // entry such that the difference between it and x is less than the threshold 
    var matchingClusters = 
     clusters.Where(
      cluster => cluster.Any(
          val => Math.Abs(current - val) <= threshold) 
     ).ToList(); 

    // Merge all the clusters that were found, plus x, into a new cluster. 
    // Replace all the existing clusters with this new one. 
    IEnumerable<int> newCluster = new List<int>(new[] { current }); 
    foreach (var match in matchingClusters) 
    { 
     clusters.Remove(match); 
     newCluster = newCluster.Concat(match); 
    } 
    clusters.Add(newCluster.ToList()); 
}