【问题标题】:What to use instead of ArrayList to group data?用什么代替 ArrayList 来分组数据?
【发布时间】:2020-01-04 02:39:29
【问题描述】:

我最终必须显示 K-menas 集群(集群的中心和属于集群的点)。现在我拥有 ArrayList 的中心和数据集,然后我将 ArrayLists 加入集群(也是 ArrayList)。但在这里我不知道如何为每个集群添加颜色。这意味着中心的每次迭代颜色都将保持不变,但点会根据它们所属的女巫集群改变颜色(= 女巫中心是最近的)。

我应该使用哈希图吗?关键是颜色?怎么改?

/*  n= Number of centers, int lowerBound = 0, int upperBound =1000000 */

    public static List<PointXY> randomCentri(int n, int lowerBound, int upperBound) {
      List<PointXY> centers = new ArrayList<>(n);
      for (int i = 0; i < n; i++) {
          float x = (float)(Math.random() * (upperBound - lowerBound) + lowerBound);
          float y = (float)(Math.random() * (upperBound - lowerBound) + lowerBound);
          PointXY point = new PointXY(x, y);
          centers.add(point);
      }
      return centers;
  }

// Dataset from file (.txt) (GPS coordinates)

    public static List<PointXY> podatki(String inputFile) throws Exception {
      List<PointXY> dataset = new ArrayList<>();
      BufferedReader br = new BufferedReader(new FileReader(inputFile));
      String line;

      while ((line = br.readLine()) != null) {
          String[] tokens = line.split(",");
          float x = Float.valueOf(tokens[0]);
          float y = Float.valueOf(tokens[1]);
          PointXY point = new PointXY(x, y);

              dataset.add(point);
      }
      br.close();
      return dataset;
  }

基本上这是 K-Means 算法的核心。我们首先分配一个名为 clusters 的列表列表,它使用 center.size() 空列表进行初始化。然后,对于我们数据集中的每一个数据,我们通过前面定义的getNearestPointIndex方法得到最近的中心索引,并将数据附加到最近中心的簇列表中。第三个循环,对于簇中的每个簇,我们计算平均值并将其附加到noviCentri变量中,作为我们方法的返回值。

public static List<PointXY> noviCentri(List<PointXY> dataset, List<PointXY> centers) {
  List<List<PointXY>> clusters = new ArrayList<>(centers.size());
  for (int i = 0; i < centers.size(); i++) {
      clusters.add(new ArrayList<PointXY>());
  }
  for (PointXY data : dataset) {
      int index = data.najblizjaTIndex(centers);
      clusters.get(index).add(data);
  }
  List<PointXY> noviCentri = new ArrayList<>(centers.size());
  for (List<PointXY> cluster : clusters) {
      noviCentri.add(PointXY.povprecje(cluster));
  }
  return noviCentri;
}

【问题讨论】:

    标签: java arraylist hashmap


    【解决方案1】:

    你可以:

    • 定义一个“DataSet”类。 DataSet 类的一个成员现在将成为您的点列表。另一位成员将成为颜色。
    • 或者...同时具有“DataSet”类和“ClusterCentre”类。 ClusterCentre 类有一个颜色成员(以及实际的中心点); DataSet 有一个“clusterCentre”成员,一旦确定就指向相关的 ClusterCentre 实例
    • 或者...您可以确实将 List 映射到 Color 并且不定义任何其他类。如果您这样做,请在您的特定情况下使用 IdentityHashMap:这是 Map 的特殊实现,它将特定的键对象实例(在您的情况下为列表)映射到有问题的值对象(在您的情况下为颜色)。 [稍后,了解 hashCode() 和 equals() 方法,了解这些方法是如何在标准 ArrayList 类中实现的,以及为什么标准 HashMap 对于您的特定情况不是一个好主意...]李>

    如您所见,您可以选择实施。哪个是对的”?好吧,与往常一样,这取决于您的要求:颜色映射是一次性的“一次性”使用,您只是暂时将颜色归因于列表吗?在这种情况下,使用 Map 选项可能是一个简单、足够的解决方案。还是您将其更多地视为数据集的“基本”属性,需要永久归因于它们并从方法传递到方法...无论如何,您是否需要 DataSet 和 ClusterCentre 类来添加其他属性,在这种情况下您不妨从一开始就开始创建这种“正确”的数据结构,并在以后需要时更容易扩展......

    【讨论】:

      【解决方案2】:

      集群的颜色是集群的属性,而不是数据点。你总是需要 k 颜色来表示 k 手段。因此,在一开始,为每个集群分配一种颜色:

      var color = new String[] {c1, c2, c3, ck };


      现在,继续您的 k 均值聚类,当迭代完成后,只需通过以下方式提取每个数据点的颜色:

      var pointColor = color[clusterIndex];

      【讨论】:

      猜你喜欢
      • 2021-10-29
      • 1970-01-01
      • 2019-11-28
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      • 2018-11-24
      • 2018-02-20
      相关资源
      最近更新 更多