华为6地铁最佳路径

来源:互联网 发布:超星尔雅网络通识课 编辑:程序博客网 时间:2024/04/28 02:43
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /****************************************************************************** 
  2.  
  3. Copyright (C), 2001-2011, Huawei Tech. Co., Ltd. 
  4.  
  5. ****************************************************************************** 
  6. File Name     : 
  7. Version       : 
  8. Author        : 
  9. Created       : 2010/3 
  10. Last Modified : 
  11. Description   : 
  12. Function List : 
  13.  
  14. History       : 
  15. 1.Date        : 2010/3 
  16. Author      : 
  17. Modification: Created file 
  18.  
  19. ******************************************************************************/  
  20. #include "FindMinimalPath.h"  
  21. #include <map>  
  22. #include <set>  
  23. using namespace std;  
  24. struct stop{  
  25.     unsigned int next[100];//最大有100个下一站,可连通  
  26.     bool paased;//每次前往下一战时,先判断下一站是否已通过,若为通过则将其加入oldstop  
  27.     int nnum;//可连通数量  
  28.     int lnum;//线路数量  
  29.     unsigned int LineNo[100];//所在线路的id  
  30.     unsigned int path[100][100];//对于每条路径。。。我只保存前一个值是不够的。。。可能有多条路径,最多100条  
  31.     int pnum;//路径数量  
  32.     //int paassN;//  
  33. };  
  34. map<unsigned int,stop> allstop;  
  35. unsigned int oldstop[1000];  
  36. unsigned int newos[1000];//用来替换正在计算中的起点站  
  37. int newosn;//总起点暂时总数  
  38. int oldn;//起点总数  
  39. int passN;//结果站点总数  
  40.   
  41. //int ps;//路径总数  
  42. //int newps;//新路径暂时总数  
  43. //unsigned int path[1000][100];  
  44. //unsigned int npath[1000][100];  
  45. /******************************************************************************************************************* 
  46. 函数说明: 增加某条地铁线路 
  47. 函数原型: void AddLine(unsigned int LineNo, unsigned int StationNum ,unsigned  int *pStationArray); 
  48. 输入参数: 
  49.            LineNo        地铁线路号; 
  50.            StationNum    该条地铁线中的站点数目,由调用者保证不小于2; 
  51.            pStationArray 该条地铁线的所有站点信息,pStationArray指向的存储空间在函数外会被释放,请自行申请存储空间; 
  52. 输出参数: 无 
  53. 返回值  : 无 
  54. ********************************************************************************************************************/  
  55. void AddLine(unsigned int LineNo, unsigned int StationNum ,unsigned  int *pStationArray)  
  56. {  
  57.     /* 在这里实现功能 */  
  58.     //假设,对与 1 ,2, 1的环线线路,如何进行判断,站台数是2。。。  
  59.     unsigned int p = 0 ;  
  60.     unsigned int start = *pStationArray;  
  61.     unsigned int before = *pStationArray;  
  62.     map<unsigned int,stop>::iterator t;  
  63.     for(int i = 0 ; i < StationNum ; i++){  
  64.         if(allstop.count(*pStationArray)){//如果与其他线路交叉  
  65.             t = allstop.find(*pStationArray);  
  66.             t->second.LineNo[t->second.lnum++] = LineNo ;  
  67.             if( i == 0){  
  68.                 before = *pStationArray++;  
  69.                 continue;  
  70.             }  
  71.         }else{  
  72.             stop news;  
  73.             news.LineNo[0] = LineNo ;  
  74.             news.lnum = 1;  
  75.             news.paased = false;  
  76.             news.nnum = 0;  
  77.             news.pnum = 0;  
  78.             allstop.insert(pair<unsigned int,stop>(*pStationArray , news));  
  79.         }  
  80.         if(i > 0){  
  81.             t = allstop.find(before);  
  82.             t->second.next[t->second.nnum++] = *pStationArray;  
  83.             t = allstop.find(*pStationArray) ;  
  84.             t->second.next[t->second.nnum++] = before;  
  85.         }  
  86.         before = *pStationArray++;  
  87.     }  
  88.     if( start == *pStationArray) {//即为环,这里的stationnum是多少就是多少,不重复包含初始站和终点站  
  89.         t->second.next[t->second.nnum++] = start ;  
  90.         t = allstop.find(start);  
  91.         t->second.next[t->second.nnum++] = before ;  
  92.     }  
  93.     return;  
  94.   
  95. }  
  96.   
  97. /********************************************************************************************************************* 
  98. 函数说明:计算从起点站到终点站的最短路线长度 
  99. 函数原型:int CalcMinPathLen(unsigned int SrcStation, unsigned int DesStation); 
  100. 输入参数: 
  101.           SrcStation  起点站; 
  102.           DesStation 终点站; 
  103. 输出参数:无 
  104. 返回值  : 
  105.           起点站到终点站的最短路线长度 
  106.           -1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等) 
  107. **********************************************************************************************************************/  
  108. bool gonext(unsigned int DesStation){  
  109.     map<unsigned int,stop>::iterator p;  
  110.     map<unsigned int,stop>::iterator next;  
  111.     newosn=0;  
  112.     passN++;  
  113.     //newps=0;  
  114.     for(int i=0;i<oldn;i++){  
  115.         p = allstop.find(oldstop[i]);  
  116.         for(int j=0;j<p->second.nnum;j++){  
  117.         next = allstop.find(p->second.next[j]);  
  118.         if(!next->second.paased){  
  119.             //next->second.paased = true;//一次前进过程中,可以从不同的方向到达同一点,但是,不能从回到原来的点  
  120.             int pathnun=p->second.pnum;  
  121.             for(int l=0;l<pathnun;l++){  
  122.             for(int k=0;k < passN - 1;k++){  
  123.                 next->second.path[next->second.pnum][k] = p->second.path[l][k];  
  124.   
  125.             }  
  126.             next->second.path[next->second.pnum++][passN-1] = next->first;  
  127.         //  npath[newps][passN-1] = next->first;  
  128.             //next->second.path[next->second.pnum++] = path[newps++];  
  129.             }  
  130.             //next  
  131.             newos[newosn++] = next->first;  
  132.   
  133.         }  
  134.         }  
  135.     }  
  136.     oldn = newosn;  
  137.     //ps = newps;  
  138.     int nn=0;  
  139.     for(int i=0;i < oldn;i++){  
  140.         p = allstop.find(newos[i]);  
  141.         if(!p->second.paased){  
  142.         oldstop[nn++] = newos [i];  
  143.          p->second.paased= true ;  
  144.         }  
  145.     }  
  146.     oldn = nn;  
  147.     //for (int i=0;i < ps;i++){  
  148.     //  for(int j=0;j < passN ;j++){  
  149.         //  path[i][j] = npath[i][j];  
  150.     //  }  
  151.     //}  
  152.     for (int i=0;i<oldn;i++){  
  153.         if(oldstop[i] == DesStation)  
  154.             return false;  
  155.     }  
  156.     return true;  
  157. }  
  158.   
  159. int CalcMinPathLen(unsigned int SrcStation, unsigned int DesStation)  
  160. {  
  161.   
  162.     /* 在这里实现功能 */  
  163.     if(SrcStation==DesStation)return -1;  
  164.     if(!allstop.count(SrcStation)||!allstop.count(DesStation))return -1;  
  165.     map<unsigned int ,stop>::iterator p;  
  166.     p = allstop.begin();  
  167.     for(int i=0; i< allstop.size();i++){//初始化一部分数据  
  168.         p -> second.paased = false;  
  169.         p -> second.pnum = 0;  
  170.         p++;  
  171.     }  
  172.     p = allstop.find(SrcStation );  
  173.     p->second.paased = true;  
  174.     p->second.pnum=1;  
  175.     oldn = 0;  
  176.     oldstop[oldn++] = SrcStation ;  
  177.     //path[0][0] = SrcStation;  
  178.     passN = 0;  
  179. //  ps = 0;  
  180.     while(gonext(DesStation));//寻找路径  
  181.     return passN;  
  182.   
  183. };  
  184.   
  185.   
  186.   
  187.   
  188. /********************************************************************************************************** 
  189. 函数说明:输出从起点站到终点站的最短路线 
  190. 函数原型:int SearchMinPathes(unsigned int SrcStation, 
  191.                               unsigned int DesStation, 
  192.                               unsigned int* pPathNum, 
  193.                               unsigned int* pPathLen, 
  194.                               unsigned int **ppPathes); 
  195. 输入参数: 
  196.           SrcStation 起点站; 
  197.           DesStation 终点站; 
  198.           Output Param 
  199.           pPathNum 最短路线条数; 
  200.           pPathLen  最短路线长度; 
  201.           ppPathes 存储最短路线的内存地址,内存空间在本函数内申请,调用者释放,内存空间的存储格式请见PPT要求; 
  202. 返回值  : 
  203.           0 :成功 
  204.           -1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等) 
  205.  
  206. ************************************************************************************************************/  
  207. int SearchMinPathes(unsigned int SrcStation,  
  208.                     unsigned int DesStation,  
  209.                     unsigned int* pPathNum,  
  210.                     unsigned int* pPathLen,  
  211.                     unsigned int **ppPathes)  
  212. {  
  213.     /* 在这里实现功能 */  
  214.     map<unsigned int,stop>::iterator p;  
  215.     int r = CalcMinPathLen(SrcStation,DesStation);  
  216.       
  217.     if(r==-1)return -1;  
  218.     else{  
  219.         *pPathNum = passN;  
  220.         p = allstop.find(DesStation);  
  221.         r = p->second.pnum;  
  222.         *pPathLen = r;  
  223.         //r*=passN;  
  224.         unsigned int  *save = (unsigned int*)malloc(sizeof(unsigned int)*r*passN);  
  225.   
  226.         for(int i=0;i<r;i++){  
  227.             *ppPathes = save;  
  228.             for(int j=0;j<passN;j++)  
  229.                 *save++ = p->second.path[i][j];  
  230.   
  231.         }  
  232.   
  233.   
  234.     }  
  235.     return 0;  
  236. }  
  237.   
  238.   
  239. /************************************************************************************************* 
  240. 函数说明:输出从起点站到终点站的最优路线 
  241. 函数原型:int SearchBestPathes(unsigned int SrcStation, 
  242.                                unsigned int DesStation, 
  243.                                unsigned int *pPathNum, 
  244.                                unsigned int* pPathLen, 
  245.                                unsigned int** ppPathes); 
  246. 输入参数: 
  247.          SrcStation 起点站; 
  248.          DesStation 终点站; 
  249.          Output Param 
  250.          pPathNum 最优路线条数; 
  251.          pPathLen  最短路线长度; 
  252.          ppPathes 存储最短路线的内存地址,内存格式见下图,内存空间在本函数内申请,调用者释放; 
  253. 返回值 : 
  254.          0:成功 
  255.          -1:任何出错情况(包括路线不存在、站点不存在、起点和终点重叠等等) 
  256. **************************************************************************************************/  
  257. int SearchBestPathes(unsigned int SrcStation,  
  258.                      unsigned int DesStation,  
  259.                      unsigned int *pPathNum,  
  260.                      unsigned int* pPathLen,  
  261.                      unsigned int** ppPathes)  
  262. {  
  263.     /* 在这里实现功能 */  
  264.   
  265.     int mini = 999;//最短路线  
  266.     int changes = 0;  
  267.     int all = 0;  
  268.     int pathnum = 0 ;  
  269.     int pathchange[100];  
  270.     set<unsigned int> oldline;  
  271.     set<unsigned int>::iterator t;  
  272.     map<unsigned int,stop>::iterator p;  
  273.     map<unsigned int,stop>::iterator last;  
  274.     map<unsigned int,stop>::iterator now;  
  275.     map<unsigned int,stop>::iterator start;  
  276.     int r = CalcMinPathLen(SrcStation,DesStation);\  
  277.     if(r == -1)return -1;  
  278.     else{  
  279.         p = allstop.find(DesStation);  
  280.         start = allstop.find(SrcStation);  
  281.         all = p->second.pnum;  
  282.         for(int i=0;i<all;i++){  
  283.             last = start;  
  284.             changes = 0;  
  285.             for(int j=0;j<last->second.lnum;j++){  
  286.                 oldline.insert(last->second.LineNo[j]);//将第一个点可能的线路记录下来  
  287.             }  
  288.             for(int j=0;j<passN;j++){  
  289.                 now = allstop.find( p->second.path[i][j]);  
  290.                 int n = oldline.size();  
  291.                 t = oldline.begin();  
  292.                 bool htheline=false;  
  293.                 for (int k=0; k < n ;k++){  
  294.                     htheline = false ;  
  295.                     for(int m=0;m<now->second.lnum;m++){  
  296.                     if( *t == now->second.LineNo[m]){  
  297.                         htheline =true;  
  298.                         break;  
  299.                     }  
  300.                     }  
  301.                     if(!htheline){  
  302.                         t = oldline.erase(t);  
  303.                     }else{  
  304.                         t++;  
  305.                     }  
  306.   
  307.                 }  
  308.                   
  309.                 if(oldline.size()==0){//为空时,即必须要换车了,将这个点的所有可能线路保存下来  
  310.                 changes++;  
  311.                 for(int j=0;j<last->second.lnum;j++){  
  312.                     for(int k=0;k<now->second.lnum;k++)  
  313.                         if(last->second.LineNo[j]==now->second.LineNo[k])  
  314.                             oldline.insert(last->second.LineNo[j]);//将从前一站到这一站可能使用的线路记录下来。  
  315.                 }  
  316.                 }else{  
  317.                     ;//继续以剩余的线路继续前行  
  318.   
  319.                 }  
  320.                 last = now;  
  321.             }  
  322.             pathchange[i] = changes ;  
  323.             oldline.clear();  
  324.         }  
  325.         mini = 999;  
  326.         for(int i=0; i<all;i++){  
  327.             mini = mini<pathchange[i]?mini:pathchange[i];//编程之美  
  328.         }  
  329.         //oldline.clear();  
  330.         for(int i=0;i<all;i++){  
  331.             if(pathchange[i]==mini)  
  332.                 pathchange[pathnum++] = i;//获得最佳路线的数量和序号  
  333.         }  
  334.         *pPathNum = pathnum;  
  335.         *pPathLen = passN ;  
  336.         unsigned int  *save = (unsigned int*)malloc(sizeof(unsigned int)*pathnum*passN);  
  337.         for(int i=0;i<pathnum;i++){  
  338.             *ppPathes = save;  
  339.             for(int j=0;j<passN;j++)  
  340.                 *save++ = p->second.path[pathchange[i]][j++];  
  341.         }  
  342.   
  343.     }  
  344.     return 0;  
  345. }  
  346.   
  347. /************************************************************************************************* 
  348. 函数说明:清空所有的线路信息 
  349. 函数原型:void Clear(); 
  350. 输入参数:无 
  351. 输出参数:无 
  352. 返回值  :无 
  353. **************************************************************************************************/  
  354. void Clear()  
  355. {  
  356.   
  357.     /* 在这里实现功能 */  
  358.     allstop.clear();  
  359.   
  360.   
  361.     return ;  
  362.   
  363. };  
0 0
原创粉丝点击