【Data Structure/Algorithm】LCSS算法实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wk1134314305/article/details/78892155

最近在写一个关于路网处理的小论文,在写作中碰到一个问题就是,高德路网数据有很大一部分的道路没有路名。因此笔者想着利用OSM上的路网作为补充,看能不能进行数据的补充。

整理思路如下:

  1. 首先对高德路网和OSM的路网整体进行R树索引的建立
  2. 对高德路网中的没有道路名称的道路,求解其MBR,然后进行R树查询查找到与其相交的OSM路网的道路。
  3. 遍历上面求交后的结果,利用LCSS算法,求出匹配的道路。

文中的R树建立请参考笔者的另外一篇博客:
【JTS】利用JTS生成R树索引

本文中关键的一个步骤就是LCSS算法的实现,本文参考了论文Discovering Similar Multidimensional Trajectories

另外笔者极力推荐一篇讲解LCS算法的博客:
程序员编程艺术第十一章:最长公共子序列(LCS)问题

关键代码:

package com.kingwang.algorithms;

import com.vividsolutions.jts.geom.Coordinate;

public class TrajectoryLCSS {
    private Coordinate[] L1;
    private Coordinate[] L2;
    private Coordinate[] LCS;
    private double distThre;
    private double matchRatio;
    private static final double DEFAULT_DISTTHRE=0.0005;//经纬度差值阈值大约0.001在地图上相差80-90米
    private int commonLen;

    public TrajectoryLCSS(Coordinate[] L1,Coordinate[] L2) {
        this.L1=L1;
        this.L2=L2;
        this.distThre=DEFAULT_DISTTHRE;
    }
    /**
     * @param L1
     * @param L2
     * @param dist_thre
     */
    public TrajectoryLCSS(Coordinate[] L1,Coordinate[] L2,double dist_thre) {
        this(L1, L2);
        this.distThre=dist_thre;
    }
    /**
     * 动态规划计算所有子问题
     * @return
     */
    public int[][] getTypeMatrix(){
        int[][] type=new int[L1.length+1][L2.length+1];
        for(int i=L1.length-1;i>=0;i--) {
            for(int j=L2.length-1;j>=0;j--) {
                if(isClose(L1[i],L2[j])){
                    System.out.println(L1[i]);
                    System.out.println(L2[j]);
                    type[i][j]=type[i+1][j+1]+1;
                    commonLen++;
                }else {
                    type[i][j]=Math.max(type[i][j+1], type[i+1][j]);
                }
            }
        }
        return type;
    }
    /**
     * 查看两点是否可以判定为同点
     * @param p1
     * @param p2
     * @return
     */
    public boolean isClose(Coordinate p1,Coordinate p2) {
        double x_abs=Math.abs(p1.x-p2.x);
        double y_abs=Math.abs(p1.y-p2.y);
        if(x_abs<distThre&&y_abs<distThre)
            return true;
        return false;
    }
    /**
     * @return
     */
    public Coordinate[] genLCSS() {
        int[][] typematrix=getTypeMatrix();
        Coordinate[] res = new Coordinate[commonLen];
        int i=0,j=0;
        int index=0;
        while(i<L1.length&&j<L2.length) {
            if(isClose(L1[i],L2[j])) {
                System.out.println(index);
                System.out.println(i);
                System.out.println(commonLen);
                System.out.println(L1[i]);
                System.out.println(L2[j]);
                res[index++]=L1[i];
                i++;
                j++;
            }else if(typematrix[i+1][j]>=typematrix[i][j+1]) {
                i++;
            }else {
                j++;
            }
        }
        LCS=res;
        matchRatio=this.LCS.length/(double)(Math.min(L1.length,L2.length));
        return res;
    }
    /**
     * 更新Ratio
     * @return
     */
    public double getMatchRatio() {
        if(matchRatio==0) {
            genLCSS();
        }
        return this.LCS.length/(double)(Math.min(L1.length,L2.length));
    }

    public static void main(String[] args) {
        Coordinate[] coor1=new Coordinate[5];
        coor1[0]=new Coordinate(114.300, 30.1);
        coor1[1]=new Coordinate(114.302, 30.101);
        coor1[2]=new Coordinate(114.3023, 30.1002);
        coor1[3]=new Coordinate(114.30235, 30.1011);
        coor1[4]=new Coordinate(114.304, 30.1003);
        Coordinate[] coor2=new Coordinate[2];
        coor2[0]=new Coordinate(114.301, 30.1002);
        coor2[1]=new Coordinate(114.3023, 30.1015);
        TrajectoryLCSS lcss=new TrajectoryLCSS(coor1, coor2, 0.001);
        Coordinate[] coors=lcss.genLCSS();
        System.out.println(lcss.getMatchRatio());
    }
}

猜你喜欢

转载自blog.csdn.net/wk1134314305/article/details/78892155