修改了README

This commit is contained in:
jackfiled 2022-07-04 18:06:25 +08:00
parent 1dad2ed57a
commit be7aea1d7d
12 changed files with 29 additions and 293 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
# 项目的构建文件夹
build/
cmake-build-*/
# VSCode的配置文件夹
.vscode/

View File

@ -1,19 +1,22 @@
# Auto Pilot Bus
## 项目简介
北京邮电大学计算机学院2021级《计算导论与程序设计》实践大作业项目仓库本次课程的题目为“自动公交车调度”。
北京邮电大学计算机学院2021级《计算导论与程序设计》实践大作业项目仓库。
### 特点
在指定的公交车行驶模型下,实现指定的算法以实现对于公交车的自动调度。
- 采用`cmake`进行项目管理,编译轻松快捷。
- 程序模块化设计,注释详尽,代码可读性高。
- 含有`GTest`单元测试模块和自行设计的全局测试模块,还提供了不少测试用例。
- 完全使用`markdown`撰写的文档
## 项目使用
### 项目结构
### 结构
```
auto_pilot_bus
|
+-all_test //本地测试文件夹
+-all_test //本地全局测试文件夹
|
+-docs // 文档文件夹
|
@ -33,29 +36,27 @@ auto_pilot_bus
### 编译环境
- 编译器 `MinGW-W64 gcc 8.1.0`
- 编译工具 `cmake 3.23.1`
- 理论上不依赖特定的编译器
### 项目使用
> `MinGW64 GCC`和`GNU GCC`编译器经过测试可正常编译。
处在校园网环境在
> 参考信息化中心的这篇[文章](https://nic.bupt.edu.cn/info/1016/1301.htm)安装VPN客户端
### 使用
使用
```bash
git clone http://10.3.255.244:8801/2021211180/2021211180.git
git clone https://github.com/jackfiled/auto_bus.git
```
下载仓库,在下载过程中可能提示输入账号和密码认证,账号即为你的学号,密码就是你登录`GitLab`时输入的密码。
下载完成后文件夹`2021211180`即为项目的文件夹。
下载完成后文件夹`auto_bus`即为项目的文件夹。
使用
> 可自行指定使用的编译器
```bash
cd 20212111180
cd auto_bus
mkdir build # 创建编译的文件夹
cd build
cmake .. -G "MinGW Makefiles" # 在第一次生成之后就不必再使用"-G"参数指定编译类型
@ -64,16 +65,25 @@ cmake --build .
在编译执行完成之后,`build`文件下的`bus.exe`即为编译产生的程序。
## 项目测试
程序具体支持的指令可以查看文档中的说明文档。
### 单元测试
### 测试
#### 单元测试
在编译之后,`build/test`文件夹内即为`google test`框架生成的单元测试。
### 本地测试
#### 全局测试
在编译之后,`build/all_test`内的`bus_all_test.exe`就是全局本地测试程序。
运行这个程序,根据程序的提示选择适当的测试集,程序会自动读取选定的测试集中的配置文件和输入文件,并且将程序的输出和测试集中的输出文件进行对比,输出比对的结果。
程序现有的测试集存储在`all_test/test_cases`下面目前已有18个测试集对应测试集采用的调度策略可以查看测试集中的配置文件。
## 支持
如果你在学习/使用的过程中遇到的任何问题,或者有任何的意见与建议,可以在仓库中提交`Issue`和`Pull Request`同我们讨论。
当然,也可以给我发电子邮件。

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,274 +0,0 @@
# 概要设计
## main函数流程
![](main模块流程图.png)
## 轨道模块
> 轨道模块是比较基础的模块,许多模块都建立在这个模块的基础上
模块的主体是一个表示每个轨道节点的结构体。
### 创建结构体
```C
/**
* 创建轨道列表
* @param length 站点之间的距离
* @param node_num 站点的个数
* @return 指向首站的指针
*/
rail_node_t * CreateRails(int length, int node_num);
```
这个函数的难点应该是创建一个双向的循环链表。
### 寻找指定的站点
```C
/**
* 查找指定编号的站点指针
* @param rails 轨道的头节点地址
* @param id 需要查找的站点编号
* @return 需要查找站点指针
*/
rail_node_t *FindNode(rail_node_t rails, int id);
```
比较重要的工具函数,给定编号寻找对应的站点站点指针,不过没啥难度。
## 公交车模块
> 公交车模块就是比较复杂的模块了。
模块的主体是一个表示公交车的结构体。
### 运行公交车
```C
/**
* 每个时刻使公交车前进
* @param rails 轨道链表
* @param direction 公交车前进的方向
* @param bus 公交车
* @return 公交车是否到达站点
*/
int RunBus(rail_node_t* rails, bus_t bus, int direction);
```
这个函数不难,就是根据指定的方向让公交车前进,同时判断公交车是否到站。
## 请求模块
请求模块的核心是一个表示请求的结构体。
### 创建请求
```C
/**
* 创建请求
* @param query 请求链表队列
* @param type 请求的类型
* @param node 请求产生/指向的站点
*/
void CreateQuery(bus_query_t query, int type, rail_node_t node);
```
还是一个简单的链表创建函数,主要的关键点在于说明的第五点第四条:
> 如果在某个请求没有完成时再有相同的请求(请求类型和站点全部相同)发生,则该请求被抛弃
也就是在创建的时候要判断是否已存在相同的请求。
### 删除请求
> 删除请求其实就是处理请求的同义词
这个函数没啥意思,就是删除一个链表节点。
## 控制器模块
> 全程序最复杂的模块
### 时间计算
一个`int`类型的全局变量储存全局的时间。
```C
/**
* 时间增加
*/
void AddTime();
```
一个可有可无的函数,负责将时间加一。
> 可能后期删除,作用不明显。
### 策略简述
策略的相关函数会在公交车到站的时候调用。
策略一般包括两个函数,方向控制函数和请求处理函数。
### 先来先服务策略(FCFS)
> first come first serve
>
> 对于先来先服务策略车一次停站只完成一个请求即使在这个站点上即有乘车请求车内也有到该站的请求也只能按策略完成已经调度的那个请求。但是完成当前请求后如果发现时间序列上后续的一个或多个连续请求都恰好在同一站点即连续的同站点请求位置相同但请求类型不同则可以立即完成这些连续的同站点请求也就是说特殊情况下一次停车的1秒内可完成多个请求。
#### 方向
```C
/**
* 在先来先服务策略下应该前进的方向
* @param bus 公交车
* @param queries 请求队列链表
* @return 前进的方向
*/
int FCFSDirection(bus_t bus, bus_query_t queries);
```
直接给出最先的一个请求就可以了。
将给定的请求赋给全局变量。
#### 请求
```C
/**
* 在先来先服务策略下给出处理的请求
* @param bus 公交车
* @param queries 请求队列链表
* @return 需要处理的请求
*/
bus_query_t FCFSQuery(bus_t bus, bus_query_t queries);
```
按照指定的策略给出现在可以处理的请求。
在这里是当前所在站点和第一个请求指向站点相同是即可处理,而且连续处理。
### 最短寻找时间优先(SSTF)
> 对于最短寻找时间优先策略一次服务的目标请求一旦确定即使中途产生更优的请求也不可以更改。但如果新的请求恰好可以顺便服务同方向的站台请求或车内请求可以为新的请求停站。具体为程序计算离当前车的位置最近的请求如果没有请求则原地不动否则按最近的路线顺、逆时针去接。如果车途中遇到与车目前同方向的上车或下车请求可以停下一秒解决反方向的上车请求不停车。车服务完目标后反复此过程直到end。特别地当车到达目标站点时可以停一次车(1秒钟)完成该站点已接收的所有类型请求(区别于顺便站停靠)。
#### 方向
```C
/**
* 在最短寻找时间策略下应该前进的方向
* @param bus 公交车
* @param queries 请求队列链表
* @return 前进的方向
*/
int SSTFDirection(bus_t bus, bus_query_t queries);
```
这个函数比较难,求出最短前进的方向即可。
将处理的请求赋给全局变量。
#### 请求
```C
/**
* 在最短寻找时间策略给出处理的请求
* @param bus 公交车
* @param queries 请求队列链表
* @return 需要处理的请求
*/
bus_query_t SSTFQuery(bus_t bus, bus_query_t queries);
```
给出当前需要处理的请求。注意有些请求时可以处理的,有些请求时不能顺便处理的。
### 顺便服务策略(SCAN)
#### 方向
```C
/**
* 顺便服务的前进方向
* @param bus 公交车
* @param queries 请求队列链表
* @return 前进的方向
*/
int SCANDirection(bus_t bus, bus_query_t queries);
```
也是判断最短的前进方向,但是
## 输入输出模块
> 输入输出模块是比较基础的模块,主要作用就是调用其他模块实现的功能。
### 配置文件读取
```C
/**
* 读取配置文件,创建轨道链表,同时读取需要使用的策略
* @return 指向轨道链表的指针
*/
rail_node_t* ReadConfigFile();
```
这个函数需要完成三个任务:
- 解析配置文件。(重点)
- 调用函数创建轨道列表。
- 读取指定的策略。
### 打印当前状态
```C
/**
* 打印当前的状态
* @param rails 轨道链表
* @return 返回需输出的字符串
*/
char* PrintState();
```
输出的格式如下:
```
TIME:秒数
BUS:
position:0
target: 0000000000
STATION:
clockwise: 0000000000
counterclockwise: 0000000000
```
这个函数的实现应该不难,遍历几个链表就结束了。
> 返回一个字符串是为了便于测试,直接`printf`出来不好测试,也不符合解耦的设计策略。
### 读取输入
```C
/**
* 读取标准输入流中的输入
* @param inputString 输入的字符串
* @return 当前读取的状态
*/
int ReadInput(char* inputString);
```
这个函数的实现比较困难,在于读取对应的输入并调用相关的函数。
输出的`int`值是一系列定义的宏:
```C
#define IO_CLOCK 0 // 读取时钟指令
#define IO_READING 1 // 读取请求指令
#define IO_END 2 // 读取结束指令
```
便于main函数确定下一步的行为。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB