一、前言
训练集的练习已经到达了尾声,通过这些训练集,我们将进一步加深对OOP概念的理解,并学会如何运用这些原则来设计和开发更加灵活、可维护、可扩展的软件系统。在程序中,我们学习如何模拟不同类型的电路组件,如电源、开关、插座、灯具等,以及它们之间的连接方式和电气特性。我们还将探讨电路中的电压、电流、功率等关键参数的计算和分析方法,帮助我们更好地理解电路行为。
二、设计与分析
第七次作业
7-7 家居强电电路模拟程序-3
分数 70
作者 蔡轲
单位 南昌航空大学
智能家居是在当下家庭中越来越流行的一种配置方案,它通过物联网技术将家中的各种设备(如音视频设备、照明系统、窗帘控制、空调控制、安防系统、数字影院系统、影音服务器、影柜系统、网络家电等)连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。与普通家居相比,智能家居不仅具有传统的居住功能,兼备建筑、网络通信、信息家电、设备自动化,提供全方位的信息交互功能。请根据如下要去设计一个智能家居强电电路模拟系统。以下题目介绍中加粗的部分为本次迭代在“家居强电电路模拟程序-2”的基础上增加的功能要求。
1、控制设备
本题模拟的控制设备包括:开关、分档调速器、连续调速器、互斥开关。
开关:包括0和1两种状态。
开关有两个引脚,任意一个引脚都可以是输入引脚(接往电源端),而另一个则是输出引脚(接网接地端)。开关状态为0时,无论输入电位是多少,输出引脚电位为0。当开关状态为1时,输出引脚电位等于输入电位。
互斥开关:
互斥开关有3个引脚:1个是汇总引脚,另两个是分支引脚。
开关电路示意图如图1所示,左边是汇总引脚,编号为1;右边两个是分支引脚,右上的输出引脚为2,右下输出引脚为3。图中1、2、3引脚均可以是输入引脚,当1为输入引脚时,2、3引脚为输出引脚;1为输出引脚时,2、3引脚为输入引脚。
互斥开关只有两种状态:开关接往上面的2号引脚、接往下面的3号引脚。开关每次只能接通其中一个分支引脚,而另一个分支引脚处于断开状态。
互斥开关的默认状态为1、2引脚接通,1、3引脚断开。
图1中所示的互斥开关可以反过来接入电路,即汇总引脚接往接地端,两个分支引脚接往电源端。
image.png
图1 互斥开关
为避免短路,互斥开关设置了限流电阻,12引脚之间默认电阻为5,13引脚之间默认电阻为10。
分档调速器
按档位调整,常见的有3档、4档、5档调速器,档位值从0档-2(3/4)档变化。本次迭代模拟4档调速器,每个档位的输出电位分别为0、0.3、0.6、0.9倍的输入电压。
连续调速器
没有固定档位,按位置比例得到档位参数,数值范围在[0.00-1.00]之间,含两位小数。输出电位为档位参数乘以输入电压。
所有调速器都有两个引脚,一个固定的输入(引脚编号为1)、一个输出引脚(引脚编号为2)。当输入电位为0时,输出引脚输出的电位固定为0,不受各类开关调节的影响。
开关、调速器的初始状态/档位为0。
调速器的输入引脚编号为1,输出引脚编号为2。
除互斥开关外,其他控制设备的电阻为 0。
2、受控设备
本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。
灯有两种工作状态:亮、灭。在亮的状态下,有的灯会因引脚电位差的不同亮度会有区别。
风扇在接电后有两种工作状态:停止、转动。风扇的转速会因引脚间电位差的不同而有区别。
本次迭代模拟两种灯具。
白炽灯:
亮度在0~200lux(流明)之间。
电位差为0-9V时亮度为0,其他电位差按比例,电位差10V对应50ux,220V对应200lux,其他电位差与对应亮度值成正比。白炽灯超过220V。
日光灯:
亮度为180lux。
只有两种状态,电位差为0时,亮度为0,电位差不为0,亮度为180。
本次迭代模拟两种风扇。
吊扇:
工作电压区间为80V-150V,对应转速区间为80-360转/分钟。80V对应转速为80转/分钟,150V对应转速为360转/分钟,超过150V转速为360转/分钟(本次迭代暂不考虑电压超标的异常情况)。其他电压值与转速成正比,输入输出电位差小于80V时转速为0。
落地扇:
工作电压区间为 80V-150V,对应转速区间为 80-360 转/分钟;[80V,100V) 对应转速为 80 转/分钟;[100,120)V 对应转速为 160 转/分钟;[120,140)V 对应转速为 260 转/分钟;大于等于 140V 转速 为 360 转/分钟(本次迭代暂不考虑电压超标的异常情况)。
本次迭代模拟一种受控窗帘:
受控窗帘的电路符号为S,其最低工作电压为50V,电压达到或超过50V,窗帘即可正常工作,不考虑室外光照强度和室内空间大小等因素,窗帘受室内灯光的光照强度控制。
当电路中所有灯光的光照强度总和在[0,50)lux范围内,窗帘全开;
在[50,100)lux范围内,窗帘打开比例为0.8;
在[100,200)lux范围内,窗帘打开比例为0.6;
在[200,300)lux范围内,窗帘打开比例为0.4;
在[300,400)lux范围内,窗帘打开比例为0.2;
在400lux及以上范围内,窗帘关闭。
当电压低于50V,窗帘不工作,默认为全开状态。
如果电路中没有灯或者灯全部关闭,光照强度为0,窗帘处于全开状态。
受控设备电阻:白炽灯的电阻为 10,日光灯的电阻为 5,吊扇的电阻为 20,落地扇的电阻为 20,窗帘电阻为15。
3、输入信息
1)输入设备信息
分别用设备标识符K、F、L、B、R、D、A、H、S分别表示开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、落地扇、互斥开关、受控窗帘。
设备标识用标识符+编号表示,如K1、F3、L2等。
引脚格式:设备标识-引脚编号,例如:K1-1标识编号为1的开关的输入引脚。
开关、分档调速器、连续调速器的输入引脚编号为1,输出引脚编号为2。
受控设备的两个引脚编号分别为1、2。
互斥开关的引脚编号已经在互斥开关的介绍部分说明。
约束条件:
不同设备的编号可以相同。
同种设备的编号可以不连续。
设备信息不单独输入,包含在连接信息中。
2)输入连接信息
一条连接信息占一行,用[]表示一组连接在一起的设备引脚,引脚与引脚之间用英文空格" "分隔。
格式:"["+引脚号+" "+引脚号+"]"
例如:[K1-1 K3-2]表示K1的1引脚,K3的2引脚连接在一起。
约束条件:
不考虑调速器串联到其他调速器的情况。
考虑各类设备的并联接入。例如,K1 的输出接到 L2 的输入,L2 的输出再接其他设备属于串联接线。K1 的输出接到 L2 的输出,同时 K1 的输入接到 L2 的输入,这种情况属于并联。
本次迭代的连接信息不单独输入,包含在线路信息中。
3)输入控制设备调节信息
开关、互斥开关调节信息格式:
+设备标识K+设备编号,例如:#K2,代表切换K2开关的状态。
+设备标识H+设备编号,例如:#H2,代表切换H2互斥开关的状态。
分档调速器的调节信息格式:
+设备标识F+设备编号+"+" 代表加一档,例如:#F3+,代表F3输出加一档。
+设备标识F+设备编号+"-" 代表减一档,例如:#F1-,代表F1输出减一档。
连续调速器的调节信息格式:
+设备标识L+设备编号+":" +数值 代表将连续调速器的档位设置到对应数值,例如:#L3:0.6,代表L3输出档位参数0.6。
4)电源接地标识:
VCC,电压220V,GND,电压0V。没有接线的引脚默认接地,电压为0V。
5)输入串联电路信息
一条串联电路占一行,串联电路由按从靠电源端到接地端顺序依次输入的 n 个连接 信息组成,连接信息之间用英文空格" "分隔。
串联电路信息格式:
"#T"+电路编号+":"+连接信息+" "+连接信息+...+" "+连接信息
例如:#T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT] 一个串联电路的第一个引脚是 IN,代表起始端,靠电源。最后一个引脚是 OUT,代表结尾端, 靠接地。
约束条件:
不同的串联电路信息编号不同。
输入的最后一条电路信息必定是总电路信息,总电路信息的起始引脚是 VCC,结束引脚是 GND。
连接信息中的引脚可能是一条串联或并联电路的 IN 或者 OUT。例如:
T1:[IN K1-1] [K1-2 T2-IN] [T2-OUT OUT]
T1:[IN K1-1] [K1-2 T2-IN] [T2-OUT M2-IN] [M2-OUT OUT]
6)输入并联电路信息
一条并联电路占一行,并联电路由其包含的几条串联电路组成,串联电路标识之间用英文空格" "分隔。
格式:
"#M"+电路编号+":"+”[”+串联电路信息+" "+....+" "+串联电路信息+”]”
例如:#M1:[T1 T2 T3]
该例声明了一个并联电路,由 T1、T2、T3 三条串联电路并联而成,三条串联电路的 IN 短 接在一起构成 M1 的 IN,三条串联电路的 OUT 短接在一起构成 M1 的 OUT。
约束条件:
本次迭代不考虑并联电路中包含并联电路的情况。
本题不考虑输入电压或电压差超过220V的情况。
输入信息以end为结束标志,忽略end之后的输入信息。
本题中的并联信息所包含的串联电路的信息都在并联信息之前输入,不考虑乱序输入的情况。
只要不因短路而造成无穷大的电流烧坏电路(如电路中的部分短接),都是合理情况,在测试点的考虑范围之内。会造成无穷大的电流的短路本次迭代不考虑。
本次迭代考虑多个并联电路串联在一起的情况。
本题考虑一条串联电路中包含其他串联电路的情况。例如:
T3:[VCC K1-1] [K1-2 T2-IN] [T2-OUT K2-1] [K2-2 T1-IN] [T1-OUT GND]
本例中T1\T2两条串联电路T3的一个部分,本题考虑这种类型的输入。
4、输出信息:
按开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、互斥开关、受控窗帘的顺序依次输出所有设备的状态或参数。每个设备一行。同类设备按编号顺序从小到大输出。
输出格式:
@设备标识+设备编号+":" +设备参数值(控制开关的档位或状态、灯的亮度、风扇的转速,只输出值,不输出单位)
连续调速器的档位信息保留两位小数,即使小数为0,依然显示两位小数.00。
开关状态为0(打开)时显示turned on,状态为1(合上)时显示closed
如:
@K1:turned on
@B1:190
@L1:0.60
互斥开关显示1、2引脚的接通状态,接通时显示closed,断开时显示turned on。
如:
@H1:turned on
受控窗帘显示窗帘打开的百分比,如:
@S1:80%
5、家居电路模拟系列所有题目的默认规则:
1)当计算电压值等数值的过程中,最终结果出现小数时,用截尾规则去掉小数部分,只保留整数部分。为避免精度的误差,所有有可能出现小数的数值用double类型保存并计算,不要作下转型数据类型转换,例如电压、转速、亮度等,只有在最后输出时再把计算结果按截尾规则,舍弃尾数,保留整数输出。
2)所有连接信息按电路从电源到接地的顺序依次输入,不会出现错位的情况。电源VCC一定是第一个连接的第一项,接地GND一定是最后一个连接的后一项。
3)连接信息如果只包含两个引脚,靠电源端的引脚在前,靠接地端的在后。
4)调速器的输入端只会直连VCC,不会接其他设备。整个电路最多只有连接在电源上的一个调速器,且不包含在并联单路中。
6、家居电路模拟系列1-4题目后续迭代设计:
1)电路结构变化:
迭代1:只有一条线路,所有元件串联
迭代2:线路中包含一个并联电路
迭代3:线路中包含多个串联起来的并联电路
迭代4:并联电路之间可能出现包含关系
电路结构变化示意图见图1。
2)计算方式的变化
迭代1只包含1个受控元件,不用计算电流,之后的电路计算要包含电流、电阻等电路参数。
3)电路元件的变化
每次迭代会增加1-2个新的电路元件。
image.png
图1:电路结构示意图
设计建议:
1、电路设备类:描述所有电路设备的公共特征。
2、受控设备类、控制设备类:对应受控、控制设备
3、串联电路类:一条由多个电路设备构成的串联电路,也看成是一个独立的电路设备
4、并联电路类:继承电路设备类,也看成是一个独立的电路设备
其他类以及类的属性、方法自行设计。
image.png
图2:建议设计类图
输入样例1:
在这里给出一组输入。例如:
T1:[IN H1-1] [H1-2 D2-1] [D2-2 OUT]
T2:[IN H1-1] [H1-3 D1-1] [D1-2 OUT]
M1:[T1 T2]
T4:[IN K3-1] [K3-2 B2-1] [B2-2 OUT]
T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
M2:[T4 T5]
T3:[VCC K2-1] [K2-2 M1-IN] [M1-OUT M2-IN] [M2-OUT GND]
K1
K2
end
输出样例1:
在这里给出相应的输出。例如:
@K1:closed
@K2:closed
@K3:turned on
@B1:87
@B2:0
@D1:0
@D2:262
@H1:closed
输入样例2:
在这里给出一组输入。例如:
T1:[IN D2-1] [D2-2 H1-2] [H1-1 OUT]
T2:[IN D1-1] [D1-2 H1-3] [H1-1 OUT]
M1:[T1 T2]
T4:[IN K3-1] [K3-2 B2-1] [B2-2 OUT]
T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
M2:[T4 T5]
T3:[VCC K2-1] [K2-2 M1-IN] [M1-OUT M2-IN] [M2-OUT GND]
K1
K2
end
输出样例2:
在这里给出相应的输出。例如:
@K1:closed
@K2:closed
@K3:turned on
@B1:87
@B2:0
@D1:0
@D2:262
@H1:closed
输入样例3:
在这里给出一组输入。例如:
T1:[IN K1-1] [K1-2 B2-1] [B2-2 OUT]
T2:[IN K2-1] [K2-2 R1-1] [R1-2 OUT]
M1:[T1 T2]
T3:[VCC K3-1] [K3-2 M1-IN] [M1-OUT S1-1] [S1-2 GND]
K1
K2
K3
end
输出样例3:
在这里给出相应的输出。例如:
@K1:closed
@K2:closed
@K3:closed
@B2:71
@R1:180
@S1:40%
输入样例4:
在这里给出一组输入。例如:
T1:[IN K2-1] [K2-2 D2-1] [D2-2 OUT]
T2:[IN K3-1] [K3-2 D1-1] [D1-2 OUT]
T3:[VCC K1-1] [K1-2 T1-IN] [T1-OUT T2-IN] [T2-OUT GND]
K1
K2
K3
end
输出样例4:
在这里给出相应的输出。例如:
@K1:closed
@K2:closed
@K3:closed
@D1:200
@D2:200
输入样例5:
在这里给出一组输入。例如:
T3:[VCC B2-1] [B2-2 K1-1] [K1-2 S1-1] [S1-2 H1-1] [H1-2 GND]
K1
end
输出样例5:
在这里给出相应的输出。例如:
@K1:closed
@B2:95
@H1:closed
@S1:80%
我的主要代码
public class Main{public static void main(String[] args){LinkedList<String> eidlist = new LinkedList<>();LinkedList<String> neweidlist = new LinkedList<>();LinkedList<String> connectlist = new LinkedList<>();LinkedHashMap<String,Equipment> emap = new LinkedHashMap<>();LinkedList<String> controllist = new LinkedList<>();LinkedList<Parallel> binglist = new LinkedList<>();LinkedList<Series> chuanlist = new LinkedList<>();Scanner in = new Scanner(System.in);//输入while(true){LinkedList<String> elist = new LinkedList<>();String newin=in.nextLine();if(newin.equals("end"))break;if(newin.startsWith("#T")){Pattern pat = Pattern.compile("#(T\\d+):(.*)");Matcher mat = pat.matcher(newin);mat.find();String sname = mat.group(1);eidlist.add(sname);
//System.out.println(sname);Equipment s = new Series(sname);Pattern pat1 = Pattern.compile("(\\w+)-(\\w+)");Matcher mat1 = pat1.matcher(newin);while(mat1.find()){connectlist.add(mat1.group(0));String id = mat1.group(1);
//System.out.println(id);if(id.startsWith("H")){elist.add(mat1.group(0));eidlist.add(mat1.group(0));((Series)s).selist.add(mat1.group(0));continue;}elist.add(id);eidlist.add(id);((Series)s).selist.add(id);}emap.put(sname,s);chuanlist.add((Series)s);}else if(newin.startsWith("#M")){Pattern pat = Pattern.compile("#(M\\d+):(.*)");Matcher mat = pat.matcher(newin);mat.find();String pname = mat.group(1);eidlist.add(pname);Equipment p = new Parallel(pname);int index = newin.indexOf(":");String str1 = newin.substring(index+1,newin.length()-1);String ps = str1.replaceAll("[\\[\\]]","");String[] pa = ps.split("\\s+");for(int i=0;i<pa.length;i++){((Parallel)p).pelist.add(pa[i]);}emap.put(pname,p);binglist.add((Parallel)p);}else if(newin.startsWith("#K")||newin.startsWith("#L")||newin.startsWith("#F")||newin.startsWith("#H")){controllist.add(newin);}}Iterator<String> it=eidlist.iterator();while (it.hasNext()){String str=it.next();if (!neweidlist.contains(str)){neweidlist.add(str);
//System.out.println(str);}}for(int i=0;i<chuanlist.size();i++){LinkedList<String> neweidlist1=new LinkedList<>();Iterator<String> it1=chuanlist.get(i).selist.iterator();while (it1.hasNext()){String str=it1.next();if (!neweidlist1.contains(str)){neweidlist1.add(str);//System.out.println(str);}}chuanlist.get(i).selist=neweidlist1;}for(int i=0;i<binglist.size();i++){LinkedList<String> neweidlist2=new LinkedList<>();Iterator<String> it2=binglist.get(i).pelist.iterator();while (it2.hasNext()){String str=it2.next();if (!neweidlist2.contains(str)){neweidlist2.add(str);
//System.out.println(str);}}binglist.get(i).pelist=neweidlist2;}for(String eid:neweidlist){if(eid.matches("K\\d+")){Switch ek = new Switch(eid);emap.put(eid,ek);}else if(eid.matches("F\\d+")){Equipment ef = new Devide(eid);emap.put(eid,ef);}else if(eid.matches("L\\d+")){Equipment el = new Continue(eid);emap.put(eid,el);}else if(eid.matches("B\\d+")){Equipment eb = new Bright(eid);emap.put(eid,eb);}else if(eid.matches("R\\d+")){Equipment er = new Sun(eid);emap.put(eid,er);}else if(eid.matches("D\\d+")){Equipment ed = new Fan(eid);emap.put(eid,ed);}else if(eid.matches("A\\d+")){Equipment ea = new AFan(eid);emap.put(eid,ea);}else if(eid.matches("H\\d+-\\d+")){Equipment eh = new Hswitch(eid);emap.put(eid,eh);}else if(eid.matches("S\\d+")){Equipment es = new S(eid);emap.put(eid,es);}}for(String cin:controllist){if(cin.startsWith("#K")){String k=cin.substring(1);if(emap.containsKey(k)){((Switch)emap.get(k)).changestate();}}else if(cin.startsWith("#F")){String f=cin.substring(1);int index1 = f.indexOf("F");int index2 = f.indexOf("+");int index3 = f.indexOf("-");if(index2>0){String f1 = f.substring(index1,index2);if(emap.containsKey(f1)){((Devide)emap.get(f1)).speedlevel++;}}else if(index3>0){String f2 = f.substring(index1,index3);if(emap.containsKey(f2)){((Devide)emap.get(f2)).speedlevel--;}}}else if(cin.startsWith("#L")){String l=cin.substring(1);String l1[] = l.split(":");if(emap.containsKey(l1[0])){((Continue)emap.get(l1[0])).setparameter(Double.parseDouble(l1[1]));}}else if(cin.startsWith("#H")){String h = cin.substring(1);for(String key:emap.keySet()){Pattern pat = Pattern.compile("(H\\d+)-(\\d+)");Matcher mat = pat.matcher(key);if(mat.find()) {String a = mat.group(1);if (a.equals(h)) {((Hswitch) emap.get(key)).change();}}}}}for(String eid:neweidlist){
//if(eid.matches("T\\d+")){for(String id:((Series)(emap.get(eid))).selist){if(emap.containsKey(id)){((Series)emap.get(eid)).semap.put(id,emap.get(id));}}}if(eid.matches("M\\d+")){for(String id:((Parallel)emap.get(eid)).pelist){if(emap.containsKey(id)){((Parallel)emap.get(eid)).pemap.put(id,emap.get(id));}}}}for(int i=0;i<chuanlist.size();i++){chuanlist.get(i).changestate();}for(String eid:neweidlist){
//System.out.println(eid);if(eid.matches("T\\d+")){for(String id:((Series)(emap.get(eid))).selist){if(emap.containsKey(id)&&!emap.get(id).type.equals("H")){emap.get(eid).resistance+=emap.get(id).resistance;
//System.out.println(id+emap.get(id).resistance);}else{((Hswitch)emap.get(id)).changer();
//System.out.println(id+emap.get(id).resistance);emap.get(eid).resistance+=emap.get(id).resistance/2;}}}if(eid.matches("M\\d+")){((Parallel)emap.get(eid)).changer();}}//输出LinkedList<Equipment> elist = new LinkedList(emap.values());//设备inv变动//System.out.println(elist.size());double inv=220.01;Equipment e =chuanlist.get(chuanlist.size()-1);for(String id:((Series)e).semap.keySet()){
//System.out.println(id);Equipment newe = ((Series)e).semap.get(id);if(newe.type.equals("K")){inv=((Switch)newe).changeoutv(inv);}else if(newe.type.equals("F"))inv=((Devide)newe).changeoutv(inv);else if(newe.type.equals("L"))inv=((Continue)newe).changeoutv(inv);}//System.out.println(inv);if(((Series)e).state!=1){for(String id:((Series)e).semap.keySet()){//System.out.println(id);Equipment newe = ((Series)e).semap.get(id);//System.out.println(newe.type);double r;if(newe.type.equals("B")){r=10;((Bright)newe).setlight(inv*r/((Series)e).resistance);}else if(newe.type.equals("R")){r=5;((Sun)newe).setlight(inv*r/((Series)e).resistance);}else if(newe.type.equals("D")){r=20;((Fan)newe).setrotate(inv*r/ e.resistance);//System.out.println(((Fan)newe).rotate);}else if(newe.type.equals("A")){r=20;((AFan)newe).setrotate(inv*r/ e.resistance);}else if(newe.type.equals("P")){newe.inv=inv* ((Series)e).semap.get(id).resistance/ e.resistance;for(String s:((Parallel)newe).pemap.keySet()){Equipment e2 =((Parallel)newe).pemap.get(s);//System.out.println(((Series)e2).state);if(((Series)e2).state==0){for(String key:((Series)e2).semap.keySet()){Equipment newe11=((Series)e2).semap.get(key);double r1;//System.out.println(newe1.type);if(newe11.type.equals("B")){r1=10;((Bright)newe11).setlight(inv*r1/ e2.resistance);}else if(newe11.type.equals("R")){r1=5;((Sun)newe11).setlight(inv*r1/ e2.resistance);}else if(newe11.type.equals("D")){r1=20;((Fan)newe11).setrotate(inv*r1/ e2.resistance);}else if(newe11.type.equals("A")){r1=20;((AFan)newe11).setrotate(inv*r1/ e2.resistance);}else if(newe11.type.equals("S")){r1= newe11.resistance;newe11.inv = inv*r1/ e2.resistance;}else if(newe11.type.equals("P")){newe11.inv=inv* ((Series)e2).semap.get(key).resistance/ e2.resistance;}else if(newe11.type.equals("S1")){r1=15;newe11.inv = inv*r1/ e2.resistance;}else if (newe11.type.equals("H")){newe11.inv=inv* ((Series)e2).semap.get(key).resistance/ e2.resistance;}}}else{for(String key:((Series)e2).semap.keySet()){//System.out.println(id);Equipment newe2 = ((Series)e2).semap.get(key);//System.out.println(newe.type);double r1;if(newe2.type.equals("B")){r1=10;((Bright)newe2).setlight(0);}else if(newe2.type.equals("R")){r1=5;((Sun)newe2).setlight(0);}else if(newe2.type.equals("D")){r1=20;((Fan)newe2).setrotate(0);}else if(newe2.type.equals("A")){r1=20;((AFan)newe2).setrotate(0);}else if(newe2.type.equals("S1")){r1=15;((S)newe2).inv=0;}}}}}else if(newe.type.equals("S1")){r=15;newe.inv=inv* r/ e.resistance;}else if(newe.type.equals("S")){if(((Series)newe).state==0) {newe.inv = inv * ((Series) e).semap.get(id).resistance / e.resistance;}else {newe.inv = 0;}}}for(int j=0;j<chuanlist.size()-1;j++){Series series = chuanlist.get(j);inv = series.inv;if(series.state!=1) {for (String id : series.semap.keySet()) {//System.out.println(id);Equipment newe1 = series.semap.get(id);//System.out.println(newe.type);double r;if (newe1.type.equals("B")) {r = 10;((Bright) newe1).setlight(inv * r / series.resistance);} else if (newe1.type.equals("R")) {r = 5;((Sun) newe1).setlight(inv * r / series.resistance);} else if (newe1.type.equals("D")) {r = 20;((Fan) newe1).setrotate(inv * r / series.resistance);//System.out.println(((Fan)newe).rotate);} else if (newe1.type.equals("A")) {r = 20;((AFan) newe1).setrotate(inv * r / series.resistance);} else if (newe1.type.equals("P")) {newe1.inv = inv * series.semap.get(id).resistance / series.resistance;}else if(newe1.type.equals("S")){newe1.inv = inv*series.semap.get(id).resistance/series.resistance;}else if (newe1.type.equals("S1")) {r = 15;newe1.inv = inv * r / series.resistance;}}}}for(int i = 0;i<binglist.size();i++){inv = binglist.get(i).inv;
//System.out.println(inv);for(String s:binglist.get(i).pemap.keySet()){Equipment e2 =binglist.get(i).pemap.get(s);if(((Series)e2).state==0){for(String id:((Series)e2).semap.keySet()){Equipment newe1=((Series)e2).semap.get(id);double r1;//System.out.println(newe1.type);if(newe1.type.equals("B")){r1=10;((Bright)newe1).setlight(inv*r1/ e2.resistance);}else if(newe1.type.equals("R")){r1=5;((Sun)newe1).setlight(inv*r1/ e2.resistance);}else if(newe1.type.equals("D")){r1=20;((Fan)newe1).setrotate(inv*r1/ e2.resistance);}else if(newe1.type.equals("A")){r1=20;((AFan)newe1).setrotate(inv*r1/ e2.resistance);}else if(newe1.type.equals("S")){r1= newe1.resistance;newe1.inv = inv*r1/ e2.resistance;}else if(newe1.type.equals("P")){newe1.inv=inv* ((Series)e2).semap.get(id).resistance/ e2.resistance;}else if(newe1.type.equals("S1")){r1=15;newe1.inv = inv*r1/ e2.resistance;}else if (newe1.type.equals("H")){newe1.inv=inv* ((Series)e2).semap.get(id).resistance/ e2.resistance;}}}else{for(String id:((Series)e2).semap.keySet()){//System.out.println(id);Equipment newe = ((Series)e2).semap.get(id);//System.out.println(newe.type);double r;if(newe.type.equals("B")){r=10;((Bright)newe).setlight(0);}else if(newe.type.equals("R")){r=5;((Sun)newe).setlight(0);}else if(newe.type.equals("D")){r=20;((Fan)newe).setrotate(0);}else if(newe.type.equals("A")){r=20;((AFan)newe).setrotate(0);}// else if(newe.type.equals("P"))// {// ((Parallel)newe).inv=0;// }}}}}}else{for(String id:((Series)e).semap.keySet()){//System.out.println(id);Equipment newe = ((Series)e).semap.get(id);//System.out.println(newe.type);double r;if(newe.type.equals("B")){r=10;((Bright)newe).setlight(0);}else if(newe.type.equals("R")){r=5;((Sun)newe).setlight(0);}else if(newe.type.equals("D")){r=20;((Fan)newe).setrotate(0);//System.out.println(((Fan)newe).rotate);}else if(newe.type.equals("A")){r=20;((AFan)newe).setrotate(0);}else if(newe.type.equals("P")){newe.inv=0;for(String s:((Parallel)newe).pemap.keySet()){Equipment e2 =((Parallel)newe).pemap.get(s);//System.out.println(((Series)e2).state);if(((Series)e2).state==0){for(String key:((Series)e2).semap.keySet()){Equipment newe11=((Series)e2).semap.get(key);double r1;//System.out.println(newe1.type);if(newe11.type.equals("B")){r1=10;((Bright)newe11).setlight(0);}else if(newe11.type.equals("R")){r1=5;((Sun)newe11).setlight(0);}else if(newe11.type.equals("D")){r1=20;((Fan)newe11).setrotate(0);}else if(newe11.type.equals("A")){r1=20;((AFan)newe11).setrotate(0);}else if(newe11.type.equals("S")){r1= newe11.resistance;newe11.inv = 0;}else if(newe11.type.equals("P")){newe11.inv=0;}else if(newe11.type.equals("S1")){r1=15;newe11.inv = 0;}else if (newe11.type.equals("H")){newe11.inv=0;}}}else{for(String key:((Series)e2).semap.keySet()){//System.out.println(id);Equipment newe2 = ((Series)e2).semap.get(key);//System.out.println(newe.type);double r1;if(newe2.type.equals("B")){r1=10;((Bright)newe2).setlight(0);}else if(newe2.type.equals("R")){r1=5;((Sun)newe2).setlight(0);}else if(newe2.type.equals("D")){r1=20;((Fan)newe2).setrotate(0);}else if(newe2.type.equals("A")){r1=20;((AFan)newe2).setrotate(0);}else if(newe2.type.equals("S1")){r1=15;((S)newe2).inv=0;}}}}}else if(newe.type.equals("S1")){r=15;newe.inv=0;}else if(newe.type.equals("S")){if(((Series)newe).state==0) {newe.inv = 0;}else {newe.inv = 0;}}}for(int j=0;j<chuanlist.size()-1;j++){Series series = chuanlist.get(j);inv = series.inv;if(series.state!=1) {for (String id : series.semap.keySet()) {//System.out.println(id);Equipment newe1 = series.semap.get(id);//System.out.println(newe.type);double r;if (newe1.type.equals("B")) {r = 10;((Bright) newe1).setlight(0);} else if (newe1.type.equals("R")) {r = 5;((Sun) newe1).setlight(0);} else if (newe1.type.equals("D")) {r = 20;((Fan) newe1).setrotate(0);//System.out.println(((Fan)newe).rotate);} else if (newe1.type.equals("A")) {r = 20;((AFan) newe1).setrotate(0);} else if (newe1.type.equals("P")) {newe1.inv = 0;}else if(newe1.type.equals("S")){newe1.inv = 0;}else if (newe1.type.equals("S1")) {r = 15;newe1.inv = 0;}}}}for(int i = 0;i<binglist.size();i++){inv = binglist.get(i).inv;
//System.out.println(inv);for(String s:binglist.get(i).pemap.keySet()){Equipment e2 =binglist.get(i).pemap.get(s);if(((Series)e2).state==0){for(String id:((Series)e2).semap.keySet()){Equipment newe1=((Series)e2).semap.get(id);double r1;//System.out.println(newe1.type);if(newe1.type.equals("B")){r1=10;((Bright)newe1).setlight(0);}else if(newe1.type.equals("R")){r1=5;((Sun)newe1).setlight(0);}else if(newe1.type.equals("D")){r1=20;((Fan)newe1).setrotate(0);}else if(newe1.type.equals("A")){r1=20;((AFan)newe1).setrotate(0);}else if(newe1.type.equals("S")){r1= newe1.resistance;newe1.inv = 0;}else if(newe1.type.equals("P")){newe1.inv=0;}else if(newe1.type.equals("S1")){r1=15;newe1.inv = 0;}else if (newe1.type.equals("H")){newe1.inv=0;}}}else{for(String id:((Series)e2).semap.keySet()){//System.out.println(id);Equipment newe = ((Series)e2).semap.get(id);//System.out.println(newe.type);double r;if(newe.type.equals("B")){r=10;((Bright)newe).setlight(0);}else if(newe.type.equals("R")){r=5;((Sun)newe).setlight(0);}else if(newe.type.equals("D")){r=20;((Fan)newe).setrotate(0);}else if(newe.type.equals("A")){r=20;((AFan)newe).setrotate(0);}// else if(newe.type.equals("P"))// {// ((Parallel)newe).inv=0;// }}}}}}double light=0;for(int i=0;i<chuanlist.size();i++){Series series = chuanlist.get(i);for(String str:series.semap.keySet()){if(str.startsWith("B")){light+=((Bright)series.semap.get(str)).light;}else if(str.startsWith("R")){light+=((Sun)series.semap.get(str)).light;}}}for(int i=0;i<chuanlist.size();i++){Series series = chuanlist.get(i);for(String str:series.semap.keySet()){if(str.startsWith("S")){((S)series.semap.get(str)).changeopenness(light);}}}Collections.sort(elist,new comparator());ArrayList<String> a = new ArrayList<>();for(Equipment e1:elist){if(!e1.type.equals("H"))e1.display(e1);else{Pattern pat = Pattern.compile("(\\w+)-(\\w+)");Matcher mat = pat.matcher(e1.id);mat.find();String nid = mat.group(1);if(!a.contains(nid)) {a.add(nid);System.out.println("@"+nid+":"+((Hswitch)e1).state);}}}}
}
踩坑心得
引入新的控制设备:开关、分档调速器、连续调速器、互斥开关。
开关操作原理:开关有两种状态,状态为0时输出引脚为0,状态为1时输出引脚与输入引脚电位相同。
互斥开关操作原理:互斥开关有汇总引脚和两个分支引脚,状态有两种,每次只能接通一个分支引脚。
互斥开关限流电阻:为避免短路问题,设置了限流电阻,确保电路安全。
设备功能丰富多样:各种设备能够模拟真实家庭中的电路控制情形,给予用户实用的操作体验。
第八次作业
7-1 家居强电电路模拟程序-4
分数 100
作者 蔡轲
单位 南昌航空大学
智能家居是在当下家庭中越来越流行的一种配置方案,它通过物联网技术将家中的各种设备(如音视频设备、照明系统、窗帘控制、空调控制、安防系统、数字影院系统、影音服务器、影柜系统、网络家电等)连接到一起,提供家电控制、照明控制、电话远程控制、室内外遥控、防盗报警、环境监测、暖通控制、红外转发以及可编程定时控制等多种功能和手段。与普通家居相比,智能家居不仅具有传统的居住功能,兼备建筑、网络通信、信息家电、设备自动化,提供全方位的信息交互功能。请根据如下要去设计一个智能家居强电电路模拟系统。以下题目介绍中加粗的部分为本次迭代在“家居强电电路模拟程序-3”的基础上增加的功能要求。
1、控制设备
本题模拟的控制设备包括:开关、分档调速器、连续调速器、互斥开关。
开关:包括0和1两种状态。
开关有两个引脚,任意一个引脚都可以是输入引脚(接往电源端),而另一个则是输出引脚(接网接地端)。开关状态为0时,无论输入电位是多少,输出引脚电位为0。当开关状态为1时,输出引脚电位等于输入电位。
互斥开关:
互斥开关有3个引脚:1个是汇总引脚,另两个是分支引脚。
开关电路示意图如图1所示,左边是汇总引脚,编号为1;右边两个是分支引脚,右上的输出引脚为2,右下输出引脚为3。图中1、2、3引脚均可以是输入引脚,当1为输入引脚时,2、3引脚为输出引脚;1为输出引脚时,2、3引脚为输入引脚。
互斥开关只有两种状态:开关接往上面的2号引脚、接往下面的3号引脚。开关每次只能接通其中一个分支引脚,而另一个分支引脚处于断开状态。
互斥开关的默认状态为1、2引脚接通,1、3引脚断开。
图1中所示的互斥开关可以反过来接入电路,即汇总引脚接往接地端,两个分支引脚接往电源端。
image.png
图1 互斥开关
为避免短路,互斥开关设置了限流电阻,1、2引脚之间默认电阻为5,1、3引脚之间默认电阻为10。
分档调速器
按档位调整,常见的有3档、4档、5档调速器,档位值从0档-2(3/4)档变化。本次迭代模拟4档调速器,每个档位的输出电位分别为0、0.3、0.6、0.9倍的输入电压。
连续调速器
没有固定档位,按位置比例得到档位参数,数值范围在[0.00-1.00]之间,含两位小数。输出电位为档位参数乘以输入电压。
所有调速器都有两个引脚,一个固定的输入(引脚编号为1)、一个输出引脚(引脚编号为2)。当输入电位为0时,输出引脚输出的电位固定为0,不受各类开关调节的影响。
开关、调速器的初始状态/档位为0。
开关的两个引脚编号为1、2。
除互斥开关外,其他控制设备的电阻为 0。
2、受控设备
本题模拟的受控设备包括:灯、风扇。两种设备都有两根引脚,通过两根引脚电压的电压差驱动设备工作。
灯有两种工作状态:亮、灭。在亮的状态下,有的灯会因引脚电位差的不同亮度会有区别。
风扇在接电后有两种工作状态:停止、转动。风扇的转速会因引脚间电位差的不同而有区别。
本次迭代模拟两种灯具。
白炽灯:
亮度在0~200lux(流明)之间。
电位差为0-9V时亮度为0,其他电位差按比例,电位差10V对应50ux,220V对应200lux,其他电位差与对应亮度值成正比。白炽灯超过220V。
日光灯:
亮度为180lux。
只有两种状态,电位差为0时,亮度为0,电位差不为0,亮度为180。
本次迭代模拟两种风扇。
吊扇:
工作电压区间为80V-150V,对应转速区间为80-360转/分钟。80V对应转速为80转/分钟,150V对应转速为360转/分钟,超过150V转速为360转/分钟(本次迭代暂不考虑电压超标的异常情况)。其他电压值与转速成正比,输入输出电位差小于80V时转速为0。
落地扇:
工作电压区间为 80V-150V,对应转速区间为 80-360 转/分钟;[80V,100V) 对应转速为 80 转/分钟;[100,120)V 对应转速为 160 转/分钟;[120,140)V 对应转速为 260 转/分钟;大于等于 140V 转速 为 360 转/分钟(本次迭代暂不考虑电压超标的异常情况)。
本次迭代模拟一种受控窗帘:
受控串联的电路符号为S,其最低工作电压为50V,电压达到或超过50V,窗帘即可正常工作,不考虑室外光照强度和室内空间大小等因素,窗帘受室内灯光的光照强度控制。
当电路中所有灯光的光照强度总和在[0,50)lux范围内,窗帘全开;
在[50,100)lux范围内,窗帘打开比例为0.8;
在[100,200)lux范围内,窗帘打开比例为0.6;
在[200,300)lux范围内,窗帘打开比例为0.4;
在[300,400)lux范围内,窗帘打开比例为0.2;
在400lux及以上范围内,窗帘关闭。
当电压低于50V,窗帘不工作,默认为全开状态。
如果电路中没有灯或者灯全部关闭,光照强度为0,窗帘处于全开状态。
受控设备电阻:白炽灯的电阻为 10,日光灯的电阻为 5,吊扇的电阻为 20,落地扇的电阻为 20,窗帘电阻为15。
3、输入信息
1)输入设备信息
分别用设备标识符K、F、L、B、R、D、A、H、S、P分别表示开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、落地扇、互斥开关、受控窗帘、二极管(见第6部分说明)。
设备标识用标识符+编号表示,如K1、F3、L2等。
引脚格式:
设备标识-引脚编号,例如:K1-1标识编号为1的开关的1号引脚。
开关、分档调速器、连续调速器的两个引脚编号为1、2。
受控设备的两个引脚编号分别为1、2。
互斥开关的引脚编号已经在互斥开关的介绍部分说明。
约束条件:
不同设备的编号可以相同。
设备信息不单独输入,包含在连接信息中。
2)输入连接信息
一条连接信息占一行,用[]表示一组连接在一起的设备引脚,引脚与引脚之间用英文空格" "分隔。
格式:
"["+引脚号+" "+引脚号+"]"
例如:[K1-1 K3-2]表示K1的1号引脚,K3的2号引脚连接在一起。
约束条件:
不考虑调速器串联到其他调速器的情况。
考虑各类设备的并联接入。例如,K1 的输出接到 L2 的输入,L2 的输出再接其他设备属于串联接线。K1 的输出接到 L2 的输出,同时 K1 的输入接到 L2 的输入,这种情况属于并联。
连接信息不单独输入,包含在线路信息中。
3)输入控制设备调节信息
开关、互斥开关调节信息格式:
+设备标识K+设备编号,例如:#K2,代表切换K2开关的状态。
+设备标识H+设备编号,例如:#H2,代表切换H2互斥开关的状态。
分档调速器的调节信息格式:
+设备标识F+设备编号+"+" 代表加一档,例如:#F3+,代表F3输出加一档。
+设备标识F+设备编号+"-" 代表减一档,例如:#F1-,代表F1输出减一档。
连续调速器的调节信息格式:
+设备标识L+设备编号+":" +数值 代表将连续调速器的档位设置到对应数值,例如:#L3:0.6,代表L3输出档位参数0.6。
4)电源接地标识:
VCC,电压220V,GND,电压0V。没有接线的引脚默认接地,电压为0V。
5)输入串联电路信息
一条串联电路占一行,串联电路信息由 n 个连接信息组成,连接信息按从靠电源端到接地端顺序依次输入,连接信息之间用英文空格" "分隔。
串联电路信息格式:
"#T"+电路编号+":"+连接信息+" "+连接信息+...+" "+连接信息
例如:#T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT] 一个串联电路的第一个引脚是 IN,代表起始端,靠电源。最后一个引脚是 OUT,代表结尾端, 靠接地。
约束条件:
不同的串联电路信息编号不同。
输入的最后一条电路信息必定是总电路信息,总电路信息的起始引脚是 VCC,结束引脚是 GND。
连接信息中的引脚可能是一条串联或并联电路的 IN 或者 OUT。例如:
T1:[IN K1-1] [K1-2 T2-IN] [T2-OUT OUT]
T1:[IN K1-1] [K1-2 T2-IN] [T2-OUT M2-IN] [M2-OUT OUT]
6)输入并联电路信息
一条并联电路占一行,并联电路由其包含的几条串联电路组成,串联电路标识之间用英文空格" "分隔。
格式:
"#M"+电路编号+":"+”[”+串联电路信息+" "+....+" "+串联电路信息+”]”
例如:#M1:[T1 T2 T3]
该例声明了一个并联电路,由 T1、T2、T3 三条串联电路并联而成,三条串联电路的 IN 短接在一起构成 M1 的 IN,三条串联电路的 OUT 短接在一起构成 M1 的 OUT。
在本题中,并联电路M中的串联电路可以包含别的并联电路。
约束条件:
本题不考虑输入电压或电压差超过220V的情况。
输入信息以end为结束标志,忽略end之后的输入信息。
本题中的并联信息所包含的串联电路的信息都在并联信息之前输入,不考虑乱序输入的情况。
只要不因短路而造成无穷大的电流烧坏电路(如电路中的部分短接),都是合理情况。
本次迭代考虑多个并联电路串联在一起的情况。
本题考虑一条串联电路中包含其他串联电路和并联电路的情况。例如:
T3:[VCC K1-1] [K1-2 T2-IN] [T2-OUT K2-1] [K2-2 T1-IN] [T1-OUT GND]
本例中T1\T2两条串联电路是T3的一个部分,本题考虑这种类型的输入。
4、输出信息:
按开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、互斥开关、受控窗帘、二极管(见第6部分说明)的顺序依次输出所有设备的状态或参数。每个设备一行。同类设备按编号顺序从小到大输出。
输出格式:
@设备标识+设备编号+":" +设备参数值(控制开关的档位或状态、灯的亮度、风扇的转速,只输出值,不输出单位)+" "+设备所有引脚的电压(按编号从小到大顺序依次输出,电压的小数部分直接丢弃,保留整数输出,电压之间用”-”分隔)
说明:
连续调速器的档位信息保留两位小数,即使小数为0,依然显示两位小数.00。
开关状态为0(打开)时显示turned on,状态为1(合上)时显示closed
如:
@K1:turned on 32-15
@B1:190 68-17
@L1:0.60 220-176
互斥开关按1、2引脚的接通状态显示,1,2接通-1,3断开时显示closed,1,3接通-1,2断开时显示turned on。
如:
@H1:turned on
受控窗帘显示窗帘打开的百分比,如:
@S1:80%
5、家居电路模拟系列所有题目的默认规则
1)当计算电压值等数值的过程中,最终结果出现小数时,用截尾规则去掉小数部分,只保留整数部分。为避免精度的误差,所有有可能出现小数的数值用double类型保存并计算,不要作下转型数据类型转换,例如电压、转速、亮度等,只有在最后输出时再把计算结果按截尾规则,舍弃尾数,保留整数输出。
2)所有连接信息按电路从靠电源端到靠接地端的顺序依次输入,不会出现错位的情况。VCC/IN一定是第一个连接的第一项,GND/OUT一定是最后一个连接的后一项。
3)连接信息如果只包含两个引脚,靠电源端的引脚在前,靠接地端的在后。
4)调速器的输入端只会直连VCC,不会接其他设备。整个电路最多只有连接在电源上的一个调速器,且不包含在并联单路中。
5)本系列题目中元件的管脚除了互斥开关的1引脚,其他所有引脚在电路中最多只出现一次。
6、本题新增内容:
1)增加管脚电压的显示
在输出每个电器的状态信息后,再依次输出该电器每个管脚的电压。(格式详见输出信息部分)
2)电流限制
电器在工作时,过大的电流会引起电器过热,从而烧坏电路。本次迭代,每个元器件都有最大电流的设置,当实时电流超过最大电流时,在该电器输出信息的最后加入提示“exceeding current limit error”,与前面的信息之间用英文空格分隔。
例如:@B1:190 68-17 exceeding current limit error
本题各类电器的最大限定电流如下:
开关20、分档调速器18、连续调速器18、白炽灯9、日光灯5、吊扇12、落地扇14、互斥开关20、受控窗帘12、二极管8。
3)短路检测
如果电路出现无穷大的电流造成短路,所有元器件信息不输出,仅输出提示“short circuit error”
4)并联电路中包含并联
本次迭代考虑并联电路中包含并联电路的情况,即构成并联电路的串联电路可以包含别的并联电路。例如如下输入的电路,并联电路M2的其中一条串联电路T4中包含了另一条并联电路M1:
T1:[IN D2-1] [D2-2 H1-2] [H1-1 OUT]
T2:[IN D1-1] [D1-2 H1-3] [H1-1 OUT]
M1:[T1 T2]
T4:[IN K3-1] [K3-2 M1-IN] [M1-OUT OUT]
T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
M2:[T4 T5]
5)二极管
增加二极管元件,其电路特性为:正向导通,反向截止;其电器符号如图4所示,当电流从左至右流过时,二极管导通”conduction”,电阻为0;电流从右至左流动时,二极管截止”cutoff”,电阻无穷大,相当于开关打开。
image.png
图2 二极管符号
二极管的标识符为’P’,左侧管脚编号为1,右侧管脚编号为2。
二极管如果两端电压相等,没有电流流过,分以下两种情况输出:
1、如果两端电压为0,二极管的导通/截止状态由接入方向决定,1号引脚靠近电源则状态为导通,反之为截止。
2、如果两端电压不为0,二极管导通。
7、设计建议
本题包含以下电路图中的所有连接情况:
image.png
图3 电路示意图
1、电路设备类:描述所有电路设备的公共特征。
2、受控设备类、控制设备类:对应受控、控制设备
3、串联电路类:一条由多个电路设备构成的串联电路,也看成是一个独立的电路设备
4、并联电路类:继承电路设备类,也看成是一个独立的电路设备
其他类以及类的属性、方法自行设计。
image.png
图4:建议设计类图
输入样例1:
在这里给出一组输入。例如:
T1:[IN P2-2] [P2-1 H1-2] [H1-1 OUT]
T2:[IN D1-1] [D1-2 H1-3] [H1-1 OUT]
M1:[T1 T2]
T4:[IN K3-1] [K3-2 M1-IN] [M1-OUT OUT]
T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
M2:[T4 T5]
T3:[VCC K2-1] [K2-2 M2-IN] [M2-OUT GND]
K1
K2
end
输出样例1:
在这里给出相应的输出。例如:
@K1:closed 220-220 exceeding current limit error
@K2:closed 220-220 exceeding current limit error
@K3:turned on 220-0
@B1:200 220-0 exceeding current limit error
@D1:0 0-0
@H1:closed 0-0-0
@P2:cutoff 0-0
输入样例2:
在这里给出一组输入。例如:
T1:[IN P2-1] [P2-2 H1-2] [H1-1 OUT]
T2:[IN D1-1] [D1-2 H1-3] [H1-1 OUT]
M1:[T1 T2]
T4:[IN K3-1] [K3-2 M1-IN] [M1-OUT OUT]
T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
M2:[T4 T5]
T3:[VCC K2-1] [K2-2 M2-IN] [M2-OUT GND]
K1
K3
K2
end
输出样例2:
在这里给出相应的输出。例如:
@K1:closed 220-220 exceeding current limit error
@K2:closed 220-220 exceeding current limit error
@K3:closed 220-220 exceeding current limit error
@B1:200 220-0 exceeding current limit error
@D1:0 220-220
@H1:closed 0-220-220 exceeding current limit error
@P2:conduction 220-220 exceeding current limit error
输入样例3:
在这里给出一组输入。例如:
T1:[IN P2-2] [P2-1 H1-2] [H1-1 OUT]
T2:[IN D1-1] [D1-2 H1-3] [H1-1 OUT]
M1:[T1 T2]
T4:[IN K3-1] [K3-2 M1-IN] [M1-OUT OUT]
T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
M2:[T4 T5]
T3:[VCC K2-1] [K2-2 M2-IN] [M2-OUT GND]
K1
K3
K2
end
输出样例3:
在这里给出相应的输出。例如:
@K1:closed 220-220 exceeding current limit error
@K2:closed 220-220 exceeding current limit error
@K3:closed 220-220
@B1:200 220-0 exceeding current limit error
@D1:0 220-220
@H1:closed 0-0-220
@P2:cutoff 0-220
输入样例4:
在这里给出一组输入。例如:
T3:[VCC K2-1] [K2-2 GND]
K2
end
输出样例4:
在这里给出相应的输出。例如:
short circuit error
输入样例5:
在这里给出一组输入。如果两端电压为0,二极管的导通/截止状态由接入方向决定,1号引脚靠近电源则状态为导通,反之截止。 例如:
T3:[VCC K2-2] [K2-1 P1-1] [P1-2 K1-2] [K1-1 GND]
end
输出样例5:
在这里给出相应的输出。例如:
@K1:turned on 0-0
@K2:turned on 0-220
@P1:conduction 0-0
输入样例6:
在这里给出一组输入。如果两端电压为0,二极管的导通/截止状态由接入方向决定,1号引脚靠近电源则状态为导通,反之截止。 例如:
T3:[VCC K2-2] [K2-1 P1-2] [P1-1 K1-2] [K1-1 GND]
end
输出样例6:
####### 。例如:
@K1:turned on 0-0
@K2:turned on 0-220
@P1:cutoff 0-0
我的主要代码
public class Main{public static void main(String[] args) {LinkedHashMap<String, Equipment> emap = new LinkedHashMap<>();LinkedList<String> controllist = new LinkedList<>();LinkedList<Parallel> binglist = new LinkedList<>();LinkedList<Series> chuanlist = new LinkedList<>();Scanner in = new Scanner(System.in);//输入while (true) {String newin = in.nextLine();if (newin.equals("end"))break;if (newin.startsWith("#T")) {Pattern pat = Pattern.compile("#(T\\d+):(.*)");Matcher mat = pat.matcher(newin);mat.find();String sname = mat.group(1);Equipment s = new Series(sname);Pattern pat1 = Pattern.compile("(\\w+)-(\\w+)");Matcher mat1 = pat1.matcher(newin);while (mat1.find()) {String id = mat1.group(1);String pin = mat1.group(2);Equipment e;if(id.matches("K\\d+")){e = new Switch(id,pin);}else if(id.matches("F\\d+")){e = new Devide(id,pin);}else if(id.matches("L\\d+")){e = new Continue(id,pin);}else if(id.matches("B\\d+"))e = new Bright(id,pin);else if(id.matches("R\\d+"))e = new Sun(id,pin);else if(id.matches("D\\d+"))e = new Fan(id,pin);else if(id.matches("A\\d+"))e = new AFan(id,pin);else if(id.matches("S\\d+"))e = new S(id,pin);else if(id.matches("P\\d+"))e = new P(id,pin);else if(id.matches("H\\d+")){if(!emap.containsKey(id)) {e = new Hswitch(id);if (pin.equals("3")) {((Hswitch) e).s3 = (Series) s;e.isreserve=true;} else if (pin.equals("2")) {((Hswitch) e).s2 = (Series) s;e.isreserve=true;}}else{if (pin.equals("3")) {((Hswitch) emap.get(id)).s3 = (Series) s;} else if (pin.equals("2")) {((Hswitch) emap.get(id)).s2 = (Series) s;}e = emap.get(id);}}else if(id.matches("M\\d+")){if(emap.containsKey(id))e=emap.get(id);elsee=null;}else if(id.matches("T\\d+")){if(emap.containsKey(id))e=emap.get(id);elsee=null;}elsee=null;if(!((Series) s).emap1.containsKey(id)&&e!=null){((Series) s).emap1.put(id,e);}if(!emap.containsKey(id)&&e!=null)emap.put(id,e);}emap.put(sname, s);chuanlist.add((Series) s);} else if (newin.startsWith("#M")) {Pattern pat = Pattern.compile("#(M\\d+):(.*)");Matcher mat = pat.matcher(newin);mat.find();String pname = mat.group(1);Equipment p = new Parallel(pname);int index = newin.indexOf(":");String str1 = newin.substring(index + 1, newin.length() - 1);String ps = str1.replaceAll("[\\[\\]]", "");String[] pa = ps.split("\\s+");for (int i = 0; i < pa.length; i++) {((Parallel) p).emap1.put(pa[i],emap.get(pa[i]));}emap.put(pname, p);binglist.add((Parallel) p);} else if (newin.startsWith("#K") || newin.startsWith("#L") || newin.startsWith("#F") || newin.startsWith("#H")) {controllist.add(newin);}}for (String cin : controllist) {if (cin.startsWith("#K")) {String k = cin.substring(1);if (emap.containsKey(k)) {((Switch) emap.get(k)).changestate();}} else if (cin.startsWith("#F")) {String f = cin.substring(1);int index1 = f.indexOf("F");int index2 = f.indexOf("+");int index3 = f.indexOf("-");if (index2 > 0) {String f1 = f.substring(index1, index2);if (emap.containsKey(f1)) {((Devide) emap.get(f1)).speedlevel++;}} else if (index3 > 0) {String f2 = f.substring(index1, index3);if (emap.containsKey(f2)) {((Devide) emap.get(f2)).speedlevel--;}}} else if (cin.startsWith("#L")) {String l = cin.substring(1);String l1[] = l.split(":");if (emap.containsKey(l1[0])) {((Continue) emap.get(l1[0])).setparameter(Double.parseDouble(l1[1]));}} else if (cin.startsWith("#H")) {String h = cin.substring(1);((Hswitch) emap.get(h)).change();}}for (int i = 0; i < chuanlist.size(); i++) {if(chuanlist.get(i)==null)continue;chuanlist.get(i).changestate();}for (String eid : emap.keySet()) {if (eid.matches("T\\d+")) {for (String id : ((Series) (emap.get(eid))).emap1.keySet()) {if (emap.get(id) instanceof Hswitch) {((Hswitch) emap.get(id)).changer();}else if(emap.get(id) instanceof Parallel){((Parallel) emap.get(id)).changer();}else if(emap.get(id) instanceof Series){for (String id1 : ((Series) (emap.get(id))).emap1.keySet()) {if (emap.get(id1) instanceof Hswitch) {((Hswitch) emap.get(id1)).changer();}else if(emap.get(id1) instanceof Parallel){((Parallel) emap.get(id1)).changer();}if(!emap.get(id).changestate1(emap.get(eid))) {emap.get(id).resistance=999999999;break;}if (emap.containsKey(id1)) {emap.get(id).resistance += emap.get(id1).resistance;if(emap.get(id).resistance>=999999999){break;}}}}if(!emap.get(eid).changestate1(emap.get(eid))) {emap.get(eid).resistance=999999999;break;}if (emap.containsKey(id)) {emap.get(eid).resistance += emap.get(id).resistance;if(emap.get(eid).resistance>=999999999){break;}}}}else if (eid.matches("M\\d+")) {((Parallel) emap.get(eid)).changer();}}//输出LinkedList<Equipment> elist = new LinkedList(emap.values());Equipment e = chuanlist.get(chuanlist.size() - 1);double v=220;for(String key:((Series)(e)).emap1.keySet()){Equipment a = ((Series)(e)).emap1.get(key);if(a instanceof Devide){v=((Devide)a).changeoutv(v);}else if(a instanceof Continue){v=((Continue)a).changeoutv(v);}e.v = v;e.inv=v;break;}((Series)e).changev();((Series)e).changepin();if(Math.abs(e.resistance)>1e-10){e.i =e.v / e.resistance;((Series)e).changei();}for(Equipment ae:elist){if(ae instanceof Bright){((Bright)ae).setlight(ae.v);}else if(ae instanceof Sun){((Sun)ae).setlight(ae.v);}else if(ae instanceof Fan){((Fan)ae).setrotate(ae.v);}else if(ae instanceof AFan){((AFan)ae).setrotate(ae.v);}}double light=0;for(int i=0;i<chuanlist.size();i++){Series series = chuanlist.get(i);for(String str:series.emap1.keySet()){if(str.startsWith("B")){light+=((Bright)series.emap1.get(str)).light;}else if(str.startsWith("R")){light+=((Sun)series.emap1.get(str)).light;}}}for(int i=0;i<chuanlist.size();i++){Series series = chuanlist.get(i);for(String str:series.emap1.keySet()){if(str.startsWith("S")){((S)series.emap1.get(str)).changeopenness(light);}}}Equipment t = elist.getLast();if(t.resistance==0){System.out.println("short circuit error");return;}Collections.sort(elist,new comparator());for(Equipment e1:elist){e1.display(e1);//System.out.println(e1.id+" "+e1.i);}}
}
abstract class Equipment{String type;String id;String pin;double resistance=0;double inv;double outv;double v;double electricity;double i;boolean isreserve = false;public Equipment(){}public Equipment(String type,String id){this.type=type;this.id=id;}public Equipment(String type,String id,String pin){this.type=type;this.id=id;this.pin=pin;}public abstract boolean changestate1(Equipment e);public void changev(circuit s){double allr = s.resistance;double allv = s.v;if(allr==0){v=0;resistance=0;return;}if(allv>=999999999){i=0;v=0;return;}v=resistance*allv/allr;//System.out.println(id+" "+resistance);}public void changelinkpin(Equipment pre, circuit c){double preVolt=0;if(pre instanceof Hswitch){if(pre.isreserve){preVolt = pre.inv;}else{if(((Hswitch) pre).s2==c){preVolt = ((Hswitch) pre).s2v;}else if(((Hswitch) pre).s3==c){preVolt = ((Hswitch) pre).s3v;}}}else preVolt = pre.outv;if(this instanceof Hswitch){if(this.isreserve){if(((Hswitch) this).s2==c){((Hswitch) this).s2v = preVolt;}else if(((Hswitch) this).s3==c){((Hswitch) this).s3v = preVolt;}}else{this.inv = preVolt;}}else this.inv = preVolt;}public void changepin(circuit e){if(changestate1(e)){if (this instanceof Hswitch){boolean isT2=(((Hswitch) this).s2 == e);boolean isT3=(((Hswitch) this).s3 == e);if (isreserve){if (isT2)this.inv = ((Hswitch) this).s2v - v;else if (isT3)this.inv = ((Hswitch) this).s3v - v;}else{if (isT2)((Hswitch) this).s2v = inv - v;else if (isT3)((Hswitch) this).s3v = inv - v;}if(((Hswitch) this).s2v < 0)((Hswitch) this).s2v = 0;if(((Hswitch) this).s3v < 0)((Hswitch) this).s3v = 0;}outv = inv - v;}if (outv < 0)outv = 0;}public void changereserve(){if(pin.equals("2"))isreserve=true;elseisreserve=false;}public void display(Equipment e){if(!(e instanceof Hswitch)&&!(e instanceof Series)&&!(e instanceof Parallel))e.changereserve();if(type.equals("K")){if(e.i>e.electricity) {if (((Switch) e).state == 0) {if(!isreserve)System.out.println("@" + id + ":turned on" + String.format(" %d-%d", ((int) inv), ((int) outv)) + " exceeding current limit error");elseSystem.out.println("@" + id + ":turned on" + String.format(" %d-%d", ((int) outv), ((int) inv)) + " exceeding current limit error");}else if (((Switch) e).state == 1) {if (!isreserve)System.out.println("@" + id + ":closed" + String.format(" %d-%d", ((int) inv), ((int) outv)) + " exceeding current limit error");elseSystem.out.println("@" + id + ":closed" + String.format(" %d-%d", ((int) outv), ((int) inv)) + " exceeding current limit error");}}else{if (((Switch) e).state == 0) {if (!isreserve)System.out.println("@" + id + ":turned on" + String.format(" %d-%d", ((int) inv), ((int) outv)));elseSystem.out.println("@" + id + ":turned on" + String.format(" %d-%d", ((int) outv), ((int) inv)));}else if (((Switch) e).state == 1) {if (!isreserve)System.out.println("@" + id + ":closed" + String.format(" %d-%d", ((int) inv), ((int) outv)));elseSystem.out.println("@" + id + ":closed" + String.format(" %d-%d", ((int) outv), ((int) inv)));}}}else if(type.equals("F")){if(e.i>e.electricity) {if(!isreserve)System.out.println("@" + id + ":" + ((Devide) e).speedlevel+String.format(" %d-%d",((int)inv),((int)outv))+" exceeding current limit error");elseSystem.out.println("@" + id + ":" + ((Devide) e).speedlevel+String.format(" %d-%d",((int) outv), ((int) inv))+" exceeding current limit error");}else{if(!isreserve)System.out.println("@" + id + ":" + ((Devide) e).speedlevel+String.format(" %d-%d",((int)inv),((int)outv)));elseSystem.out.println("@" + id + ":" + ((Devide) e).speedlevel+String.format(" %d-%d",((int) outv), ((int) inv)));}}else if(type.equals("L")){if(e.i>e.electricity) {if(!isreserve)System.out.println("@" + id + ":" + String.format("%.2f", ((Continue) e).parameter)+String.format(" %d-%d",((int)inv),((int)outv))+" exceeding current limit error");elseSystem.out.println("@" + id + ":" + String.format("%.2f", ((Continue) e).parameter)+String.format(" %d-%d",((int)outv),((int)inv))+" exceeding current limit error");}else{if(!isreserve)System.out.println("@" + id + ":" + String.format("%.2f", ((Continue) e).parameter)+String.format(" %d-%d",((int)inv),((int)outv)));elseSystem.out.println("@" + id + ":" + String.format("%.2f", ((Continue) e).parameter)+String.format(" %d-%d",((int)outv),((int)inv)));}}else if(type.equals("B")){if(e.i>e.electricity) {if(!isreserve)System.out.println("@" + id + ":" + (int) Math.floor(((Bright) e).light)+String.format(" %d-%d",((int)inv),((int)outv))+" exceeding current limit error");elseSystem.out.println("@" + id + ":" + (int) Math.floor(((Bright) e).light)+String.format(" %d-%d",((int)outv),((int)inv))+" exceeding current limit error");}else{if(!isreserve)System.out.println("@" + id + ":" + (int) Math.floor(((Bright) e).light)+String.format(" %d-%d",((int)inv),((int)outv)));elseSystem.out.println("@" + id + ":" + (int) Math.floor(((Bright) e).light)+String.format(" %d-%d",((int)outv),((int)inv)));}}else if(type.equals("R")){if(e.i>e.electricity) {if(!isreserve)System.out.println("@" + id + ":" + (int) Math.floor(((Sun) e).light)+String.format(" %d-%d",((int)inv),((int)outv))+" exceeding current limit error");elseSystem.out.println("@" + id + ":" + (int) Math.floor(((Sun) e).light)+String.format(" %d-%d",((int)outv),((int)inv))+" exceeding current limit error");}else{if(!isreserve)System.out.println("@" + id + ":" + (int) Math.floor(((Sun) e).light)+String.format(" %d-%d",((int)inv),((int)outv)));elseSystem.out.println("@" + id + ":" + (int) Math.floor(((Sun) e).light)+String.format(" %d-%d",((int)outv),((int)inv)));}}else if(type.equals("D")){if(e.i>e.electricity) {if(!isreserve)System.out.println("@" + id + ":" + (int) Math.floor(((Fan) e).rotate)+String.format(" %d-%d",((int)inv),((int)outv))+" exceeding current limit error");elseSystem.out.println("@" + id + ":" + (int) Math.floor(((Fan) e).rotate)+String.format(" %d-%d",((int)outv),((int)inv))+" exceeding current limit error");}else{if(!isreserve)System.out.println("@" + id + ":" + (int) Math.floor(((Fan) e).rotate)+String.format(" %d-%d",((int)inv),((int)outv)));elseSystem.out.println("@" + id + ":" + (int) Math.floor(((Fan) e).rotate)+String.format(" %d-%d",((int)outv),((int)inv)));}}else if(type.equals("A")){if(e.i>e.electricity) {if(!isreserve)System.out.println("@" + id + ":" + (int) Math.floor(((AFan) e).rotate)+String.format(" %d-%d",((int)inv),((int)outv))+" exceeding current limit error");elseSystem.out.println("@" + id + ":" + (int) Math.floor(((AFan) e).rotate)+String.format(" %d-%d",((int)outv),((int)inv))+" exceeding current limit error");}else{if(!isreserve)System.out.println("@" + id + ":" + (int) Math.floor(((AFan) e).rotate)+String.format(" %d-%d",((int)inv),((int)outv)));elseSystem.out.println("@" + id + ":" + (int) Math.floor(((AFan) e).rotate)+String.format(" %d-%d",((int)outv),((int)inv)));}}else if(type.equals("S1")){if(e.i>e.electricity) {if(!isreserve)System.out.println("@" + id + ":" + ((S) e).openness+String.format(" %d-%d",((int)inv),((int)outv))+" exceeding current limit error");elseSystem.out.println("@" + id + ":" + ((S) e).openness+String.format(" %d-%d",((int)outv),((int)inv))+" exceeding current limit error");}else{if(!isreserve)System.out.println("@" + id + ":" + ((S) e).openness+String.format(" %d-%d",((int)inv),((int)outv)));elseSystem.out.println("@" + id + ":" + ((S) e).openness+String.format(" %d-%d",((int)outv),((int)inv)));}}else if(type.equals("P1")){if(e.i>e.electricity){if(((P)e).state==1) {if(!isreserve)System.out.println("@" + id + ":" + "conduction" + String.format(" %d-%d", ((int) inv), ((int) outv)) + " exceeding current limit error");elseSystem.out.println("@" + id + ":" + "conduction" + String.format(" %d-%d", ((int) outv), ((int) inv)) + " exceeding current limit error");}else {if(!isreserve)System.out.println("@" + id + ":" + "cutoff" + String.format(" %d-%d", ((int) inv), ((int) outv)) + " exceeding current limit error");elseSystem.out.println("@" + id + ":" + "cutoff" + String.format(" %d-%d", ((int) outv), ((int) inv)) + " exceeding current limit error");}}else{if(((P)e).state==1) {if (!isreserve)System.out.println("@" + id + ":" + "conduction" + String.format(" %d-%d", ((int) inv), ((int) outv)) );elseSystem.out.println("@" + id + ":" + "conduction" + String.format(" %d-%d", ((int) outv), ((int) inv)) );}else {if (!isreserve)System.out.println("@" + id + ":" + "cutoff" + String.format(" %d-%d", ((int) inv), ((int) outv)) );elseSystem.out.println("@" + id + ":" + "cutoff" + String.format(" %d-%d", ((int) outv), ((int) inv)) );}}}else if (e instanceof Hswitch){if (e.i > e.electricity){System.out.println("@" + id + ":" + ((Hswitch) e).state + String.format(" %d-%d-%d", (int)(e.inv), (int)((Hswitch) e).s2v, (int)((Hswitch) e).s3v) + " exceeding current limit error");}else {System.out.println("@" + id + ":" + ((Hswitch) e).state + String.format(" %d-%d-%d", (int)(e.inv), (int)((Hswitch) e).s2v, (int)((Hswitch) e).s3v));}}}protected void R_changelinkpin(Equipment ne, circuit c) {double neVolt=0;if(ne instanceof Hswitch){if(ne.isreserve){if(((Hswitch) ne).s2 == c){neVolt = ((Hswitch) ne).s2v;}else if(((Hswitch) ne).s3 == c){neVolt = ((Hswitch) ne).s3v;}}else{neVolt = ne.inv;}}else neVolt = ne.inv;if(this instanceof Hswitch){if(this.isreserve){this.inv = neVolt;}else{if(((Hswitch) this).s2.id == c.id){((Hswitch) this).s2v = neVolt;}else if(((Hswitch) this).s3.id == c.id){((Hswitch) this).s3v = neVolt;}}}else this.outv = neVolt;}protected void R_changepin(circuit e) {if(changestate1(e)){if(this instanceof Hswitch){boolean isT2=false;boolean isT3=false;if(((Hswitch) this).s2!=null)isT2 = Objects.equals(((Hswitch) this).s2.id, e.id);if(((Hswitch) this).s3!=null)isT3= Objects.equals(((Hswitch) this).s3.id, e.id);if(isreserve){if(isT2)((Hswitch) this).s2v = inv;else if(isT3)((Hswitch) this).s3v = inv;}else{if(isT2)inv = ((Hswitch) this).s2v;else if(isT3)inv = ((Hswitch) this).s3v;}}elseinv = outv;}}
}
踩坑心得
在本题的新增内容中,我们引入了以下三个重要更新:
管脚电压显示:在输出每个电器的状态信息后,新增了显示每个电器每个管脚的电压。这项功能可以帮助用户更好地了解电路中各个元器件的工作状态。
电流限制:为了保护电路中的元器件不过热烧坏,每个元器件都设置了最大电流限制。当实时电流超过最大限制时,输出信息中会提示“exceeding current limit error”。这项更新可以提醒用户注意电流的控制,避免元器件损坏。
短路检测:若电路出现无穷大的电流造成短路,将输出提示“short circuit error”,并不输出任何元器件信息。这是为了及时发现电路中的短路问题,确保电路安全运行。
总结
在前两次作业中,我们围绕智能家居系统的仿真模拟进行了功能扩展和性能优化。以下是对这两次作业的总结:
第一次作业:
实现了基本电路元器件的模拟,包括开关、调速器、灯具、风扇等,使用户能够搭建简单的家居控制电路。
提供了元器件状态显示和控制操作,用户可以通过控制台实时查看和改变元器件的状态。
引入了互斥开关和设备连接功能,增加了电路的复杂性和灵活性。
第二次作业:
添加了管脚电压显示功能,增强了用户对电路中各元器件工作状态的了解。
引入了电流限制设置和显示,帮助用户控制电路中的电流,避免元器件过热损坏。
增加了短路检测功能,及时发现电路中的短路问题,保障电路安全运行。
通过这两次作业的迭代,智能家居系统的仿真模拟功能更加完善,用户体验得到了提升,功能更加强大、实用和安全。希望通过持续地改进和优化,为用户提供更好的智能家居电路模拟体验,促进智能家居领域的发展和应用。