//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); //输出最短路径 }
//public double getHeight(double mileage, int id) //{ // double res = 0; // if (mileage < sm[id]) // { // res = h[id] + (mileage - m[id]) * i1[id]; // } // else if (mileage > em[id]) // { // res = h[id] + (mileage - m[id]) * i2[id]; // } // else // { // res = h[id] + (sm[id] - m[id]) * i1[id] + (mileage - sm[id]) * i1[id] // + Math.Sign(i2[id] - i1[id]) * (mileage - sm[id]) * (mileage - sm[id]) / r[id] / 2; // } // return res; //} #endregion public CSubPath(MGraph graph, string fromDK, double fromMileage, string toDK, double toMileage, double stepm) { List <string> strls = new List <string>(); List <double> dls = new List <double>(); strls.Add(fromDK); strls.Add(toDK); dls.Add(fromMileage); dls.Add(toMileage); CreateSubPathFromNodeList(graph, strls, dls, stepm); }
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); }
public static MGraph gMileageConnection; // 用于计算里程 /// <summary> /// 由数据库或远程服务器读入三维中线的数据 /// </summary> /// <param name="fileName"></param> public static void CreateLinelistFromExcel(string dbPath) { double[] m, x, y, z; double fromMeter, toMeter; //double fromX, toX, fromY, toY; int chainIndex; int chainType; string dkcode, dkcode2; //bool isRight = false; //bool isDouble = true; int count; DataTable dt1, dt2, dt3; //本地sqlite数据库读取里程数据 //#if DEBUG // Helper.LogHelper.WriteLog("SQlite Database" + dbPath); //#endif dt1 = ExcelWrapper.LoadDataTableFromExcel(dbPath, @"select chainIndex, fromMeter, toMeter,DKCode,DKCode2,chainType from [ChainInfo$] order by chainIndex"); dt2 = ExcelWrapper.LoadDataTableFromExcel(dbPath, @"select fromChain, toChain from [ExtraConnection$] "); List <OneConnection> connectionList = new List <OneConnection>(); foreach (DataRow dr in dt2.Rows) { OneConnection aCon = new OneConnection(); aCon.fromIndex = Convert.ToInt32(dr["fromChain"]); aCon.toIndex = Convert.ToInt32(dr["toChain"]); //aCon.isRealConnect = Convert.ToInt32(dr["isConnect"])==0 ? true:false; //aCon.mileageOffset = Convert.ToDouble(dr["mileageOffset"]); connectionList.Add(aCon); } //int index = 0; foreach (DataRow dr in dt1.Rows) { chainIndex = Convert.ToInt32(dr["chainIndex"]); fromMeter = Convert.ToDouble(dr["fromMeter"]); toMeter = Convert.ToDouble(dr["toMeter"]); dkcode = (string)dr["DKCode"]; dkcode2 = dr["DKCode2"].ToString(); chainType = Convert.ToInt32(dr["chainType"]); // isReverse = Convert.ToBoolean(dr["IsReverse"]); string strOrder = (fromMeter < toMeter) ? "" : " desc "; string tableName = "sheet" + chainIndex; dt3 = ExcelWrapper.LoadDataTableFromExcel(dbPath, @"select Mileage, Longitude,Latitude,Altitude from [" + tableName + "$] order by mileage " + strOrder); count = dt3.Rows.Count; if (count < 2) { continue; } m = new double[count]; x = new double[count]; y = new double[count]; z = new double[count]; //xMars = new double[count]; //yMars = new double[count]; int j = 0; foreach (DataRow dr2 in dt3.Rows) { m[j] = Math.Abs(Convert.ToDouble(dr2["Mileage"]) - fromMeter); x[j] = Convert.ToDouble(dr2["Longitude"]); y[j] = Convert.ToDouble(dr2["Latitude"]); z[j] = Convert.ToDouble(dr2["Altitude"]); j++; //xMars[j] = Convert.ToDouble(dr2["LongitudeMars"]); //yMars[j] = Convert.ToDouble(dr2["LatitudeMars"]); } mLineList.Add(new CRailwayLine(chainIndex, dkcode, dkcode2, fromMeter, toMeter, chainType, count, m, x, y, z)); } gRealConnection = new MGraph(); gMileageConnection = new MGraph(); ShortestPathFloyd.initPathGraph(mLineList, gRealConnection, null); ShortestPathFloyd.initPathGraph(mLineList, gMileageConnection, connectionList); }
/// <summary> /// 生成子路径 /// </summary> /// <param name="g">寻径的floyd图</param> /// <param name="DKlist">路径上的dkcode列表,至少2个</param> /// <param name="milelist">路径上的里程列表,至少2个</param> /// <param name="stepm">细分里程间隔</param> private void CreateSubPathFromNodeList(MGraph g, List <string> DKlist, List <double> milelist, double stepm) { if (DKlist == null || DKlist.Count < 2) { return; } mFromDK = DKlist.First(); mToDK = DKlist.Last(); mFromMileage = milelist.First(); mToMileage = milelist.Last(); mStepM = stepm; mLength = 0; List <PathNode> ls = new List <PathNode>(); // 路径节点,0,2,4,6下标为链路编号,1,3,5,7等标注正序还是逆序,0-正序,1-逆序 List <int> idls = null; CRailwayLine tmpLine; //存放所有路径上的链路编号 int[] rlls = new int[DKlist.Count]; for (int i = 0; i < DKlist.Count; i++) { tmpLine = CRailwayLineList.getRailwayLineByDKCode(DKlist[i], milelist[i]); if (tmpLine == null) { return; } rlls[i] = tmpLine.mIndex; } // 路径节点,0,2,4,6下标为路径编号,1,3,5,7等标注正序还是逆序,0-正序,1-逆序 idls = ShortestPathFloyd.getNavPath(rlls, g); if (idls == null) { Console.WriteLine(DKlist[0] + "等路径不存在"); return; } if (DKlist.Count == 2 && rlls[0] == rlls[1]) // 起点和终点在同一个链路中 { CRailwayLine rl = CRailwayLineList.getRailwayLineByIndex(idls[0]); mLength = Math.Abs(milelist[0] - milelist.Last()); //if (idls[1] == 0) ls.Add(new PathNode(rl, milelist[0], milelist.Last(), false)); //else // ls.Add(new PathNode(rl, milelist.Last(), milelist[0], true)); } else if (idls.Count > 2) { mLength = 0; mNodeLength = new double[idls.Count / 2]; // path中的第一条链 CRailwayLine rl = CRailwayLineList.getRailwayLineByIndex(idls[0]); if (idls[1] == 0) { ls.Add(new PathNode(rl, milelist[0], rl.mEnd, false)); mLength += Math.Abs(milelist[0] - rl.mEnd); } else { ls.Add(new PathNode(rl, milelist[0], rl.mStart, true)); mLength += Math.Abs(milelist[0] - rl.mStart); } mNodeLength[0] = mLength; if (idls.Count > 2) { // path的中间链 for (int i = 1; i < idls.Count / 2 - 1; i++) { rl = CRailwayLineList.getRailwayLineByIndex(idls[2 * i]); if (idls[2 * i + 1] == 0) { ls.Add(new PathNode(rl, rl.mStart, rl.mEnd, false)); } else { ls.Add(new PathNode(rl, rl.mEnd, rl.mStart, true)); } mLength += Math.Abs(rl.mLength); mNodeLength[i] = mLength; } // path的最后一条链 rl = CRailwayLineList.getRailwayLineByIndex(idls[idls.Count - 2]); if (idls.Last() == 0) { ls.Add(new PathNode(rl, rl.mStart, milelist.Last(), false)); mLength += Math.Abs(rl.mStart - milelist.Last()); } else { ls.Add(new PathNode(rl, rl.mEnd, milelist.Last(), true)); mLength += Math.Abs(rl.mEnd - milelist.Last()); } mNodeLength[mNodeLength.Length - 1] = mLength; } } mPathNodeList = ls; hasPath = mPathNodeList.Count > 0 && mLength > 1; if (hasPath) { createSubLine(); } }
public CSubPath(MGraph g, List <string> DKlist, List <double> milelist, double stepm) { CreateSubPathFromNodeList(g, DKlist, milelist, stepm); }
//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); }
/// <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; }
/// <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; }