【学习并改进】黑马程序员-张孝祥-交通灯管理系统业务

本文介绍了一个交通灯系统模拟程序的设计与实现,通过Java语言构建了一套包含12个方向的交通灯系统,利用多线程技术实现了不同方向的车辆运行与交通灯控制的交互。
import java.util.*; //导入工具包
import java.util.concurrent.*; //导入工具子包并发包

/**
 * 产生多个方向的路线和整个交通灯系统
 * @author 张孝祥-黑马程序员
 * @editor 魏安-黑马程序员
 */
public class Traffic //交通灯类
{
	public static void main(String[] Ann) //主函数
	{
		String[] directions = {"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"}; //定义字符串数组为方向路线
		int index = directions.length - 1; //定义数组角标
		Lamp lamp = Lamp.valueOf(directions[index]); //定义枚举值为数组对应角标值
		boolean flag = ( lamp == Lamp.S2E || lamp == Lamp.N2W || lamp == Lamp.E2N || lamp == Lamp.W2S ); //定义判断标记为虚拟绿灯状态
		if ( ! flag ) //如果不符合标记条件
		{
			for ( int i = 0; i < directions.length; i++ ) //对整个数组遍历
			{
				new Road( directions[i] ); //建立道路类对象并传入数组对应角标参数值
			}
			new LampController(lamp); //建立灯控制器对象
		}
		else //否则执行
		{
			System.out.println("目前全部为绿灯状态,无需灯控制器,观察道路车流!"); //打印信息
			for ( int i = 0; i < directions.length; i++ ) //对整个数组遍历
			{
				new Road( directions[i] ); //建立道路类对象并传入数组对应角标参数值
			}
		}
	}
}

/**
 * E = East = 东 W = West = 西
 * N = North = 北 S = South = 南
 * 东西和南北为直线通行类 WE & SN
 * 东南和西北为转折通行类 SE & WN
 * 每个Lamp枚举元素代表一个方向上的灯,总共有12个方向,共有12个Lamp元素。
 * 有如下一些方向上的灯,每两个形成一组,一组灯同时变绿或变红。
 * 所以程序代码只需要控制每组灯中的一个灯即可:
 * s2n,n2s =
 * s2w,n2e ^
 * e2w,w2e =
 * e2s,w2n ^
 * -------
 * s2e,n2w x
 * e2n,w2s x
 * 上面最后两行的灯是虚拟的,由于从南向东和从西向北、以及它们的对应方向不受红绿灯的控制,
 * 所以可以假想它们总是绿灯。
 * @author 张孝祥-黑马程序员
 * @editor 魏安-黑马程序员
 */
enum Lamp //灯枚举
{
	S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false), //定义枚举元素为单向控制灯
	N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false), //定义枚举元素为单向相反控制灯
	S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true); //定义枚举元素为总是绿灯通行
	private boolean lighted; //定义判断变量为绿灯通行开关
	private String opposite; //定义字符串变量为与当前灯相同状态对应灯
	private String next; //定义字符串变量为当前灯状态改变时下个会变绿灯
	private Lamp(String opposite,String next,boolean lighted) //枚举构造函数
	{
		this.opposite = opposite; //锁定传入参数变量
		this.next = next; //锁定传入参数变量
		this.lighted = lighted; //锁定传入参数变量
	}
	public boolean isLighted() //判断开关功能
	{
		return lighted; //返回开关值
	}
	/*当某个灯变绿时,它对应方向的灯也要变绿。*/
	public void light() //亮灯功能
	{
		this.lighted = true; //改变开关值
		if ( opposite != null ) //如果对应灯值不为空
		{
			Lamp.valueOf(opposite).light(); //对应灯枚举常量递归执行亮灯功能
		}
		System.out.println("现在 " + this.name() + " 为绿灯,下面共有6个方向能看到汽车穿过!"); //打印此枚举常量名称信息
	}
	/*当某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿。*/
	public Lamp blackOut() //灭灯功能
	{
		this.lighted = false; //改变开关值
		Lamp nextLamp = null; //定义枚举变量为下个方向灯
		if ( opposite != null ) //如果对应灯值不为空
		{
			Lamp.valueOf(opposite).blackOut(); //对应灯枚举常量递归执行灭灯功能
		}
		if ( next != null ) //如果当前灯状态改变时下个会变绿灯值不为空
		{
			nextLamp = Lamp.valueOf(next); //下个方向灯值为当前灯状态改变时下个会变绿灯枚举常量
			System.out.println("绿灯从" + this.name() + "切换为" + next); //打印此枚举常量名称信息
			nextLamp.light(); //下个方向灯执行亮灯功能
		}
		return nextLamp; //返回下个方向灯枚举值
	}
}

