This is an automated email from the ASF dual-hosted git repository.

leirui pushed a commit to branch research/area-visualization
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 308affe76884dde28382322accec60b8ad35b6a3
Author: Lei Rui <[email protected]>
AuthorDate: Fri Jan 17 18:14:12 2025 +0800

    add
---
 .../iotdb/db/query/simpiece/Visval_standard.java   | 469 ++++++++++++---------
 .../db/query/simpiece/Visval_standard_slow.java    | 275 ++++++++++++
 2 files changed, 546 insertions(+), 198 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/simpiece/Visval_standard.java 
b/server/src/main/java/org/apache/iotdb/db/query/simpiece/Visval_standard.java
index 5471f62f65f..80aa0995809 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/query/simpiece/Visval_standard.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/simpiece/Visval_standard.java
@@ -19,233 +19,306 @@
 
 package org.apache.iotdb.db.query.simpiece;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.PriorityQueue;
-import java.util.Random;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.*;
 import java.util.stream.Collectors;
 
 // adapted from the open source C++ code
 // https://github.com/ofZach/Visvalingam-Whyatt/blob/master/src/testApp.cpp
 class Triangle {
 
-  int[] indices = new int[3];
-  double area;
-  Triangle prev;
-  Triangle next;
-
-  public Triangle(int index1, int index2, int index3, double area) {
-    this.indices[0] = index1;
-    this.indices[1] = index2;
-    this.indices[2] = index3;
-    this.area = area;
-  }
+    int[] indices = new int[3];
+    double area;
+    Triangle prev;
+    Triangle next;
+    boolean isDeleted;
+
+    public Triangle(int index1, int index2, int index3, double area) {
+        this.indices[0] = index1;
+        this.indices[1] = index2;
+        this.indices[2] = index3;
+        this.area = area;
+        this.isDeleted = false; // flag for removal. Avoid using 
heap.remove(x) as it is O(n) complexity
+    }
+
+    public Triangle(Triangle oldTri) {
+        // deep copy and inherit connection
+
+        this.indices[0] = oldTri.indices[0];
+        this.indices[1] = oldTri.indices[1];
+        this.indices[2] = oldTri.indices[2];
+        this.area = oldTri.area;
+        this.prev = oldTri.prev;
+        this.next = oldTri.next;
+
+        // TODO important! inherit connection relationship to this new point
+        if (this.prev != null) { // previous point to this new point
+            this.prev.next = this;
+        }
+        if (this.next != null) { // next point to this new point
+            this.next.prev = this;
+        }
+
+        this.isDeleted = false; // this new triangle is not deleted
+    }
+
+    public boolean isValid() {
+        return !isDeleted;
+    }
+
+    public void markDeleted() {
+        this.isDeleted = true;
+    }
 }
 
 class vPoint {
 
-  double x, y, z;
+    double x, y, z;
 
-  public vPoint(double x, double y) {
-    this.x = x;
-    this.y = y;
-    this.z = Double.POSITIVE_INFINITY; // effective area
-  }
+    public vPoint(double x, double y) {
+        this.x = x;
+        this.y = y;
+        this.z = Double.POSITIVE_INFINITY; // effective area
+    }
 }
 
 class Polyline {
 
-  private List<vPoint> vertices = new ArrayList<>();
+    private List<vPoint> vertices = new ArrayList<>();
 
-  public void addVertex(vPoint point) {
-    vertices.add(point);
-  }
+    public void addVertex(vPoint point) {
+        vertices.add(point);
+    }
 
-  public List<vPoint> getVertices() {
-    return new ArrayList<>(vertices);
-  }
+    public List<vPoint> getVertices() {
+        return new ArrayList<>(vertices);
+    }
 
-  public int size() {
-    return vertices.size();
-  }
+    public int size() {
+        return vertices.size();
+    }
 
-  public vPoint get(int index) {
-    return vertices.get(index);
-  }
+    public vPoint get(int index) {
+        return vertices.get(index);
+    }
 }
 
 public class Visval_standard {
 
-  // 计算三角形面积
-  private static double triArea(vPoint d0, vPoint d1, vPoint d2) {
-    double dArea = ((d1.x - d0.x) * (d2.y - d0.y) - (d2.x - d0.x) * (d1.y - 
d0.y)) / 2.0;
-    return (double) ((dArea > 0.0) ? dArea : -dArea); // abs
-  }
-
-  public static void buildEffectiveArea(Polyline lineToSimplify, List<vPoint> 
results) {
-    results.clear();
-    results.addAll(lineToSimplify.getVertices());
-
-    int total = lineToSimplify.size();
-    if (total < 3) {
-      return; // 不足 3 个点无法形成三角形
+    // 计算三角形面积
+    private static double triArea(vPoint d0, vPoint d1, vPoint d2) {
+        double dArea = ((d1.x - d0.x) * (d2.y - d0.y) - (d2.x - d0.x) * (d1.y 
- d0.y)) / 2.0;
+        return (double) ((dArea > 0.0) ? dArea : -dArea); // abs
     }
 
-    int nTriangles = total - 2;
-    Triangle[] triangles = new Triangle[nTriangles];
-
-    // 创建所有三角形并计算初始面积
-    for (int i = 1; i < total - 1; i++) {
-      int index1 = i - 1, index2 = i, index3 = i + 1;
-      double area =
-          triArea(
-              lineToSimplify.get(index1), lineToSimplify.get(index2), 
lineToSimplify.get(index3));
-      triangles[i - 1] = new Triangle(index1, index2, index3, area);
+    public static void buildEffectiveArea(Polyline lineToSimplify, 
List<vPoint> results) {
+        results.clear();
+        results.addAll(lineToSimplify.getVertices()); // TODO debug
+
+        int total = lineToSimplify.size();
+        if (total < 3) {
+            return; // 不足 3 个点无法形成三角形
+        }
+
+        int nTriangles = total - 2;
+        Triangle[] triangles = new Triangle[nTriangles];
+
+        // 创建所有三角形并计算初始面积
+        for (int i = 1; i < total - 1; i++) {
+            int index1 = i - 1, index2 = i, index3 = i + 1;
+            double area =
+                    triArea(
+                            lineToSimplify.get(index1), 
lineToSimplify.get(index2), lineToSimplify.get(index3));
+            triangles[i - 1] = new Triangle(index1, index2, index3, area);
+        }
+
+        // 设置三角形的前后关系
+        for (int i = 0; i < nTriangles; i++) { // TODO 这个可以和上一个循环合并吗??好像不可以
+            triangles[i].prev = (i == 0 ? null : triangles[i - 1]);
+            triangles[i].next = (i == nTriangles - 1 ? null : triangles[i + 
1]);
+        }
+
+        // 使用优先队列构建 minHeap
+        PriorityQueue<Triangle> triangleHeap =
+                new PriorityQueue<>(Comparator.comparingDouble(t -> t.area));
+        Collections.addAll(triangleHeap, triangles); // complexity TODO
+
+        double previousEA = -1;
+        while (!triangleHeap.isEmpty()) {
+            // 注意peek只需要直接访问该位置的元素,不涉及任何重排或堆化操作
+            // 而poll是删除堆顶元素,需要重新堆化以维护堆的性质,复杂度是O(logk),k是当前堆的大小
+            Triangle tri = triangleHeap.poll(); // O(logn)
+
+            // 如果该三角形已经被删除,跳过. Avoid using heap.remove(x) as it is O(n) 
complexity
+            // 而且除了heap里,已经没有其他节点会和它关联了,所有的connections关系已经迁移到新的角色替代节点上
+            if (tri.isDeleted) {
+                continue;
+            }
+
+            // 更新当前点的重要性(z 轴存储effective area,这是一个单调增的指标)
+            if (tri.area > previousEA) {
+                previousEA = tri.area;
+            }
+            results.get(tri.indices[1]).z = previousEA;
+            //      System.out.println(tri.indices[1] + "," + previousEA);
+
+            // 更新相邻三角形
+            if (tri.prev != null) {
+                // 1. 处理旧的tri.prev被标记删除的事情(角色替代)
+                // triangleHeap.remove(tri.prev); // Avoid using 
heap.remove(x) as it is O(n) complexity!
+                tri.prev.markDeleted(); // O(1) 
这个点标记为废掉,前后关联都砍断,但是不remove因为那太耗时,只有poll到它就跳过就可以
+
+                Triangle newPre = new Triangle(tri.prev); // deep copy and 
inherit connection
+                tri.prev = newPre; // replace
+
+                // 2. 处理pi被淘汰引起tri.prev被更新的事情
+                // 前一个三角形连到后一个三角形
+                tri.prev.next = tri.next; // ATTENTION!!!: 
这里的tri.next后面可能会因为处理旧的tri.next被标记删除的事情被换掉!到时候要重新赋值!
+                tri.prev.indices[2] = tri.indices[2];
+                tri.prev.area =
+                        triArea(
+                                lineToSimplify.get(tri.prev.indices[0]),
+                                lineToSimplify.get(tri.prev.indices[1]),
+                                lineToSimplify.get(tri.prev.indices[2]));
+
+                // 重新加入堆
+                // 在 Java 的 PriorityQueue 中,修改元素的属性不会自动更新堆的顺序
+                // 所以必须通过add 来显式重新插入修改后的元素
+                triangleHeap.add(tri.prev); // O(logn) 
注意加入的是一个新的对象isDeleted=false
+            }
+
+            if (tri.next != null) {
+                // 1. 处理旧的tri.next被标记删除的事情(角色替代)
+                // triangleHeap.remove(tri.next); // Avoid using 
heap.remove(x) as it is O(n) complexity
+                tri.next.markDeleted(); // O(1) 
这个点标记为废掉,前后关联都砍断,但是不remove因为那太耗时,只有poll到它就跳过就可以
+
+                Triangle newNext = new Triangle(tri.next); // deep copy and 
inherit connection
+                tri.next = newNext; // replace
+
+                if (tri.prev != null) {
+                    tri.prev.next = tri.next; // ATTENTION!!!: 
这里的tri.next已经被换掉!所以之前的要重新赋值!
+                }
+
+                // 2. 处理pi被淘汰引起tri.next被更新的事情
+                tri.next.prev = tri.prev; // 
注意此时tri.prev已经是替代后的节点,tri.next也是,从而被标记为废点的前后关联真正砍断
+                tri.next.indices[0] = tri.indices[0];
+                tri.next.area =
+                        triArea(
+                                lineToSimplify.get(tri.next.indices[0]),
+                                lineToSimplify.get(tri.next.indices[1]),
+                                lineToSimplify.get(tri.next.indices[2]));
+
+                // 重新加入堆
+                // 在 Java 的 PriorityQueue 中,修改元素的属性不会自动更新堆的顺序
+                // 所以必须通过add 来显式重新插入修改后的元素
+                triangleHeap.add(tri.next); // 注意加入的是一个新的对象isDeleted=false
+            }
+        }
     }
 
-    // 设置三角形的前后关系
-    for (int i = 0; i < nTriangles; i++) {
-      triangles[i].prev = (i == 0 ? null : triangles[i - 1]);
-      triangles[i].next = (i == nTriangles - 1 ? null : triangles[i + 1]);
+    public static void main(String[] args) {
+        Polyline polyline = new Polyline();
+        List<Polyline> polylineList = new ArrayList<>();
+        Random rand = new Random(1);
+        int n = 10000; //1000_000;
+
+        int p = 100;
+        for (int i = 0; i < n; i += p) {
+            Polyline polylineBatch = new Polyline();
+            for (int j = i; j < Math.min(i + p, n); j++) {
+                double v = rand.nextInt(1000);
+
+                polyline.addVertex(new vPoint(j, v));
+
+                polylineBatch.addVertex(new vPoint(j, v));
+            }
+            polylineList.add(polylineBatch);
+        }
+
+        System.out.println("---------------------------------");
+        List<vPoint> results = new ArrayList<>();
+        // 计算运行时间
+        long startTime = System.currentTimeMillis();
+        buildEffectiveArea(polyline, results);
+        // 输出结果
+        long endTime = System.currentTimeMillis();
+        System.out.println("Time taken to reduce points: " + (endTime - 
startTime) + "ms");
+        System.out.println(results.size());
+
+        if (results.size() <= 100) {
+            System.out.println("+++++++++++++++++++");
+            for (int i = 0; i < results.size(); i++) {
+                vPoint point = results.get(i);
+                System.out.println("Point: (" + point.x + ", " + point.y + ", 
" + point.z + ")");
+            }
+        }
+
+        try (FileWriter writer = new FileWriter("fast.csv")) {
+            // 写入CSV头部
+            writer.append("x,y,z\n");
+
+            // 写入每个点的数据
+            for (int i = 0; i < results.size(); i++) {
+                vPoint point = results.get(i);
+                writer.append(point.x + "," + point.y + "," + point.z + "\n");
+            }
+            System.out.println("Data has been written");
+        } catch (IOException e) {
+            System.out.println("Error writing to CSV file: " + e.getMessage());
+        }
+
+        System.out.println("---------------------------------");
+        List<List<vPoint>> resultsBatchList = new ArrayList<>();
+        // 计算运行时间
+        int cnt = 0;
+        startTime = System.currentTimeMillis();
+        for (Polyline polylineBatch : polylineList) {
+            List<vPoint> resultsBatch = new ArrayList<>();
+            buildEffectiveArea(polylineBatch, resultsBatch);
+            cnt += resultsBatch.size();
+            resultsBatchList.add(resultsBatch);
+        }
+        // 输出结果
+        endTime = System.currentTimeMillis();
+        System.out.println("Time taken to reduce points: " + (endTime - 
startTime) + "ms");
+        System.out.println(cnt);
+
+        System.out.println("---------------------------------");
+        // 使用 Stream API 合并所有列表
+        List<vPoint> mergedList =
+                
resultsBatchList.stream().flatMap(List::stream).collect(Collectors.toList());
+        int sameCnt = 0;
+        for (int i = 0; i < mergedList.size(); i++) {
+            if (mergedList.get(i).z == results.get(i).z) {
+                sameCnt += 1;
+            }
+        }
+        System.out.println("sameCnt=" + sameCnt + ", percent=" + sameCnt * 1.0 
/ mergedList.size());
     }
 
-    // 使用优先队列构建 minHeap
-    PriorityQueue<Triangle> triangleHeap =
-        new PriorityQueue<>(Comparator.comparingDouble(t -> t.area));
-    Collections.addAll(triangleHeap, triangles);
-
-    double previousEA = -1;
-    while (!triangleHeap.isEmpty()) {
-      // 注意peek只需要直接访问该位置的元素,不涉及任何重排或堆化操作
-      // 而poll是删除堆顶元素,需要重新堆化以维护堆的性质,复杂度是O(logk),k是当前堆的大小
-      Triangle tri = triangleHeap.poll();
-
-      // 更新当前点的重要性(z 轴存储effective area,这是一个单调增的指标)
-      if (tri.area > previousEA) {
-        previousEA = tri.area;
-      }
-      results.get(tri.indices[1]).z = previousEA;
-      //      System.out.println(tri.indices[1] + "," + previousEA);
-
-      // 更新相邻三角形
-      if (tri.prev != null) {
-        // 前一个三角形连到后一个三角形
-        tri.prev.next = tri.next;
-        tri.prev.indices[2] = tri.indices[2];
-        tri.prev.area =
-            triArea(
-                lineToSimplify.get(tri.prev.indices[0]),
-                lineToSimplify.get(tri.prev.indices[1]),
-                lineToSimplify.get(tri.prev.indices[2]));
-
-        // 重新加入堆
-        // 在 Java 的 PriorityQueue 中,修改元素的属性不会自动更新堆的顺序
-        // 所以必须通过 remove 和 add 来显式重新插入修改后的元素
-        triangleHeap.remove(tri.prev);
-        triangleHeap.add(tri.prev);
-      }
-
-      if (tri.next != null) {
-        // 后一个三角形连到前一个三角形
-        tri.next.prev = tri.prev;
-        tri.next.indices[0] = tri.indices[0];
-        tri.next.area =
-            triArea(
-                lineToSimplify.get(tri.next.indices[0]),
-                lineToSimplify.get(tri.next.indices[1]),
-                lineToSimplify.get(tri.next.indices[2]));
-
-        // 重新加入堆
-        triangleHeap.remove(tri.next);
-        triangleHeap.add(tri.next);
-      }
-    }
-  }
-
-  public static void main(String[] args) {
-    Polyline polyline = new Polyline();
-    List<Polyline> polylineList = new ArrayList<>();
-    Random rand = new Random();
-    int n = 1000_000;
-    int p = 10;
-    for (int i = 0; i < n; i += p) {
-      Polyline polylineBatch = new Polyline();
-      for (int j = i; j < Math.min(i + p, n); j++) {
-        double v = rand.nextInt(1000);
-        polyline.addVertex(new vPoint(j, v));
-        polylineBatch.addVertex(new vPoint(j, v));
-      }
-      polylineList.add(polylineBatch);
-    }
-
-    System.out.println("---------------------------------");
-    List<vPoint> results = new ArrayList<>();
-    // 计算运行时间
-    long startTime = System.currentTimeMillis();
-    buildEffectiveArea(polyline, results);
-    // 输出结果
-    long endTime = System.currentTimeMillis();
-    System.out.println("Time taken to reduce points: " + (endTime - startTime) 
+ "ms");
-    System.out.println(results.size());
-
-    //    for (int i = 0; i < results.size(); i++) {
-    //      vPoint point = results.get(i);
-    //      System.out.println("Point: (" + point.x + ", " + point.y + ", " + 
point.z + ")");
+    //    float[] vlist = new float[]{11346, 33839, 35469, 23108, 22812, 5519, 
5526, 4865, 5842,
+    // 23089};
+    //    for (int i = 0; i < vlist.length; i++) {
+    //      polyline.addVertex(new vPoint(i, vlist[i]));
     //    }
 
-    System.out.println("---------------------------------");
-    List<List<vPoint>> resultsBatchList = new ArrayList<>();
-    // 计算运行时间
-    int cnt = 0;
-    startTime = System.currentTimeMillis();
-    for (Polyline polylineBatch : polylineList) {
-      List<vPoint> resultsBatch = new ArrayList<>();
-      buildEffectiveArea(polylineBatch, resultsBatch);
-      cnt += resultsBatch.size();
-      resultsBatchList.add(resultsBatch);
-    }
-    // 输出结果
-    endTime = System.currentTimeMillis();
-    System.out.println("Time taken to reduce points: " + (endTime - startTime) 
+ "ms");
-    System.out.println(cnt);
-
-    System.out.println("---------------------------------");
-    // 使用 Stream API 合并所有列表
-    List<vPoint> mergedList =
-        
resultsBatchList.stream().flatMap(List::stream).collect(Collectors.toList());
-    int sameCnt = 0;
-    for (int i = 0; i < mergedList.size(); i++) {
-      if (mergedList.get(i).z == results.get(i).z) {
-        sameCnt += 1;
-      }
-    }
-    System.out.println("sameCnt=" + sameCnt + ", percent=" + sameCnt * 1.0 / 
mergedList.size());
-  }
-
-  //    float[] vlist = new float[]{11346, 33839, 35469, 23108, 22812, 5519, 
5526, 4865, 5842,
-  // 23089};
-  //    for (int i = 0; i < vlist.length; i++) {
-  //      polyline.addVertex(new vPoint(i, vlist[i]));
-  //    }
-
-  //    ArrayList<Double> v = new ArrayList<>();
-  //    String filePath = "D://desktop//数据集//New York Stock 
Exchange//merged_prices.csv";
-  //    try (BufferedReader br = new BufferedReader(new FileReader(filePath))) 
{
-  //      String line;
-  //      int count = 0;
-  //      while ((line = br.readLine()) != null && count < 1000) {
-  //        String[] columns = line.split(","); // 假设 CSV 文件以逗号分隔
-  //        v.add(Double.parseDouble(columns[0])); // 读取第一列数据
-  //        count++;
-  //      }
-  //    } catch (Exception e) {
-  //      e.printStackTrace();
-  //    }
-  //    // 打印数据长度
-  //    System.out.println("Data length: " + v.size());
-  //    for (int i = 0; i < v.size(); i++) {
-  //      polyline.addVertex(new vPoint(i, v.get(i)));
-  //    }
+    //    ArrayList<Double> v = new ArrayList<>();
+    //    String filePath = "D://desktop//数据集//New York Stock 
Exchange//merged_prices.csv";
+    //    try (BufferedReader br = new BufferedReader(new 
FileReader(filePath))) {
+    //      String line;
+    //      int count = 0;
+    //      while ((line = br.readLine()) != null && count < 1000) {
+    //        String[] columns = line.split(","); // 假设 CSV 文件以逗号分隔
+    //        v.add(Double.parseDouble(columns[0])); // 读取第一列数据
+    //        count++;
+    //      }
+    //    } catch (Exception e) {
+    //      e.printStackTrace();
+    //    }
+    //    // 打印数据长度
+    //    System.out.println("Data length: " + v.size());
+    //    for (int i = 0; i < v.size(); i++) {
+    //      polyline.addVertex(new vPoint(i, v.get(i)));
+    //    }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/query/simpiece/Visval_standard_slow.java
 
b/server/src/main/java/org/apache/iotdb/db/query/simpiece/Visval_standard_slow.java
new file mode 100644
index 00000000000..929fa304568
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/query/simpiece/Visval_standard_slow.java
@@ -0,0 +1,275 @@
+///*
+// * Licensed to the Apache Software Foundation (ASF) under one
+// * or more contributor license agreements.  See the NOTICE file
+// * distributed with this work for additional information
+// * regarding copyright ownership.  The ASF licenses this file
+// * to you under the Apache License, Version 2.0 (the
+// * "License"); you may not use this file except in compliance
+// * with the License.  You may obtain a copy of the License at
+// *
+// *     http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing,
+// * software distributed under the License is distributed on an
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// * KIND, either express or implied.  See the License for the
+// * specific language governing permissions and limitations
+// * under the License.
+// */
+//
+//package org.apache.iotdb.db.query.simpiece;
+//
+//import java.io.FileWriter;
+//import java.io.IOException;
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+//// adapted from the open source C++ code
+//// https://github.com/ofZach/Visvalingam-Whyatt/blob/master/src/testApp.cpp
+//class Triangle {
+//
+//    int[] indices = new int[3];
+//    double area;
+//    Triangle prev;
+//    Triangle next;
+//
+//    public Triangle(int index1, int index2, int index3, double area) {
+//        this.indices[0] = index1;
+//        this.indices[1] = index2;
+//        this.indices[2] = index3;
+//        this.area = area;
+//    }
+//}
+//
+//class vPoint {
+//
+//    double x, y, z;
+//
+//    public vPoint(double x, double y) {
+//        this.x = x;
+//        this.y = y;
+//        this.z = Double.POSITIVE_INFINITY; // effective area
+//    }
+//}
+//
+//class Polyline {
+//
+//    private List<vPoint> vertices = new ArrayList<>();
+//
+//    public void addVertex(vPoint point) {
+//        vertices.add(point);
+//    }
+//
+//    public List<vPoint> getVertices() {
+//        return new ArrayList<>(vertices);
+//    }
+//
+//    public int size() {
+//        return vertices.size();
+//    }
+//
+//    public vPoint get(int index) {
+//        return vertices.get(index);
+//    }
+//}
+//
+//public class Visval_standard_slow {
+//
+//    // 计算三角形面积
+//    private static double triArea(vPoint d0, vPoint d1, vPoint d2) {
+//        double dArea = ((d1.x - d0.x) * (d2.y - d0.y) - (d2.x - d0.x) * 
(d1.y - d0.y)) / 2.0;
+//        return (double) ((dArea > 0.0) ? dArea : -dArea); // abs
+//    }
+//
+//    public static void buildEffectiveArea(Polyline lineToSimplify, 
List<vPoint> results) {
+//        results.clear();
+//        results.addAll(lineToSimplify.getVertices());
+//
+//        int total = lineToSimplify.size();
+//        if (total < 3) {
+//            return; // 不足 3 个点无法形成三角形
+//        }
+//
+//        int nTriangles = total - 2;
+//        Triangle[] triangles = new Triangle[nTriangles];
+//
+//        // 创建所有三角形并计算初始面积
+//        for (int i = 1; i < total - 1; i++) {
+//            int index1 = i - 1, index2 = i, index3 = i + 1;
+//            double area =
+//                    triArea(
+//                            lineToSimplify.get(index1), 
lineToSimplify.get(index2), lineToSimplify.get(index3));
+//            triangles[i - 1] = new Triangle(index1, index2, index3, area);
+//        }
+//
+//        // 设置三角形的前后关系
+//        for (int i = 0; i < nTriangles; i++) {
+//            triangles[i].prev = (i == 0 ? null : triangles[i - 1]);
+//            triangles[i].next = (i == nTriangles - 1 ? null : triangles[i + 
1]);
+//        }
+//
+//        // 使用优先队列构建 minHeap
+//        PriorityQueue<Triangle> triangleHeap =
+//                new PriorityQueue<>(Comparator.comparingDouble(t -> t.area));
+//        Collections.addAll(triangleHeap, triangles);
+//
+//        double previousEA = -1;
+//        while (!triangleHeap.isEmpty()) {
+//            // 注意peek只需要直接访问该位置的元素,不涉及任何重排或堆化操作
+//            // 而poll是删除堆顶元素,需要重新堆化以维护堆的性质,复杂度是O(logk),k是当前堆的大小
+//            Triangle tri = triangleHeap.poll(); // O(logn)
+//
+//            // 更新当前点的重要性(z 轴存储effective area,这是一个单调增的指标)
+//            if (tri.area > previousEA) {
+//                previousEA = tri.area;
+//            }
+//            results.get(tri.indices[1]).z = previousEA;
+//            //      System.out.println(tri.indices[1] + "," + previousEA);
+//
+//            // 更新相邻三角形
+//            if (tri.prev != null) {
+//                // 前一个三角形连到后一个三角形
+//                tri.prev.next = tri.next;
+//                tri.prev.indices[2] = tri.indices[2];
+//                tri.prev.area =
+//                        triArea(
+//                                lineToSimplify.get(tri.prev.indices[0]),
+//                                lineToSimplify.get(tri.prev.indices[1]),
+//                                lineToSimplify.get(tri.prev.indices[2]));
+//
+//                // 重新加入堆
+//                // 在 Java 的 PriorityQueue 中,修改元素的属性不会自动更新堆的顺序
+//                // 所以必须通过 remove 和 add 来显式重新插入修改后的元素
+//                triangleHeap.remove(tri.prev); // TODO 但是这个操作复杂度是O(n)!!!!
+//                triangleHeap.add(tri.prev);  // O(logn)
+//            }
+//
+//            if (tri.next != null) {
+//                // 后一个三角形连到前一个三角形
+//                tri.next.prev = tri.prev;
+//                tri.next.indices[0] = tri.indices[0];
+//                tri.next.area =
+//                        triArea(
+//                                lineToSimplify.get(tri.next.indices[0]),
+//                                lineToSimplify.get(tri.next.indices[1]),
+//                                lineToSimplify.get(tri.next.indices[2]));
+//
+//                // 重新加入堆
+//                triangleHeap.remove(tri.next);
+//                triangleHeap.add(tri.next);
+//            }
+//        }
+//    }
+//
+//    public static void main(String[] args) {
+//        Polyline polyline = new Polyline();
+//        List<Polyline> polylineList = new ArrayList<>();
+//        Random rand = new Random(1);
+////        int n = 1000_000;
+//        int n = 10000;
+//
+//        int p = 100;
+//        for (int i = 0; i < n; i += p) {
+//            Polyline polylineBatch = new Polyline();
+//            for (int j = i; j < Math.min(i + p, n); j++) {
+//                double v = rand.nextInt(1000);
+//
+//                polyline.addVertex(new vPoint(j, v));
+//
+//                polylineBatch.addVertex(new vPoint(j, v));
+//            }
+//            polylineList.add(polylineBatch);
+//        }
+//
+//        System.out.println("---------------------------------");
+//        List<vPoint> results = new ArrayList<>();
+//        // 计算运行时间
+//        long startTime = System.currentTimeMillis();
+//        buildEffectiveArea(polyline, results);
+//        // 输出结果
+//        long endTime = System.currentTimeMillis();
+//        System.out.println("Time taken to reduce points: " + (endTime - 
startTime) + "ms");
+//        System.out.println(results.size());
+//
+//        if (results.size() <= 100) {
+//            System.out.println("+++++++++++++++++++");
+//            for (int i = 0; i < results.size(); i++) {
+//                vPoint point = results.get(i);
+//                System.out.println("Point: (" + point.x + ", " + point.y + 
", " + point.z + ")");
+//            }
+//        }
+//
+//        try (FileWriter writer = new FileWriter("slow.csv")) {
+//            // 写入CSV头部
+//            writer.append("x,y,z\n");
+//
+//            // 写入每个点的数据
+//            for (int i = 0; i < results.size(); i++) {
+//                vPoint point = results.get(i);
+//                writer.append(point.x + "," + point.y + "," + point.z + 
"\n");
+//            }
+//            System.out.println("Data has been written");
+//        } catch (IOException e) {
+//            System.out.println("Error writing to CSV file: " + 
e.getMessage());
+//        }
+//
+//        System.out.println("---------------------------------");
+//        List<List<vPoint>> resultsBatchList = new ArrayList<>();
+//        // 计算运行时间
+//        int cnt = 0;
+//        startTime = System.currentTimeMillis();
+//        for (Polyline polylineBatch : polylineList) {
+//            List<vPoint> resultsBatch = new ArrayList<>();
+//            buildEffectiveArea(polylineBatch, resultsBatch);
+//            cnt += resultsBatch.size();
+//            resultsBatchList.add(resultsBatch);
+//        }
+//        // 输出结果
+//        endTime = System.currentTimeMillis();
+//        System.out.println("Time taken to reduce points: " + (endTime - 
startTime) + "ms");
+//        System.out.println(cnt);
+//
+//        System.out.println("---------------------------------");
+//        // 使用 Stream API 合并所有列表
+//        List<vPoint> mergedList =
+//                
resultsBatchList.stream().flatMap(List::stream).collect(Collectors.toList());
+//        int sameCnt = 0;
+//        for (int i = 0; i < mergedList.size(); i++) {
+//            if (mergedList.get(i).z == results.get(i).z) {
+//                sameCnt += 1;
+//            }
+//        }
+//        System.out.println("sameCnt=" + sameCnt + ", percent=" + sameCnt * 
1.0 / mergedList.size());
+//
+//
+//
+//
+//
+//
+//
+////        float[] vlist = new float[]{11346, 33839, 35469, 23108, 22812, 
5519, 5526, 4865, 5842,
+////                23089};
+////        for (int i = 0; i < vlist.length; i++) {
+////            polyline.addVertex(new vPoint(i, vlist[i]));
+////        }
+////
+////        ArrayList<Double> v = new ArrayList<>();
+////        String filePath = "D://datasets//regular//New York Stock 
Exchange//merged_prices.csv";
+////        try (BufferedReader br = new BufferedReader(new 
FileReader(filePath))) {
+////            String line;
+////            int count = 0;
+////            while ((line = br.readLine()) != null && count < 1000) {
+////                String[] columns = line.split(","); // 假设 CSV 文件以逗号分隔
+////                v.add(Double.parseDouble(columns[0])); // 读取第一列数据
+////                count++;
+////            }
+////        } catch (Exception e) {
+////            e.printStackTrace();
+////        }
+////        // 打印数据长度
+////        System.out.println("Data length: " + v.size());
+////        for (int i = 0; i < v.size(); i++) {
+////            polyline.addVertex(new vPoint(i, v.get(i)));
+////        }
+//    }
+//}

Reply via email to