毕业设计思路篇(三)之预加载车辆路线
主循环已经够忙了,算路这种重活能挪到启动前就先挪走。
思路篇(二) 把红绿灯对接完之后,仿真还需要知道「每辆车打算走哪几条路」。在线跑 Dijkstra 不是不行,但毕业设计那次我选择启动前一次性读文件:路径在 番外篇 里离线算好,整理成 route.txt,主程序里 loadRoute 解析进全局的 v_Route,供 思路篇(四) 的 generateVehicle 随机(或暂时写死)挑路线用。
1. 从文件(route.txt)中读取路径
文件放在资源目录 DIR_RES"route.txt",一行代表一条从头到尾都畅通的道路编号序列(编号对应 Graph::m_Road_v 的下标,不是 OSM 原始 id)。示例:
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
上面这种递增写法是当时调试用的样例:第 n 行有 n+1 个道路 id,用来验证「路径越长、换路次数越多」时主循环是否稳定。正式数据来自番外篇输出的道路链,格式一样,都是空格分隔的整数。
为什么用 queue<int> 而不是 vector?车辆在 思路篇(五) 里每走完一段路要 route.pop() 掉队首,剩下的是「还未行驶的路段」;队列语义和「下一站去哪」很贴,拷贝给 Vehicle 之后各车各 pop,互不影响。
将所有道路存入 v_Route:
vector<queue<int>> v_Route;
/**
* load route from route file
* @param Map_graph
*/
void loadRoute(Graph &Map_graph) {
string str_Path;
ifstream fin_Route(DIR_RES"route.txt");
while (getline(fin_Route, str_Path)) {
stringstream ss_Temp(str_Path);
queue<int> q_Path_Temp;
int n_Temp;
while (ss_Temp >> n_Temp) {
q_Path_Temp.push(n_Temp);
}
v_Route.push_back(q_Path_Temp);
}
}
实现很直白:getline 读一行,stringstream 按空白切分整数,push 进临时队列,再 push_back 到 v_Route。空行会被读进来但得到空队列,正式数据里应避免;当时也没做 id 合法性校验,如果 route.txt 里写了不存在的道路编号,要到仿真阶段才会暴露。
Map_graph 参数在函数体里没用到,签名留着是为了和「构图 → 加载路线 → 发车」的调用顺序一致,以后可以在加载时校验每条边的 m_CrossRoadFromSite 是否连通。踩坑:Windows 下换行符和路径宏混用时曾经读到带 \r 的行,最后一个数字解析失败;改成统一文本模式或 trim 行尾就正常了。
加载完 v_Route 就可以调 generateVehicle 了。若文件缺失或为空,后面发车无路线可选,属于启动前就该检查的配置问题,别留到 runSimulation 里才发现。
版权声明: 本文首发于 指尖魔法屋-毕业设计思路篇(三)之预加载车辆路线(https://blog.thinkmoon.cn/post/129-graduation-design-source-code-cplusplus/) 转载或引用必须申明原指尖魔法屋来源及源地址!