Пример #1
0
        //private static Stack<int> shortestPathBetween(int lineid1, int lineid2) {
        //    Stack<int> pathStack = new Stack<int>();
        //}

        //static void getXY(List<CRailwayLine> ls,int i, out double x, out double y)
        //{
        //    if (i % 2 == 0)
        //    {
        //        x = ls[i / 2].longitude[0];
        //        y = ls[i / 2].latitude[0];
        //    }
        //    else
        //    {
        //        int m = ls[i / 2].mPointNum;
        //        x = ls[i / 2].longitude[m - 1];
        //        y = ls[i / 2].latitude[m - 1];
        //    }
        //}

        static void Floyd(MGraph g)
        {
            double[,] A = g.edges; // new double[g.n, g.n];//A用于存放当前顶点之间的最短路径长度,分量A[i][j]表示当前顶点vi到顶点vj的最短路径长度。
            int[,] path = g.path;  //从顶点vi到顶点vj的路径上所经过的顶点编号不大于k的最短路径长度。
            int i, j, k;

            //for (i = 0; i < g.n; i++)
            //{
            //    for (j = 0; j < g.n; j++)//对各个节点初始已经知道的路径和距离
            //    {
            //        A[i, j] = g.edges[i, j];
            //        path[i, j] = -1;
            //    }
            //}
            for (k = 0; k < g.n; k++)
            {
                for (i = 0; i < g.n; i++)
                {
                    for (j = 0; j < g.n; j++)
                    {
                        if (A[i, j] > A[i, k] + A[k, j])    //从i到j的路径比从i经过k到j的路径长
                        {
                            A[i, j]    = A[i, k] + A[k, j]; //更改路径长度
                            path[i, j] = k;                 //更改路径信息经过k
                        }
                    }
                }
            }

            //Dispath(A, path, g.n);   //输出最短路径
        }
Пример #2
0
 public static int lineid2Nodeid(MGraph g, int lineid)
 {
     for (int i = 0; i < g.rline.Length; i++)
     {
         if (lineid == g.rline[i].mIndex)
         {
             return(i);
         }
     }
     return(-1);
 }
Пример #3
0
        //private const int MaxSize = 6;
        //private const int INF = 32767;    //INF表示∞
        //int vertexNum = 4;    //最大顶点个数
        //结构体的成员定义里不能直接赋值,也就是等号后的应该移除,在你后面实例化整个结构体以后,
        //再对Study_Data[n].input=new double[50] 其他成员类似。顺便说下其实用class简单得多。

        //struct VertexType
        //{
        //    public int no;                        //顶点编号
        //    public int info;                    //顶点其他信息
        //};                               //顶点类型


        public static void initPathGraph(List <CRailwayLine> ls, MGraph gNav, List <OneConnection> conList = null)
        {
            int i, j;

            gNav.n     = ls.Count * 2;
            gNav.edges = new double[gNav.n, gNav.n];
            gNav.path  = new int[gNav.n, gNav.n];
            gNav.rline = new CRailwayLine[ls.Count];

            i = 0;
            foreach (CRailwayLine rl in ls)
            {
                gNav.rline[i++] = rl;
                //gNav.lineID[i++] = rl.mIndex ;
            }


            for (i = 0; i < gNav.n; i++)        //建立图的图的邻接矩阵
            {
                for (j = 0; j < gNav.n; j++)
                {
                    gNav.path[i, j] = -1;
                    if (i == j) // 相同顶点
                    {
                        gNav.edges[i, j] = 0;
                    }
                    else if (i / 2 == j / 2)  //同一条线路上的两个点
                    {
                        //if (i < j)
                        gNav.edges[i, j] = gNav.edges[j, i] = gNav.rline[i / 2].mLength;
                        //else
                        //    g.edges[i, j] = Double.MaxValue/10;
                    }
                    //else { if (Math.Abs(1)) ;
                    else
                    {
                        double p1x, p1y, p2x, p2y;
                        if (i % 2 == 0)
                        {
                            p1x = gNav.rline[i / 2].startLongitude;
                            p1y = gNav.rline[i / 2].startLatitude;
                        }
                        else
                        {
                            p1x = gNav.rline[i / 2].endLongitude;
                            p1y = gNav.rline[i / 2].endLatitude;
                        }

                        if (j % 2 == 0)
                        {
                            p2x = gNav.rline[j / 2].startLongitude;
                            p2y = gNav.rline[j / 2].startLatitude;
                        }
                        else
                        {
                            p2x = gNav.rline[j / 2].endLongitude;
                            p2y = gNav.rline[j / 2].endLatitude;
                        }

                        if (Math.Abs(p1x - p2x) < 0.0000001 && Math.Abs(p1y - p2y) < 0.0000001)
                        {
                            gNav.edges[i, j] = 0;
                        }
                        else
                        {
                            gNav.edges[i, j] = Double.MaxValue / 1000;
                        }
                    }
                }
            }
            //Console.WriteLine("各顶点的最短路径:");
            if (conList != null)
            {
                //int id1, id2;
                foreach (OneConnection c in conList)
                {
                    i = lineid2Nodeid(gNav, c.fromIndex);
                    j = lineid2Nodeid(gNav, c.toIndex);
                    gNav.edges[i * 2 + 1, j * 2] = 0;
                }
            }
            Floyd(gNav);
        }