/**
 * 对灯进行控制的方法
 * @author 张孝祥-黑马程序员
 * @editor 魏安-黑马程序员
 */
class LampController //灯控制器类
{
	private Lamp currentLamp; //定义枚举变量为当前灯
	private Runnable TurnLamp = new Runnable() //建立可运行多线程类对象为转换灯操作
	{
		@Override //覆写系统功能标记
		public void run() //覆写系统运行功能
		{
			System.out.println("绿灯切换,可以通行了!"); //打印信息
			currentLamp = currentLamp.blackOut(); //当前灯值为当前灯执行灭灯功能
		}
	}; //匿名内部类调用方式
	public LampController(Lamp lamp) //类构造函数
	{
		currentLamp = lamp; //当前灯为枚举调用值
		currentLamp.light(); //当前灯执行亮灯功能
		/*等10秒后执行且每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿*/
		ScheduledExecutorService SES = Executors.newScheduledThreadPool(1); //定义规划执行服务为执行器创建线程池
		SES.scheduleAtFixedRate(TurnLamp,10,10,TimeUnit.SECONDS); //规划执行服务按照参数执行转换灯操作
	}
}

/**
 * 每个Road对象代表一条路线,总共有12条路线,即系统中总共要产生12个Road实例对象。
 * 每条路线上随机增加新的车辆,增加到一个集合中保存。
 * 每条路线每隔一秒都会检查控制本路线的灯是否为绿,是则将本路线保存车的集合中的第一辆车移除,即表示车穿过了路口。
 * @author 张孝祥-黑马程序员
 * @editor 魏安-黑马程序员
 */
class Road //道路类
{
	private int Sleeptime = (new Random().nextInt(10) + 1) * 1000; //定义休眠时间
	private ArrayList<String> Vechicles = new ArrayList<String>(); //建立数组列表为车辆队伍容器
	private String name = null; //定义字符串变量为名字
	private Runnable VechiclesRun = new Runnable() //建立可运行多线程类对象为车辆运行操作
	{
		@Override //覆写系统功能标记
		public void run() //覆写系统运行功能
		{
			for ( int i = 1; i < 1000; i++ ) //定义循环条件
			{
				try //尝试执行
				{
					Thread.sleep(Sleeptime); //线程休眠
				}
				catch ( InterruptedException IE ) //抓住中断异常
				{
					IE.printStackTrace(); //打印堆栈信息
				}
				Vechicles.add(Road.this.name + "_" + i); //往容器添加元素
			}
		}
	}; //匿名内部类调用方式
	private Runnable Released = new Runnable() //建立可运行多线程类对象为放行操作
	{
		@Override //覆写系统功能标记
		public void run() //覆写系统运行功能
		{
			if ( Vechicles.size() > 0 ) //如果容器容量值不为空
			{
				boolean Lighted = Lamp.valueOf(Road.this.name).isLighted(); //判断绿灯通行开关对应枚举值执行判断开关功能
				if ( Lighted ) //如果开关值为打开
				{
					System.out.println(Vechicles.remove(0) + " 有车经过!"); //打印容器移除对应角标值信息
				}
			}
		}
	}; //匿名内部类调用方式
	public Road(String name) //类构造函数
	{
		this.name = name; //锁定传入参数变量
		/*车辆不断随机上路过程*/
		ExecutorService ES = Executors.newSingleThreadExecutor(); //定义执行服务为执行器创建单线程
		ES.execute(VechiclesRun); //执行服务执行车辆运行操作
		/*每隔一秒检查对应的灯是否为绿,若是,则放行一辆车*/
		ScheduledExecutorService SES = Executors.newScheduledThreadPool(1); //定义规划执行服务为执行器创建线程池
		SES.scheduleAtFixedRate(Released,1,1,TimeUnit.SECONDS); //规划执行服务按照参数执行放行操作
	}
}


学习心得:在巨人的肩膀上,你会做得更好!


其实个人认为,该程序由于要顾及车辆运行的模拟,而不仅仅是交通灯的工作,所以结构就有点复杂了。

