计算两条折现的相似度距离过远的两条折现认为不相似入参为两个listdouble用java写
以下是Java代码实现:
import java.util.List;
public class Similarity {
public static double calculateSimilarity(List<double[]> curve1, List<double[]> curve2) {
// 获取两条折线的长度
int len1 = curve1.size();
int len2 = curve2.size();
// 如果长度相差太大,则认为不相似
if (Math.abs(len1 - len2) > Math.max(len1, len2) / 2) {
return 0.0;
}
// 构建动态规划表格,dp[i][j]表示第一条折线前i个点和第二条折线前j个点的相似度
double[][] dp = new double[len1+1][len2+1];
// 初始化第一行和第一列
for (int i = 0; i <= len1; i++) {
dp[i][0] = 0.0;
}
for (int j = 0; j <= len2; j++) {
dp[0][j] = 0.0;
}
// 填充dp表格
for (int i = 1; i <= len1; i++) {
for (int j = 1; j <= len2; j++) {
// 计算当前点对的欧几里得距离
double dist = calculateDistance(curve1.get(i-1), curve2.get(j-1));
// 根据dp转移方程计算dp[i][j]
dp[i][j] = Math.max(dp[i-1][j-1] + 1.0 / (1.0 + dist), Math.max(dp[i-1][j], dp[i][j-1]));
}
}
// 返回dp表格右下角的值
return dp[len1][len2];
}
// 计算两个点之间的欧几里得距离
private static double calculateDistance(double[] p1, double[] p2) {
double dx = p1[0] - p2[0];
double dy = p1[1] - p2[1];
return Math.sqrt(dx*dx + dy*dy);
}
}
其中,calculateSimilarity方法接收两个折线的点集,返回它们的相似度。如果两条折线长度相差大于其中一条折线长度的一半,则认为它们不相似,返回0。
接下来,我们使用动态规划的思路来计算相似度。我们定义dp[i][j]表示第一条折线前i个点和第二条折线前j个点的相似度。则最终的相似度为dp[len1][len2],其中len1和len2分别是两条折线的长度。
我们初始化dp表格的第一行和第一列为0,表示其中一条折线为空时的相似度为0。然后我们遍历两条折线,计算每个点对的欧几里得距离,并根据dp转移方程计算出dp[i][j]的值。具体来说,如果第一条折线的第i个点和第二条折线的第j个点距离小于某个阈值,则认为它们是相似的,此时dp[i][j]等于dp[i-1][j-1] + 1.0 / (1.0 + dist),其中dist是两点之间的欧几里得距离,1.0 / (1.0 + dist)是对距离的惩罚项,使得距离越近的点对贡献越大。如果两点不相似,则可以从dp[i-1][j]或dp[i][j-1]中选择一个较大的值转移而来。
最终,我们返回dp[len1][len2]作为两条折线的相似度。
注意,在实际应用中,还需要根据具体场景确定距离的阈值和惩罚项的参数
原文地址: http://www.cveoy.top/t/topic/epgu 著作权归作者所有。请勿转载和采集!