levenshtein java_1.交通聚类:编辑距离 (Levenshtein距离)Java实现

1.最近工作中要实现用户车辆的行驶路线的聚类,由于所给的数据只有用户一天中交通卡口所监视的卡口名称 :即青岛路-威海路-济阳路 。

要通过聚类实现车辆路线的规律分析,首先要解决的是相似度问题,我们知道计算相似度可以用 :空间向量距离(欧式距离,余弦相似度)等算法。可是这些在此要求中都不适应,故需要用编辑距离来解决此问题

2. 编辑距离的思想: a.是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

例如:将kitten 转成 sitting:

1.sitten (k->s)

2.sittin (e –> i)

3.sitting (-> g)

俄罗斯科学家 Vladimir Levenshtein在1965年提出的这个概念

3. 问题:找出字符串的编辑距离,即把一个字符串S1最少经过多少步操作变成字符串S2,操作有三种:添加字符,删除字符,修改一个字符。 解析:首先定义一个这样的函数—edit(i,j),它表示第一个字符串的长度为i 的子串到第二个字符串的长度为j 的子串的编辑距离。

显然有如下的动态规划公式:

1.if i == 0 且 j == 0,edit(i,j)==0

2. if  i == 0 且j >0, edit(i,j )==j

3.if i >0且 j ==0 ,edit(i,j)==i

4.if i >= 1且j>=1,edit(i,j) == min{ edit (i-1,j)+1, edit(i,j-1)+1, edit(i –1,j-1)+f(i,j)} , 当第一个字符串的第i 个字符不等于第二个字符串的第j个字符时,f(i,j) =1; 否则,f(i,j) =0.

4. 上代码: package com.dk.route;

/**

* 编辑距离,计算文本的相似度

* @author zzy

*

*/

public class LevenshteinDistance {

public static void main (String[] args){

String str1 = "东海路与燕儿岛路路口 山东路海泊桥 山东路与抚顺路路口 辽阳西路与劲松四路路口 重庆中路与振华路路口";

String str2 = "青岛东收费站 夏庄主站收费站 S217朱诸路-张应大朱戈 胶宁高架路三百惠桥上";

// String str2 = "S217朱诸路-张应大朱戈";//S217朱诸路-张应大朱戈

// String str1 = "青兰高速(双埠-管家楼)K23+800桩号增大方向";

// String str2 = "青岛路";

// String str1 = "山东";

System.out.println("ld= "+ levenshteinDistance(str1, str2));

// System.out.println("sim="+sim(str1,str2) );

}

private static int min(int one,int two,int three){

int min = one;

if (two < min){

min = two;

}

if (three

min = three;

}

return min;

}

public static int levenshteinDistance(String str1,String str2){

int d[][]; // 矩阵

int n = str1.length();

int m = str2.length();

int i ; // for str1

int j; // for str2

char ch1;

char ch2;

int temp; // 记录相同字符,在某个矩阵位置值得增量,不是0就是1;

if(n == 0){

return m;

}

if (m == 0){

return n;

}

d = new int [n+1][m+1];

for ( i = 0; i < n ; i++) { // 初始化第一列

d[i][0] = i;

}

for(j = 0; j<= m;j++){ // 初始化第一行

d[0][j] = j;

}

for (i =1; i<= n;i++){

ch1 = str1.charAt(i-1);

for(j=1;j <= m;j++){

ch2 = str2.charAt(j-1);

if(ch1 == ch2){

temp = 0;

}else{

temp =1;

}

d[i][j] = min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+temp);

}

}

return d[n][m];

}

public static double sim (Route initR,Route r){

if (initR.routename == null || r.routename == null){

return 0;

}

String str1 = initR.routename;

String str2 = r.routename;

double ld = levenshteinDistance(str1, str2);

double strMax = Math.max(str1.length(), str2.length());

double sim =1- ld/strMax;

// if(ld < strMax){

// sim = 1-ld/Math.min(str1.length(), str2.length());

// }

// System.out.println(initR.routename +"-------与-------" +r.routename +"的相似度=" + sim);

return sim;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值