毕竟程序的分解是越小块就越具体,用小细节组成大环境会比较好,而如果要一下子考虑全盘因素,肯定有困难。

当然三天时间做出这样的东西,真的很佩服张孝祥老师!


如果只考虑交通灯的工作运行情况,个人思路如下:

1.红灯亮一段时间,绿灯在这段时间内关闭。

2.红灯灭,绿灯打开一段时间。

3.轮流切换,可以用循环,也可以独立设置时间参数。

4.黄灯的工作要看时机而定。

运行参数的关键在于:开关状态和时间长短


以上只是一组灯的运行方式,如果考虑多组灯,请使用多线程或者多步操作完成。无非是逻辑执行而已。

由于本人并非做过这种项目,只能管中窥豹了,如有指教,请在本文评论,谢谢!


原帖:http://blog.csdn.net/zhangxiaoxiang/article/details/6273384

张孝祥老师已逝,可惜!无论世人如何评价他,起码他都是个实实在在做事的人!就凭这一点,就值得世人敬佩!他真的帮助了很多人!

内容概要:本文提出一种基于融合鱼鹰搜索行为与柯西变异策略的改进麻雀优化算法(OCSSA),用于优化变分模态分解(VMD)的关键参数(如模态分量数K和惩罚因子α),以实现对滚动轴承振动信号的高效自适应分解,有效抑制模态混叠问题。经过OCSSA优化的VMD对原始信号进行预处理后,将分解得到的本征模态函数(IMF)重构为时频特征矩阵,作为卷积神经网络(CNN)的输入,以自动提取深层次的空间特征;随后,双向长短期记忆网络(BiLSTM)进一步挖掘特征序列中的前后向时序依赖关系,最终实现高精度的故障分类识别。该OCSSA-VMD-CNN-BiLSTM模型在西储大学公开轴承数据集上进行了充分验证,结果表明其在复杂噪声环境下对轴承不同故障类型与程度的诊断准确率显著优于传统方法,充分体现了智能优化算法与深度学习相结合在故障诊断领域的优越性能。; 适合人群:具备信号处理、机器学习及智能优化算法基础知识,从事机械装备状态监测、故障诊断、工业大数据分析等相关领域的科研人员、工程技术人员及高校研究生。; 使用场景及目标:①解决传统VMD参数依赖经验设定导致信号分解效果不稳定的问题;②提升强背景噪声和工况变化下滚动轴承早期微弱故障的检测灵敏度与分类准确率;③为智能制造和工业互联网背景下的关键设备智能运维与预测性维护提供一套可复现、高性能的技术解决方案。; 阅读建议:此资源以Matlab代码实现为核心,建议读者深入研读算法代码,重点理解OCSSA的寻优机制、VMD参数自适应选择过程以及CNN-BiLSTM的网络构建细节,通过复现完整实验流程,掌握从信号预处理、特征提取到智能分类的全流程关键技术,尝试在自有数据集上进行迁移应用与性能对比。
源码链接: https://pan.quark.cn/s/a4b39357ea24 接口测试框架(基于json格式、http请求,python3,不兼容python2.x版本) 注:现在基于Excel文件管理测试用例基本实现,) 备注:大家在运行的时候,如果参数不需要key,只需要字典,可以在ddt_case.py和case.py改造parame,注释掉现在的parem,启用新的即可 依赖用例支持用例执行,在testCase的ddt_case.py有实现,逻辑在代码中有写,参数的格式{"name":"$case1=data"}即代表name的值是case1的data字段,简单的实现。 依赖用例是简单的实现,具体在业务上面还有很多复杂的要处理,知识实现了,部分的思路。 (目前在部分window上会出现FileNotFoundError [Errno 2] No such file or directory,这个bug是路径过长,解决方案为吧log日志放在当前目录,或者修改动态生成的文件的名字,给了第一种方式,测试日志放在当前目录) qq交流群:194704520 Alt text 使用的库 requests,绝大部分是基于Python原有的库进行的,这样简单方便, 使用脚本参数分离等思想,尽可能降低代码的耦合度。 如果你不配置钉钉机器人,注释到机器人相关的代码 首先我们来看下我们的目录 Alt text ### 1.Case文件夹用来存放我们的测试用例相关的, test_case用来存储我们的测试数据,Excel管理测试用例,yaml文件管理测试用例,后续要把yaml管理测试用例的也封装出来。 Interface对测试接口相关的封装,包括requests库,发送...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值