——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
在传智播客的视频中有这样的一个题目:交通灯模拟。今天我也尝试做一个:
交通灯模拟的需求分析
- 交通灯是一个路口交通控制系统,交通灯模拟即又要模拟路口的交通,也要模拟交通灯控制
- 路口的交通需求包括车流通过和行人通过,行人走人行道(与车流交错)或是天桥/地下,车流走交通灯路口或是立交桥。
- 交通灯控制有控制需求的交错点,比如行人与车流的交错,车流之间的交错,一个交通灯控制一个流或者多个同向流。
- 交通灯有的是双向同步的,即此方向可去,则对面方向也可来;有的则不是,仅仅控制一个方向。对于双向交通灯,他们之间的状态是同步的。行人只有双向流,所以行人交通灯都是双向的。
- 路口由多个端点组成,每个端点有一般不多于2条人行道,数条机动车道,这里按车流目的端点将机动车分为不同的流,车流来自端点,去向也是端点,行人来自人行道,去向另一个人行道。
- 对于寻路问题,这里不考虑,只模拟通过一次路口的情况,也就是说,忽略行人多次穿过路口的情况。对于车流,也假设一次即可保证通过,不存在中间点或者中心环路这些复杂情况。
- 对于路口交错,交通灯系统应该提供至少一个可行的通过管理方案,这个方案应该可以切换。这里忽略特权车辆和交通违章,视为一切公平和谐。
- 模拟系统应该以随机频率向各个流中加入行人或车,按一定时间间隔或是交通灯变化时报告当前阻塞状况(即每个流的数量)和通过情况(相对于上次报告),加入应该是模拟并行的,通过路口应该是完全符合交通规则和交通灯控制状态的。
- 忽略GUI设计,只需模拟在日志或是控制台输出即可。
- 本次仅模拟一个双向2车道带有双边人行道的南北x东西的交叉路口,没有立交和天桥等无障碍设施。
第一轮设计
- 路口运行由一个模拟器执行,交通灯控制系统自身实现Runnable,由模拟器开启线程执行,路口的每个端点开启一个线程随机加入排队对象,路口开启一个线程依次从可通行的流中拉取对象通过路口。类 TrafficSimulator.
- 通过接口和可通过接口
- 行人和车辆实现通过者接口,路口实现可通过接口,路口包含交通流(只计到路口,不计离开的)。
- 街道路端,街道包含人行道和车流。
- 街道路端和人行道实现端点,端点是穿过路口的两端。
- 人行流和车流实现交通流,人流在人行道上,目标是对端人行道;车流在街道路端上,目标是另一个街道路端。
- 本次实际模拟的交通路口有4个街道路端,12条车流,8个人流,其中4条人流是完全不受控的(街角转弯),其他均受控于交通灯。
- 流知晓控制自己的控制者(交通灯),当控制者为空时,流将不停的通行。
- 交通灯有3种状态,红绿黄,本次忽略黄的作用,仅做切换和显示,只有红设计为可令阻断交通流。
一次代码如下:`
/**
* 交通模拟器
* @author lz
*
*/
public class TrafficSimulator {
public static void main(String[] args) {
//构建交叉路口
//启动交通控制器
//启动所有交通流
//启动随机加入模拟器
}
}
/**
* 通过者
* @author lz
*
*/
public interface Traverse {
void traverse(Traversable block);
}
/**
* 可通过的阻碍
* @author lz
*
*/
public interface Traversable {
}
/**
* 交通端点,穿过的起点或是终点
* @author lz
*
*/
public interface Peer {
}
/**
* 街道端点
* 街道端点有2个人行道和3条车流
* @author lz
*
*/
public class StreetPeer implements Peer {
/**
* 左右人行道
*/
Pavement leftPavement,rightPavement;
/**
* 左转,前行,右转车流
*/
VehicleStream leftStream,forwardStream,rightStream;
}
/**
* 人行道
* 人行道有2条人流,转角和横穿街道
* @author lz
*
*/
public class Pavement implements Peer {
/**
* 人流,转角和横穿街道
*/
StreamOfPeople turnCorner,crossStreet;
}
/**
* 交通流,指的是等待通过路口的有同一目的一个队列,
* @author lz
*
*/
public abstract class TrafficStream {
/**
* 当前流的控制令
*/
TrafficCommander commander;
/**
* 目的端点
*/
Peer destination;
/**
* 队列中数目
*/
int waitingCount;
public TrafficStream(TrafficCommander commander, Peer destination) {
super();
this.commander = commander;
this.destination = destination;
this.waitingCount = 0;
}
}
/**
* 行人交通灯
* @author lz
*
*/
public class WalkTrafficLight extends TrafficLight {
@Override
TrafficLightState nextState() {
//行人交通灯只有红绿两色
return this.state == TrafficLightState.GREEN ? TrafficLightState.RED
: TrafficLightState.GREEN;
}
}
/**
* 人流
* @author lz
*
*/
public class StreamOfPeople extends TrafficStream {
public StreamOfPeople(TrafficCommander commander, Pavement destination) {
super(commander, destination);
}
}
/**
* 交通信令
* @author lz
*
*/
public interface TrafficCommander {
/**
* @return 是否允许通行
*/
boolean currentAllowed();
}
/**
* 车流
* @author lz
*
*/
public class VehicleStream extends TrafficStream{
public VehicleStream(TrafficCommander commander, StreetPeer destination) {
super(commander, destination);
}
}
/**
* 基于交通灯的路口交通管理系统
* @author lz
*
*/
public class TrafficLightController implements TrafficController {
}