Пример #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="idLs">途经路径的线路id</param>
        /// <param name="g"></param>
        /// <returns></returns>
        public static List <int> getNavPath(int[] idLs, MGraph g)
        {
            int id1, id2;

            id1 = id2 = 0;
            double     dis      = 0;
            List <int> pathList = new List <int>();

            if (idLs == null || idLs.Length == 0)
            {
                return(pathList);
            }

            if (idLs.Length == 1)
            {
                pathList.Add(idLs[0]);
                pathList.Add(0);
                return(pathList);
            }

            int[] idxsls = new int[idLs.Length * 2];
            int   xs, xe, xnext;
            int   j = 0;

            for (j = 0; j < (idLs.Length - 1) * 2; j += 2)
            {
                xs    = lineid2Nodeid(g, idLs[j / 2]) * 2;
                xe    = lineid2Nodeid(g, idLs[j / 2]) * 2 + 1;
                xnext = lineid2Nodeid(g, idLs[j / 2 + 1]) * 2;
                if (g.edges[xs, xnext] > g.edges[xe, xnext])
                {
                    idxsls[j]     = xs;
                    idxsls[j + 1] = xe;
                }
                else
                {
                    idxsls[j]     = xe;
                    idxsls[j + 1] = xs;
                }
            }
            j = (idLs.Length - 1) * 2;
            int xpre = lineid2Nodeid(g, idLs[j / 2 - 1]) * 2;

            xs = lineid2Nodeid(g, idLs[j / 2]) * 2;
            xe = lineid2Nodeid(g, idLs[j / 2]) * 2 + 1;
            if (g.edges[xpre, xs] < g.edges[xpre, xe])
            {
                idxsls[j]     = xs;
                idxsls[j + 1] = xe;
            }
            else
            {
                idxsls[j]     = xe;
                idxsls[j + 1] = xs;
            }

            Stack <int> pathStack = new Stack <int>();

            for (j = idxsls.Length - 2; j >= 0; j--)
            {
                id1  = idxsls[j];
                id2  = idxsls[j + 1];
                dis += g.edges[id1, id2];
                if (dis > Double.MaxValue / 10000)
                {
                    return(pathList);
                }
                if (pathStack.Count == 0)
                {
                    pathStack.Push(id2);
                }
                else if (pathStack.Peek() != id2)
                {
                    pathStack.Push(id2);
                }
                while (g.path[id1, id2] != -1)
                {
                    pathStack.Push(g.path[id1, id2]);
                    id2 = g.path[id1, id2];
                }
            }
            pathStack.Push(id1);

            //Console.WriteLine(pathStack);
            //if (isNodeIndex)
            //    return pathStack.ToList();
            //pathList = pathStack.ToList();
            while (pathStack.Count > 1)
            {
                int id     = pathStack.Pop();
                int x      = g.rline[id / 2].mIndex;
                int nextid = pathStack.Pop();
                int nextx  = g.rline[nextid / 2].mIndex;
                if (x == nextx)
                {
                    pathList.Add(x);
                    pathList.Add(nextid > id ? 0 : 1);
                }
                else
                {
                    pathList.Add(x);
                    pathList.Add(id % 2 == 1 ? 0 : 1);
                    pathList.Add(nextx);
                    pathList.Add(nextid % 2 == 0 ? 0 : 1);
                    if (pathStack.Count > 0)
                    {
                        pathStack.Pop();
                    }
                }
            }
            if (pathStack.Count == 1)
            {
                int id = pathStack.Pop();
                int x  = g.rline[id / 2].mIndex;
                pathList.Add(x);
                pathList.Add(id % 2 == 0 ? 0 : 1);
            }

            return(pathList);
            //        return path;
        }
