毕业设计思路篇(三)之预加载车辆路线

主循环已经够忙了,算路这种重活能挪到启动前就先挪走。

思路篇(二) 把红绿灯对接完之后,仿真还需要知道「每辆车打算走哪几条路」。在线跑 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_backv_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/) 转载或引用必须申明原指尖魔法屋来源及源地址!