feat: 添加实时公交模拟
This commit is contained in:
87
PracticalTrain/DataStructure/include/bus.h
Normal file
87
PracticalTrain/DataStructure/include/bus.h
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// include/bus.h
|
||||||
|
#ifndef BUS_H
|
||||||
|
#define BUS_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "route.h"
|
||||||
|
#include "station.h"
|
||||||
|
|
||||||
|
#define MAX_BUSES 50
|
||||||
|
|
||||||
|
// 巴士状态枚举
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
BUS_MOVING, // 行驶中
|
||||||
|
BUS_STOPPING, // 停靠中
|
||||||
|
BUS_IDLE // 空闲/未启动
|
||||||
|
} BusStatus;
|
||||||
|
|
||||||
|
// 巴士方向枚举
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DIRECTION_FORWARD, // 正向(起点到终点)
|
||||||
|
DIRECTION_BACKWARD // 反向(终点到起点)
|
||||||
|
} BusDirection;
|
||||||
|
|
||||||
|
// 巴士结构体
|
||||||
|
typedef struct Bus
|
||||||
|
{
|
||||||
|
int id; // 巴士编号
|
||||||
|
int routeId; // 所属线路ID
|
||||||
|
BusStatus status; // 当前状态
|
||||||
|
BusDirection direction; // 行驶方向
|
||||||
|
|
||||||
|
int currentStationIndex; // 当前站点索引(在线路站点数组中的位置)
|
||||||
|
double progress; // 在两站之间的进度(0.0-1.0)
|
||||||
|
|
||||||
|
double speed; // 速度(km/h)
|
||||||
|
double stopTimeRemaining; // 剩余停靠时间(分钟)
|
||||||
|
|
||||||
|
double totalDistance; // 总行驶距离(km)
|
||||||
|
double totalTime; // 总运行时间(分钟)
|
||||||
|
} Bus;
|
||||||
|
|
||||||
|
// 巴士管理系统
|
||||||
|
typedef struct BusSystem
|
||||||
|
{
|
||||||
|
Bus buses[MAX_BUSES];
|
||||||
|
int busCount;
|
||||||
|
double systemTime; // 系统运行时间(分钟)
|
||||||
|
} BusSystem;
|
||||||
|
|
||||||
|
// 巴士系统初始化
|
||||||
|
BusSystem *createBusSystem();
|
||||||
|
void destroyBusSystem(BusSystem *system);
|
||||||
|
|
||||||
|
// 巴士管理
|
||||||
|
int addBus(BusSystem *system, int routeId, int startStationIndex,
|
||||||
|
BusDirection direction, double speed);
|
||||||
|
Bus *getBus(BusSystem *system, int busId);
|
||||||
|
void removeBus(BusSystem *system, int busId);
|
||||||
|
|
||||||
|
// 巴士模拟
|
||||||
|
void updateBusSystem(BusSystem *system, const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount, double deltaTime);
|
||||||
|
void updateSingleBus(Bus *bus, const BusRoute *route, const Station stations[],
|
||||||
|
int stationCount, double deltaTime);
|
||||||
|
|
||||||
|
// 显示功能
|
||||||
|
void displayBus(const Bus *bus, const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount);
|
||||||
|
void displayAllBuses(const BusSystem *system, const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount);
|
||||||
|
|
||||||
|
// 查询功能
|
||||||
|
void queryBusesOnRoute(const BusSystem *system, int routeId,
|
||||||
|
const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount);
|
||||||
|
void queryBusesAtStation(const BusSystem *system, int stationId,
|
||||||
|
const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount);
|
||||||
|
|
||||||
|
// 自动模拟
|
||||||
|
void runSimulation(BusSystem *system, const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount,
|
||||||
|
double duration, double timeStep);
|
||||||
|
|
||||||
|
#endif
|
||||||
57
PracticalTrain/DataStructure/setup.sh
Normal file
57
PracticalTrain/DataStructure/setup.sh
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 项目初始化脚本
|
||||||
|
|
||||||
|
echo "=========================================="
|
||||||
|
echo " 巴士路线管理系统 - 初始化脚本"
|
||||||
|
echo "=========================================="
|
||||||
|
|
||||||
|
# 创建目录结构
|
||||||
|
echo "创建目录结构..."
|
||||||
|
mkdir -p include src data obj bin
|
||||||
|
|
||||||
|
# 创建 stations.csv
|
||||||
|
echo "创建 data/stations.csv..."
|
||||||
|
cat > data/stations.csv << 'EOF'
|
||||||
|
id,name,latitude,longitude,stopTime
|
||||||
|
0,火车站,39.9042,116.4074,60
|
||||||
|
1,市中心,39.9100,116.4100,45
|
||||||
|
2,大学城,39.9200,116.4200,45
|
||||||
|
3,科技园,39.9300,116.4300,45
|
||||||
|
4,商业街,39.9150,116.4250,60
|
||||||
|
5,体育馆,39.9250,116.4350,45
|
||||||
|
6,公园,39.9180,116.4180,30
|
||||||
|
7,机场,39.9400,116.4400,90
|
||||||
|
8,医院,39.9050,116.4150,50
|
||||||
|
9,图书馆,39.9280,116.4280,40
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 创建 routes.csv
|
||||||
|
echo "创建 data/routes.csv..."
|
||||||
|
cat > data/routes.csv << 'EOF'
|
||||||
|
id,routeName,stationCount
|
||||||
|
0,1号线,4
|
||||||
|
0,1,2,3
|
||||||
|
5.0,6.0,7.0
|
||||||
|
1,2号线,5
|
||||||
|
0,4,5,7,9
|
||||||
|
8.0,6.0,10.0,5.0
|
||||||
|
2,3号线,4
|
||||||
|
1,6,4,2
|
||||||
|
4.0,5.0,6.0
|
||||||
|
3,4号线,3
|
||||||
|
8,1,3
|
||||||
|
7.0,12.0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✓ 目录结构创建完成"
|
||||||
|
echo "✓ 数据文件创建完成"
|
||||||
|
echo ""
|
||||||
|
echo "现在可以运行以下命令:"
|
||||||
|
echo " make # 编译项目"
|
||||||
|
echo " make run # 运行程序"
|
||||||
|
echo ""
|
||||||
|
echo "数据文件位置:"
|
||||||
|
echo " - data/stations.csv (站点数据)"
|
||||||
|
echo " - data/routes.csv (线路数据)"
|
||||||
|
echo "=========================================="
|
||||||
338
PracticalTrain/DataStructure/src/bus.c
Normal file
338
PracticalTrain/DataStructure/src/bus.c
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
// src/bus.c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "../include/bus.h"
|
||||||
|
|
||||||
|
// 创建巴士系统
|
||||||
|
BusSystem* createBusSystem() {
|
||||||
|
BusSystem* system = (BusSystem*)malloc(sizeof(BusSystem));
|
||||||
|
system->busCount = 0;
|
||||||
|
system->systemTime = 0.0;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_BUSES; i++) {
|
||||||
|
system->buses[i].id = -1;
|
||||||
|
system->buses[i].status = BUS_IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 销毁巴士系统
|
||||||
|
void destroyBusSystem(BusSystem* system) {
|
||||||
|
if (system) {
|
||||||
|
free(system);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加巴士
|
||||||
|
int addBus(BusSystem* system, int routeId, int startStationIndex,
|
||||||
|
BusDirection direction, double speed) {
|
||||||
|
if (system->busCount >= MAX_BUSES) {
|
||||||
|
printf("错误: 巴士数量已达上限\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int busId = system->busCount;
|
||||||
|
Bus* bus = &system->buses[busId];
|
||||||
|
|
||||||
|
bus->id = busId;
|
||||||
|
bus->routeId = routeId;
|
||||||
|
bus->status = BUS_STOPPING; // 初始在站点停靠
|
||||||
|
bus->direction = direction;
|
||||||
|
bus->currentStationIndex = startStationIndex;
|
||||||
|
bus->progress = 0.0;
|
||||||
|
bus->speed = speed;
|
||||||
|
bus->stopTimeRemaining = 0.0;
|
||||||
|
bus->totalDistance = 0.0;
|
||||||
|
bus->totalTime = 0.0;
|
||||||
|
|
||||||
|
system->busCount++;
|
||||||
|
printf("巴士 #%d 已添加到线路 %d\n", busId, routeId);
|
||||||
|
|
||||||
|
return busId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取巴士
|
||||||
|
Bus* getBus(BusSystem* system, int busId) {
|
||||||
|
if (busId >= 0 && busId < system->busCount) {
|
||||||
|
return &system->buses[busId];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除巴士
|
||||||
|
void removeBus(BusSystem* system, int busId) {
|
||||||
|
if (busId >= 0 && busId < system->busCount) {
|
||||||
|
system->buses[busId].status = BUS_IDLE;
|
||||||
|
printf("巴士 #%d 已移除\n", busId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算两点之间的距离(简化版,使用欧氏距离)
|
||||||
|
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
|
||||||
|
double dx = (lon2 - lon1) * 111.0; // 1度经度约111km
|
||||||
|
double dy = (lat2 - lat1) * 111.0; // 1度纬度约111km
|
||||||
|
return sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新单个巴士状态
|
||||||
|
void updateSingleBus(Bus* bus, const BusRoute* route, const Station stations[],
|
||||||
|
int stationCount, double deltaTime) {
|
||||||
|
if (bus->status == BUS_IDLE) return;
|
||||||
|
|
||||||
|
// 如果正在停靠
|
||||||
|
if (bus->status == BUS_STOPPING) {
|
||||||
|
bus->stopTimeRemaining -= deltaTime;
|
||||||
|
|
||||||
|
if (bus->stopTimeRemaining <= 0) {
|
||||||
|
// 停靠结束,开始移动
|
||||||
|
bus->status = BUS_MOVING;
|
||||||
|
bus->stopTimeRemaining = 0.0;
|
||||||
|
|
||||||
|
// 检查是否到达终点
|
||||||
|
if (bus->direction == DIRECTION_FORWARD) {
|
||||||
|
if (bus->currentStationIndex >= route->stationCount - 1) {
|
||||||
|
// 到达终点,掉头
|
||||||
|
bus->direction = DIRECTION_BACKWARD;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bus->currentStationIndex <= 0) {
|
||||||
|
// 到达起点,掉头
|
||||||
|
bus->direction = DIRECTION_FORWARD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果正在行驶
|
||||||
|
if (bus->status == BUS_MOVING) {
|
||||||
|
int fromIdx = bus->currentStationIndex;
|
||||||
|
int toIdx;
|
||||||
|
|
||||||
|
if (bus->direction == DIRECTION_FORWARD) {
|
||||||
|
toIdx = fromIdx + 1;
|
||||||
|
if (toIdx >= route->stationCount) {
|
||||||
|
bus->status = BUS_STOPPING;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toIdx = fromIdx - 1;
|
||||||
|
if (toIdx < 0) {
|
||||||
|
bus->status = BUS_STOPPING;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算这一段的行驶时间
|
||||||
|
int segmentIdx = (bus->direction == DIRECTION_FORWARD) ? fromIdx : toIdx;
|
||||||
|
double segmentTime = route->segmentTimes[segmentIdx];
|
||||||
|
|
||||||
|
// 计算进度增量
|
||||||
|
double progressDelta = deltaTime / segmentTime;
|
||||||
|
bus->progress += progressDelta;
|
||||||
|
|
||||||
|
// 计算行驶距离
|
||||||
|
int fromStationId = route->stations[fromIdx];
|
||||||
|
int toStationId = route->stations[toIdx];
|
||||||
|
int fromStIdx = findStationById(stations, stationCount, fromStationId);
|
||||||
|
int toStIdx = findStationById(stations, stationCount, toStationId);
|
||||||
|
|
||||||
|
if (fromStIdx != -1 && toStIdx != -1) {
|
||||||
|
double distance = calculateDistance(
|
||||||
|
stations[fromStIdx].latitude, stations[fromStIdx].longitude,
|
||||||
|
stations[toStIdx].latitude, stations[toStIdx].longitude
|
||||||
|
);
|
||||||
|
bus->totalDistance += distance * progressDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果到达下一站
|
||||||
|
if (bus->progress >= 1.0) {
|
||||||
|
bus->progress = 0.0;
|
||||||
|
bus->currentStationIndex = toIdx;
|
||||||
|
bus->status = BUS_STOPPING;
|
||||||
|
|
||||||
|
// 设置停靠时间
|
||||||
|
int stationId = route->stations[toIdx];
|
||||||
|
int stIdx = findStationById(stations, stationCount, stationId);
|
||||||
|
if (stIdx != -1) {
|
||||||
|
bus->stopTimeRemaining = stations[stIdx].stopTime / 60.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bus->totalTime += deltaTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新整个巴士系统
|
||||||
|
void updateBusSystem(BusSystem* system, const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount, double deltaTime) {
|
||||||
|
system->systemTime += deltaTime;
|
||||||
|
|
||||||
|
for (int i = 0; i < system->busCount; i++) {
|
||||||
|
Bus* bus = &system->buses[i];
|
||||||
|
if (bus->status != BUS_IDLE && bus->routeId >= 0 && bus->routeId < routeCount) {
|
||||||
|
updateSingleBus(bus, &routes[bus->routeId], stations, stationCount, deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示巴士状态
|
||||||
|
void displayBus(const Bus* bus, const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount) {
|
||||||
|
if (bus->status == BUS_IDLE) return;
|
||||||
|
|
||||||
|
printf("\n--- 巴士 #%d ---\n", bus->id);
|
||||||
|
|
||||||
|
if (bus->routeId >= 0 && bus->routeId < routeCount) {
|
||||||
|
printf("线路: %s\n", routes[bus->routeId].routeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("方向: %s\n", bus->direction == DIRECTION_FORWARD ? "正向" : "反向");
|
||||||
|
|
||||||
|
const char* statusStr;
|
||||||
|
switch (bus->status) {
|
||||||
|
case BUS_MOVING: statusStr = "行驶中"; break;
|
||||||
|
case BUS_STOPPING: statusStr = "停靠中"; break;
|
||||||
|
default: statusStr = "空闲"; break;
|
||||||
|
}
|
||||||
|
printf("状态: %s\n", statusStr);
|
||||||
|
|
||||||
|
if (bus->routeId >= 0 && bus->routeId < routeCount) {
|
||||||
|
int stationId = routes[bus->routeId].stations[bus->currentStationIndex];
|
||||||
|
int stIdx = findStationById(stations, stationCount, stationId);
|
||||||
|
if (stIdx != -1) {
|
||||||
|
printf("当前位置: %s", stations[stIdx].name);
|
||||||
|
|
||||||
|
if (bus->status == BUS_MOVING) {
|
||||||
|
int nextIdx;
|
||||||
|
if (bus->direction == DIRECTION_FORWARD) {
|
||||||
|
nextIdx = bus->currentStationIndex + 1;
|
||||||
|
} else {
|
||||||
|
nextIdx = bus->currentStationIndex - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextIdx >= 0 && nextIdx < routes[bus->routeId].stationCount) {
|
||||||
|
int nextStationId = routes[bus->routeId].stations[nextIdx];
|
||||||
|
int nextStIdx = findStationById(stations, stationCount, nextStationId);
|
||||||
|
if (nextStIdx != -1) {
|
||||||
|
printf(" -> %s (进度: %.1f%%)",
|
||||||
|
stations[nextStIdx].name, bus->progress * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (bus->status == BUS_STOPPING) {
|
||||||
|
printf(" (停靠中, 剩余 %.1f 秒)", bus->stopTimeRemaining * 60);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("速度: %.1f km/h\n", bus->speed);
|
||||||
|
printf("总行驶距离: %.2f km\n", bus->totalDistance);
|
||||||
|
printf("总运行时间: %.1f 分钟\n", bus->totalTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示所有巴士
|
||||||
|
void displayAllBuses(const BusSystem* system, const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount) {
|
||||||
|
printf("\n========== 巴士实时状态 ==========\n");
|
||||||
|
printf("系统时间: %.1f 分钟\n", system->systemTime);
|
||||||
|
printf("运行中巴士数: %d\n", system->busCount);
|
||||||
|
|
||||||
|
int activeBuses = 0;
|
||||||
|
for (int i = 0; i < system->busCount; i++) {
|
||||||
|
if (system->buses[i].status != BUS_IDLE) {
|
||||||
|
displayBus(&system->buses[i], routes, routeCount, stations, stationCount);
|
||||||
|
activeBuses++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeBuses == 0) {
|
||||||
|
printf("\n当前没有运行中的巴士\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("==================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询指定线路上的巴士
|
||||||
|
void queryBusesOnRoute(const BusSystem* system, int routeId,
|
||||||
|
const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount) {
|
||||||
|
printf("\n========== 线路 %s 上的巴士 ==========\n", routes[routeId].routeName);
|
||||||
|
|
||||||
|
int found = 0;
|
||||||
|
for (int i = 0; i < system->busCount; i++) {
|
||||||
|
if (system->buses[i].routeId == routeId && system->buses[i].status != BUS_IDLE) {
|
||||||
|
displayBus(&system->buses[i], routes, routeCount, stations, stationCount);
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found == 0) {
|
||||||
|
printf("该线路上没有巴士\n");
|
||||||
|
}
|
||||||
|
printf("==================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询指定站点的巴士
|
||||||
|
void queryBusesAtStation(const BusSystem* system, int stationId,
|
||||||
|
const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount) {
|
||||||
|
int stIdx = findStationById(stations, stationCount, stationId);
|
||||||
|
if (stIdx == -1) return;
|
||||||
|
|
||||||
|
printf("\n========== %s 站的巴士 ==========\n", stations[stIdx].name);
|
||||||
|
|
||||||
|
int found = 0;
|
||||||
|
for (int i = 0; i < system->busCount; i++) {
|
||||||
|
Bus* bus = (Bus*)&system->buses[i];
|
||||||
|
if (bus->status == BUS_IDLE || bus->routeId < 0 || bus->routeId >= routeCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int currentStationId = routes[bus->routeId].stations[bus->currentStationIndex];
|
||||||
|
|
||||||
|
// 检查是否在该站点或即将到达
|
||||||
|
if (currentStationId == stationId && bus->status == BUS_STOPPING) {
|
||||||
|
displayBus(bus, routes, routeCount, stations, stationCount);
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found == 0) {
|
||||||
|
printf("该站点当前没有巴士\n");
|
||||||
|
}
|
||||||
|
printf("==================================\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行模拟
|
||||||
|
void runSimulation(BusSystem* system, const BusRoute routes[], int routeCount,
|
||||||
|
const Station stations[], int stationCount,
|
||||||
|
double duration, double timeStep) {
|
||||||
|
printf("\n========== 开始模拟 ==========\n");
|
||||||
|
printf("模拟时长: %.1f 分钟\n", duration);
|
||||||
|
printf("时间步长: %.1f 分钟\n", timeStep);
|
||||||
|
printf("==============================\n\n");
|
||||||
|
|
||||||
|
double elapsedTime = 0.0;
|
||||||
|
int updateCount = 0;
|
||||||
|
|
||||||
|
while (elapsedTime < duration) {
|
||||||
|
updateBusSystem(system, routes, routeCount, stations, stationCount, timeStep);
|
||||||
|
elapsedTime += timeStep;
|
||||||
|
updateCount++;
|
||||||
|
|
||||||
|
// 每5次更新显示一次状态
|
||||||
|
if (updateCount % 5 == 0) {
|
||||||
|
printf("\n[时间: %.1f 分钟]\n", system->systemTime);
|
||||||
|
displayAllBuses(system, routes, routeCount, stations, stationCount);
|
||||||
|
printf("\n按 Enter 继续...");
|
||||||
|
getchar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n========== 模拟结束 ==========\n");
|
||||||
|
printf("总运行时间: %.1f 分钟\n", system->systemTime);
|
||||||
|
displayAllBuses(system, routes, routeCount, stations, stationCount);
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "../include/station.h"
|
#include "../include/station.h"
|
||||||
#include "../include/route.h"
|
#include "../include/route.h"
|
||||||
#include "../include/graph.h"
|
#include "../include/graph.h"
|
||||||
|
#include "../include/bus.h"
|
||||||
|
|
||||||
#define MAX_ROUTES 20
|
#define MAX_ROUTES 20
|
||||||
|
|
||||||
@@ -14,28 +15,184 @@ BusRoute routes[MAX_ROUTES];
|
|||||||
int stationCount = 0;
|
int stationCount = 0;
|
||||||
int routeCount = 0;
|
int routeCount = 0;
|
||||||
Graph *graph = NULL;
|
Graph *graph = NULL;
|
||||||
|
BusSystem *busSystem = NULL;
|
||||||
|
|
||||||
// 函数声明
|
// 函数声明
|
||||||
void printMenu();
|
void printMenu();
|
||||||
void queryRoute();
|
void queryRoute();
|
||||||
|
void manageBuses();
|
||||||
|
void startSimulation();
|
||||||
void saveQueryResult(const char *filename, const char *startName, const char *endName,
|
void saveQueryResult(const char *filename, const char *startName, const char *endName,
|
||||||
PathNode *path, double totalTime);
|
PathNode *path, double totalTime);
|
||||||
|
|
||||||
// 打印菜单
|
// 打印菜单
|
||||||
void printMenu() {
|
void printMenu()
|
||||||
|
{
|
||||||
printf("\n╔════════════════════════════════╗\n");
|
printf("\n╔════════════════════════════════╗\n");
|
||||||
printf("║ 巴士路线管理系统 ║\n");
|
printf("║ 巴士路线管理系统 ║\n");
|
||||||
printf("╠════════════════════════════════╣\n");
|
printf("╠════════════════════════════════╣\n");
|
||||||
printf("║ 1. 查询最短路径 ║\n");
|
printf("║ 1. 查询最短路径 ║\n");
|
||||||
printf("║ 2. 显示所有站点 ║\n");
|
printf("║ 2. 显示所有站点 ║\n");
|
||||||
printf("║ 3. 显示所有线路 ║\n");
|
printf("║ 3. 显示所有线路 ║\n");
|
||||||
printf("║ 4. 退出系统 ║\n");
|
printf("║ 4. 巴士管理 ║\n");
|
||||||
|
printf("║ 5. 启动实时模拟 ║\n");
|
||||||
|
printf("║ 6. 退出系统 ║\n");
|
||||||
printf("╚════════════════════════════════╝\n");
|
printf("╚════════════════════════════════╝\n");
|
||||||
printf("请选择功能 (1-4): ");
|
printf("请选择功能 (1-6): ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询路线
|
// 巴士管理菜单
|
||||||
void queryRoute() {
|
void manageBuses()
|
||||||
|
{
|
||||||
|
int choice;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
printf("\n╔════════════════════════════════╗\n");
|
||||||
|
printf("║ 巴士管理菜单 ║\n");
|
||||||
|
printf("╠════════════════════════════════╣\n");
|
||||||
|
printf("║ 1. 添加巴士 ║\n");
|
||||||
|
printf("║ 2. 查看所有巴士 ║\n");
|
||||||
|
printf("║ 3. 查询线路上的巴士 ║\n");
|
||||||
|
printf("║ 4. 查询站点的巴士 ║\n");
|
||||||
|
printf("║ 5. 手动更新一次(1分钟) ║\n");
|
||||||
|
printf("║ 6. 返回主菜单 ║\n");
|
||||||
|
printf("╚════════════════════════════════╝\n");
|
||||||
|
printf("请选择 (1-6): ");
|
||||||
|
|
||||||
|
if (scanf("%d", &choice) != 1)
|
||||||
|
{
|
||||||
|
while (getchar() != '\n')
|
||||||
|
;
|
||||||
|
printf("无效输入\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (choice)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
// 添加巴士
|
||||||
|
printf("\n可用线路:\n");
|
||||||
|
for (int i = 0; i < routeCount; i++)
|
||||||
|
{
|
||||||
|
printf(" %d. %s\n", i, routes[i].routeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
int routeId, startIdx, direction;
|
||||||
|
double speed;
|
||||||
|
|
||||||
|
printf("选择线路ID: ");
|
||||||
|
scanf("%d", &routeId);
|
||||||
|
|
||||||
|
if (routeId < 0 || routeId >= routeCount)
|
||||||
|
{
|
||||||
|
printf("无效的线路ID\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("选择起始站点索引 (0-%d): ", routes[routeId].stationCount - 1);
|
||||||
|
scanf("%d", &startIdx);
|
||||||
|
|
||||||
|
printf("选择方向 (0-正向, 1-反向): ");
|
||||||
|
scanf("%d", &direction);
|
||||||
|
|
||||||
|
printf("输入速度(km/h): ");
|
||||||
|
scanf("%lf", &speed);
|
||||||
|
|
||||||
|
addBus(busSystem, routeId, startIdx,
|
||||||
|
direction == 0 ? DIRECTION_FORWARD : DIRECTION_BACKWARD, speed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// 查看所有巴士
|
||||||
|
displayAllBuses(busSystem, routes, routeCount, stations, stationCount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
// 查询线路上的巴士
|
||||||
|
int routeId;
|
||||||
|
printf("输入线路ID: ");
|
||||||
|
scanf("%d", &routeId);
|
||||||
|
|
||||||
|
if (routeId >= 0 && routeId < routeCount)
|
||||||
|
{
|
||||||
|
queryBusesOnRoute(busSystem, routeId, routes, routeCount,
|
||||||
|
stations, stationCount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("无效的线路ID\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
// 查询站点的巴士
|
||||||
|
char stationName[MAX_NAME];
|
||||||
|
printf("输入站点名称: ");
|
||||||
|
scanf("%s", stationName);
|
||||||
|
|
||||||
|
int stationId = findStationByName(stations, stationCount, stationName);
|
||||||
|
if (stationId != -1)
|
||||||
|
{
|
||||||
|
queryBusesAtStation(busSystem, stationId, routes, routeCount,
|
||||||
|
stations, stationCount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("找不到站点 '%s'\n", stationName);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
// 手动更新
|
||||||
|
printf("更新巴士位置(1分钟)...\n");
|
||||||
|
updateBusSystem(busSystem, routes, routeCount, stations, stationCount, 1.0);
|
||||||
|
displayAllBuses(busSystem, routes, routeCount, stations, stationCount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("无效选择\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动模拟
|
||||||
|
void startSimulation()
|
||||||
|
{
|
||||||
|
if (busSystem->busCount == 0)
|
||||||
|
{
|
||||||
|
printf("\n错误: 请先添加巴士\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double duration;
|
||||||
|
printf("\n输入模拟时长(分钟): ");
|
||||||
|
scanf("%lf", &duration);
|
||||||
|
|
||||||
|
printf("开始自动模拟...\n");
|
||||||
|
printf("提示: 每5次更新会暂停显示状态\n");
|
||||||
|
|
||||||
|
// 清空输入缓冲
|
||||||
|
while (getchar() != '\n')
|
||||||
|
;
|
||||||
|
|
||||||
|
runSimulation(busSystem, routes, routeCount, stations, stationCount, duration, 1.0);
|
||||||
|
}
|
||||||
|
void queryRoute()
|
||||||
|
{
|
||||||
char startName[MAX_NAME], endName[MAX_NAME];
|
char startName[MAX_NAME], endName[MAX_NAME];
|
||||||
|
|
||||||
printf("\n请输入起点站名称: ");
|
printf("\n请输入起点站名称: ");
|
||||||
@@ -46,11 +203,13 @@ void queryRoute() {
|
|||||||
int startId = findStationByName(stations, stationCount, startName);
|
int startId = findStationByName(stations, stationCount, startName);
|
||||||
int endId = findStationByName(stations, stationCount, endName);
|
int endId = findStationByName(stations, stationCount, endName);
|
||||||
|
|
||||||
if (startId == -1) {
|
if (startId == -1)
|
||||||
|
{
|
||||||
printf("错误: 找不到站点 '%s'\n", startName);
|
printf("错误: 找不到站点 '%s'\n", startName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (endId == -1) {
|
if (endId == -1)
|
||||||
|
{
|
||||||
printf("错误: 找不到站点 '%s'\n", endName);
|
printf("错误: 找不到站点 '%s'\n", endName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -58,7 +217,8 @@ void queryRoute() {
|
|||||||
double totalTime;
|
double totalTime;
|
||||||
PathNode *path = dijkstra(graph, startId, endId, &totalTime);
|
PathNode *path = dijkstra(graph, startId, endId, &totalTime);
|
||||||
|
|
||||||
if (!path || totalTime < 0) {
|
if (!path || totalTime < 0)
|
||||||
|
{
|
||||||
printf("\n没有找到从 %s 到 %s 的路线\n", startName, endName);
|
printf("\n没有找到从 %s 到 %s 的路线\n", startName, endName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -81,9 +241,11 @@ void queryRoute() {
|
|||||||
|
|
||||||
// 保存查询结果
|
// 保存查询结果
|
||||||
void saveQueryResult(const char *filename, const char *startName, const char *endName,
|
void saveQueryResult(const char *filename, const char *startName, const char *endName,
|
||||||
PathNode* path, double totalTime) {
|
PathNode *path, double totalTime)
|
||||||
|
{
|
||||||
FILE *fp = fopen(filename, "a");
|
FILE *fp = fopen(filename, "a");
|
||||||
if (!fp) {
|
if (!fp)
|
||||||
|
{
|
||||||
printf("警告: 无法保存查询结果到文件\n");
|
printf("警告: 无法保存查询结果到文件\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -95,11 +257,14 @@ void saveQueryResult(const char* filename, const char* startName, const char* en
|
|||||||
fprintf(fp, "路径: ");
|
fprintf(fp, "路径: ");
|
||||||
|
|
||||||
PathNode *curr = path;
|
PathNode *curr = path;
|
||||||
while (curr) {
|
while (curr)
|
||||||
|
{
|
||||||
int stationIdx = findStationById(stations, stationCount, curr->stationId);
|
int stationIdx = findStationById(stations, stationCount, curr->stationId);
|
||||||
if (stationIdx != -1) {
|
if (stationIdx != -1)
|
||||||
|
{
|
||||||
fprintf(fp, "%s", stations[stationIdx].name);
|
fprintf(fp, "%s", stations[stationIdx].name);
|
||||||
if (curr->next) {
|
if (curr->next)
|
||||||
|
{
|
||||||
fprintf(fp, " -> ");
|
fprintf(fp, " -> ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +276,8 @@ void saveQueryResult(const char* filename, const char* startName, const char* en
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 主函数
|
// 主函数
|
||||||
int main() {
|
int main()
|
||||||
|
{
|
||||||
printf("========================================\n");
|
printf("========================================\n");
|
||||||
printf(" 巴士路线管理系统 v1.0\n");
|
printf(" 巴士路线管理系统 v1.0\n");
|
||||||
printf("========================================\n\n");
|
printf("========================================\n\n");
|
||||||
@@ -119,13 +285,15 @@ int main() {
|
|||||||
// 加载数据
|
// 加载数据
|
||||||
printf("正在加载系统数据...\n");
|
printf("正在加载系统数据...\n");
|
||||||
stationCount = loadStations("data/stations.csv", stations, MAX_STATIONS);
|
stationCount = loadStations("data/stations.csv", stations, MAX_STATIONS);
|
||||||
if (stationCount == 0) {
|
if (stationCount == 0)
|
||||||
|
{
|
||||||
printf("错误: 无法加载站点数据\n");
|
printf("错误: 无法加载站点数据\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
routeCount = loadRoutes("data/routes.csv", routes, MAX_ROUTES);
|
routeCount = loadRoutes("data/routes.csv", routes, MAX_ROUTES);
|
||||||
if (routeCount == 0) {
|
if (routeCount == 0)
|
||||||
|
{
|
||||||
printf("错误: 无法加载线路数据\n");
|
printf("错误: 无法加载线路数据\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -134,20 +302,28 @@ int main() {
|
|||||||
graph = createGraph(stationCount);
|
graph = createGraph(stationCount);
|
||||||
buildGraphFromRoutes(graph, routes, routeCount, stations, stationCount);
|
buildGraphFromRoutes(graph, routes, routeCount, stations, stationCount);
|
||||||
|
|
||||||
|
// 创建巴士系统
|
||||||
|
busSystem = createBusSystem();
|
||||||
|
printf("巴士系统初始化完成\n");
|
||||||
|
|
||||||
printf("\n系统初始化完成!\n");
|
printf("\n系统初始化完成!\n");
|
||||||
|
|
||||||
// 主循环
|
// 主循环
|
||||||
int choice;
|
int choice;
|
||||||
while (1) {
|
while (1)
|
||||||
|
{
|
||||||
printMenu();
|
printMenu();
|
||||||
|
|
||||||
if (scanf("%d", &choice) != 1) {
|
if (scanf("%d", &choice) != 1)
|
||||||
while (getchar() != '\n');
|
{
|
||||||
printf("无效输入,请输入数字1-4\n");
|
while (getchar() != '\n')
|
||||||
|
;
|
||||||
|
printf("无效输入,请输入数字1-6\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (choice) {
|
switch (choice)
|
||||||
|
{
|
||||||
case 1:
|
case 1:
|
||||||
queryRoute();
|
queryRoute();
|
||||||
break;
|
break;
|
||||||
@@ -158,11 +334,18 @@ int main() {
|
|||||||
displayAllRoutes(routes, routeCount, stations, stationCount);
|
displayAllRoutes(routes, routeCount, stations, stationCount);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
manageBuses();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
startSimulation();
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
printf("\n感谢使用巴士路线管理系统!\n");
|
printf("\n感谢使用巴士路线管理系统!\n");
|
||||||
destroyGraph(graph);
|
destroyGraph(graph);
|
||||||
|
destroyBusSystem(busSystem);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
printf("无效选择,请输入1-4\n");
|
printf("无效选择,请输入1-6\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user