sinboy的菜地

一份耕耘,一份收获

用户操作
[即时聊天] [发私信] [加为好友]
张新波ID:sinboy
86083次访问,排名1113好友4人,关注者27
sinboy的文章
原创 49 篇
翻译 0 篇
转载 2 篇
评论 105 篇
sinboy的公告

喜欢中文分词技术的朋友请入http://groups.google.com/group/ictclas

最近评论
lcm62975723:谢谢你。
不知是否能给出一个完整的源代码。我的email是:
lichunming3793789@126.com
leon:您好! 我也需要JAVA版的ICTCLAS源码一份
非常感谢您
我的邮箱是 leiyongekin@126.com
再次谢谢您了。
yuzishui:呵呵,都是要源码的。
谢谢您的知识.
也希望您能坚持下去.
支持.
周梁:怎么就这两句话?赶紧加强啊。
xazl.ia.ac.cn@gmail.com
周梁:我刚开始看,这里我觉得楼主可能没有理解,
作者的原意是为了防止权重相同的节点,<判断就是和=判断区别开,如果出现=,i就不会增加,继续会在这个权重下面进行插入父节点。呵呵。
可以参考他的论文一段话:

如果两条或两条以上路径长度相等,那么他们的长度并列第i,都要列入粗分结果集,而且不影响其他路径的排列序号,最后的粗分结果集合大小大于或等于N。
文章分类
收藏
    相册
    IO
    TPTP
    友情链接
    DanceFire的BLOG
    Justin的BLOG
    Martin Fowler
    博客园设计模式
    吕震宇的BLOG
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 单源点最短路径Dijkstra算法的JAVA实现收藏

    新一篇: 在网络中使用IO流进行数据收发 | 旧一篇: 关于在Log4j中使用JDBCAppender时出现死循环的问题

    在城市智能交通中,经常会用到最短路径的问题,比如找最佳的行车路线等,Dijkstra算法做为最经典的求解方法,为我们指明了方向.不过真正想让我了解该算法的原因是在学习ICTCLAS的N-最短路径算法,虽然和我们常用的案例有一点区别,但基本相同,为了更好的理解N-最短路径算法,我又重新把大学时代的数据结构知识搬了出来。

    在网上找到一篇文章,非常详细生动(有FLASH动画演示)的描述了该算法的实现,不过第一页右下角的图终点那一列2和3弄反了,看的时候要注意 ,具体的算法描述不再赘述,请参考:

    http://student.zjzk.cn/course_ware/data_structure/web/tu/tu7.5.1.htm

    下面给出我的算法实现具体代码,为了更好的验证程序的正确性,在原来的基础上我又多加了几条边

     

    package sinboy.datastructure;

    import java.util.ArrayList;

    public class Dijkstra {
        
    static ArrayList<Side> map = null;

        
    static ArrayList<Integer> redAgg = null;

        
    static ArrayList<Integer> blueAgg = null;

        
    static Side[] parents = null;

        
    public static void main(String[] args) {
            
    // 初始化顶点集
            int[] nodes = 013245,6 };

            
    // 初始化有向权重图
            map = new ArrayList<Side>();
            map.add(
    new Side(0110));
            map.add(
    new Side(0330));
            map.add(
    new Side(04100));
            map.add(
    new Side(1250));
            map.add(
    new Side(2410));
            map.add(
    new Side(3220));
            map.add(
    new Side(3460));
            map.add(
    new Side(4550));
            map.add(
    new Side(3560));
            map.add(
    new Side(5610));
            map.add(
    new Side(3680)); 

            
    // 初始化已知最短路径的顶点集,即红点集,只加入顶点0
            redAgg = new ArrayList<Integer>();
            redAgg.add(nodes[
    0]);

            
    // 初始化未知最短路径的顶点集,即蓝点集
            blueAgg = new ArrayList<Integer>();
            
    for (int i = 1; i < nodes.length; i++)
                blueAgg.add(nodes[i]);

            
    // 初始化每个顶点在最短路径中的父结点,及它们之间的权重,权重-1表示无连通
            parents = new Side[nodes.length];
            parents[
    0= new Side(-1, nodes[0], 0);
            
    for (int i = 0; i < blueAgg.size(); i++{
                
    int n = blueAgg.get(i);
                parents[i 
    + 1= new Side(nodes[0], n, getWeight(nodes[0], n));
            }


            
    // 找从蓝点集中找出权重最小的那个顶点,并把它加入到红点集中 
            while (blueAgg.size() > 0{
                MinShortPath msp 
    = getMinSideNode();
                
    if(msp.getWeight()==-1)
                    msp.outputPath(nodes[
    0]);
                
    else
                    msp.outputPath();
                
                
    int node = msp.getLastNode();
                redAgg.add(node); 
                
    // 如果因为加入了新的顶点,而导致蓝点集中的顶点的最短路径减小,则要重要设置
                setWeight(node);
            }

     
        }


        
    /**
         * 得到一个节点的父节点
         * 
         * 
    @param parents
         * 
    @param node
         * 
    @return
         
    */

        
    public static int getParent(Side[] parents, int node) {
            
    if (parents != null{
                
    for (Side nd : parents) {
                    
    if (nd.getNode() == node) {
                        
    return nd.getPreNode();
                    }

                }

            }

            
    return -1;
        }


        
    /**
         * 重新设置蓝点集中剩余节点的最短路径长度
         * 
         * 
    @param preNode
         * 
    @param map
         * 
    @param blueAgg
         
    */

        
    public static void setWeight(int preNode) {
            
    if (map != null && parents != null && blueAgg != null{
                
    for (int node : blueAgg) {
                    MinShortPath msp
    =getMinPath(node);
                    
    int w1 = msp.getWeight();
                    
    if (w1 == -1)
                        
    continue;
                    
    for (Side n : parents) {
                        
    if (n.getNode() == node) {
                            
    if (n.getWeight() == -1 || n.getWeight() > w1) {
                                n.setWeight(w1);
                                n.setPreNode(preNode);
    //重新设置顶点的父顶点
                                break;
                            }

                        }

                    }

                }

            }

        }


        
    /**
         * 得到两点节点之间的权重
         * 
         * 
    @param map
         * 
    @param preNode
         * 
    @param node
         * 
    @return
         
    */

        
    public static int getWeight(int preNode, int node) {
            
    if (map != null{
                
    for (Side s : map) {
                    
    if (s.getPreNode() == preNode && s.getNode() == node)
                        
    return s.getWeight();
                }

            }

            
    return -1;
        }


        
    /**
         * 从蓝点集合中找出路径最小的那个节点
         * 
         * 
    @param map
         * 
    @param blueAgg
         * 
    @return
         
    */

        
    public static MinShortPath getMinSideNode() {
            MinShortPath minMsp 
    = null;
            
    if (blueAgg.size() > 0{
                
    int index = 0;
                
    for (int j = 0; j < blueAgg.size(); j++{
                    MinShortPath msp 
    = getMinPath(blueAgg.get(j));
                    
    if (minMsp == null || msp.getWeight()!=-1 &&  msp.getWeight() < minMsp.getWeight()) {
                        minMsp 
    = msp;
                        index 
    = j;
                    }

                }

                blueAgg.remove(index);

            }

            
    return minMsp;
        }


        
    /**
         * 得到某一节点的最短路径(实际上可能有多条,现在只考虑一条)
         * 
    @param node
         * 
    @return
         
    */

        
    public static MinShortPath getMinPath(int node) {
            MinShortPath msp 
    = new MinShortPath(node);
            
    if (parents != null && redAgg != null{
                
    for (int i = 0; i < redAgg.size(); i++{
                    MinShortPath tempMsp 
    = new MinShortPath(node);
                    
    int parent = redAgg.get(i);
                    
    int curNode = node;
                    
    while (parent > -1{
                        
    int weight = getWeight(parent, curNode);
                        
    if (weight > -1{
                            tempMsp.addNode(parent);
                            tempMsp.addWeight(weight);
                            curNode 
    = parent;
                            parent 
    = getParent(parents, parent);
                        }
     else
                            
    break;
                    }


                    
    if (msp.getWeight() == -1 || tempMsp.getWeight()!=-1 && msp.getWeight() > tempMsp.getWeight())
                        msp 
    = tempMsp;
                }

            }


            
    return msp;
        }

    }


    /**
     * 图中的有向边,包括节点名及他的一个前向节点名,和它们之间的权重
     * 
     
    */

    class Side {
        
    private int preNode; // 前向节点

        
    private int node;// 后向节点

        
    private int weight;// 权重

        
    public Side(int preNode, int node, int weight) {
            
    this.preNode = preNode;
            
    this.node = node;
            
    this.weight = weight;
        }


        
    public int getPreNode() {
            
    return preNode;
        }


        
    public void setPreNode(int preNode) {
            
    this.preNode = preNode;
        }


        
    public int getNode() {
            
    return node;
        }


        
    public void setNode(int node) {
            
    this.node = node;
        }


        
    public int getWeight() {
            
    return weight;
        }


        
    public void setWeight(int weight) {
            
    this.weight = weight;
        }


    }


    class MinShortPath {
        
    private ArrayList<Integer> nodeList;// 最短路径集

        
    private int weight;// 最短路径

        
    public MinShortPath(int node) {
            nodeList 
    = new ArrayList<Integer>();
            nodeList.add(node);
            weight 
    = -1;
        }