Java实现LTTB抽样算法
·
package org.example;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
public class LttbUtils {
/**
* LTTB算法,用于优化抽样,入参为两个double值,第一个是时间戳,第二个是要抽样的变量值
* @param data
* @param threshold
* @return
*/
public static List<double[]> lttb(List<double[]> data, int threshold) {
// Step 1: Sort the data by x-axis (ascending order)
data.sort(Comparator.comparingDouble(a -> a[0]));
// Step 2: Divide the data into buckets
int bucketSize = (int) Math.ceil(data.size() / (double) threshold);
List<List<double[]>> buckets = new ArrayList<>(bucketSize);
for (int i = 0; i < data.size(); i += bucketSize) {
buckets.add(data.subList(i, Math.min(i + bucketSize, data.size())));
}
// Step 3: Compute the largest triangle in each bucket
List<double[]> result = new ArrayList<>(threshold);
for (List<double[]> bucket : buckets) {
if (bucket.size() < 3) {
result.addAll(bucket);
continue;
}
double areaMax = 0;
int indexMax = 0;
//增加极值
//在找到每个 bucket 中最大三角形面积时,不仅记录最大面积和对应索引,还需要记录包含该最大面积的三角形的三个点。
//将这些记录下来的三角形点加入结果集中,而不仅仅只是最大面积对应的点。
// double[] p0Max = null;
// double[] p1Max = null;
// double[] p2Max = null;
//
for (int i = 1; i < bucket.size() - 1; i++) {
double[] p0 = bucket.get(0);
double[] p1 = bucket.get(i);
double[] p2 = bucket.get(i + 1);
double area = Math.abs((p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1])) / 2.0;
if (area > areaMax) {
areaMax = area;
indexMax = i;
//增加极值
// p0Max = p0;
// p1Max = p1;
// p2Max = p2;
//
}
}
// 增加极值
// if (p0Max != null)
// result.add(p0Max);
// if (p1Max != null)
// result.add(p1Max);
// if (p2Max != null)
// result.add(p2Max);
//
result.add(bucket.get(indexMax));
}
// // Step 4: Interpolate the data points
// LinearInterpolator interpolator = new LinearInterpolator();
// PolynomialSplineFunction function = interpolator.interpolate(result.stream().mapToDouble(p -> p[0]).toArray(),
// result.stream().mapToDouble(p -> p[1]).toArray());
//
// // Step 5: Sample the interpolated function to get the final output
// List<double[]> output = new ArrayList<>(threshold);
// double step = (result.get(result.size() - 1)[0] - result.get(0)[0]) / (double) (threshold - 1);
// for (int i = 0; i < threshold; i++) {
// double x = result.get(0)[0] + i * step;
// output.add(new double[]{x, function.value(x)});
// }
// return output;
return result;
}
public static String formatTimestampToTime(double timestamp) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/M/d H:mm:ss");
Date date = new Date((long) timestamp);
return dateFormat.format(date);
}
public static double parseTimeToTimestamp(String timeString) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/M/d H:mm:ss");
try {
Date date = dateFormat.parse(timeString);
return date.getTime(); // Convert milliseconds to seconds
} catch (ParseException e) {
e.printStackTrace();
return 0; // Return 0 if parsing fails
}
}
}
更多推荐


所有评论(0)