Пример #5
0
        /// <summary>
        /// 有些抽象,获取两个链之间的路径
        /// </summary>
        /// <param name="fromID">起始链的编号</param>
        /// <param name="toID">终止链的编号</param>
        /// <param name="dis">之间的距离,不准确,可能包含起始链或终止链,也可能不包含</param>
        /// <returns>路径节点,0,2,4,6下标为路径编号,1,3,5,7等标注正序还是逆序,0-正序,1-逆序</returns>
        public static List <int> getNavPath(int fromID, int toID, MGraph gNav, out double dis)
        {
            int id1, id2;

            id1 = id2 = 0;
            dis = 0;
            List <int> pathList = new List <int>();

            if (fromID == toID)
            {
                pathList.Add(fromID);
                pathList.Add(0);
                return(pathList);
            }

            for (int i = 0; i < gNav.n; i++)
            {
                if (gNav.rline[i].mIndex == fromID)
                {
                    id1 = i * 2;
                    break;
                }
            }
            for (int i = 0; i < gNav.n; i++)
            {
                if (gNav.rline[i].mIndex == toID)
                {
                    id2 = i * 2 + 1;
                    break;
                }
            }

            Stack <int> pathStack = new Stack <int>();

            dis = gNav.edges[id1, id2];
            if (dis > Double.MaxValue / 10000)
            {
                return(pathList);
            }
            pathStack.Push(id2);
            while (gNav.path[id1, id2] != -1)
            {
                pathStack.Push(gNav.path[id1, id2]);
                id2 = gNav.path[id1, id2];
            }
            pathStack.Push(id1);

            //Console.WriteLine(pathStack);
            //if (isNodeIndex)
            //    return pathStack.ToList();
            //pathList = pathStack.ToList();
            while (pathStack.Count > 1)
            {
                int id     = pathStack.Pop();
                int x      = id / 2;
                int nextid = pathStack.Pop();
                int nextx  = nextid / 2;
                if (x == nextx)
                {
                    pathList.Add(x);
                    pathList.Add(nextid > id ? 0 : 1);
                }
                else
                {
                    pathList.Add(x);
                    pathList.Add(id % 2 == 1 ? 0 : 1);
                    pathList.Add(nextx);
                    pathList.Add(nextid % 2 == 0 ? 0 : 1);
                    if (pathStack.Count > 0)
                    {
                        pathStack.Pop();
                    }
                }
            }
            if (pathStack.Count == 1)
            {
                int id = pathStack.Pop();
                int x  = id / 2;
                pathList.Add(x);
                pathList.Add(id % 2 == 0 ? 0 : 1);
            }

            return(pathList);
            //        return path;
        }