比较闲暇的时间,为了保持点编程的工作量,帮忙解决了一个小小的编程问题。由于本人并非该专业的学生,对于专业问题就门外汉了,本文主要以解决编程问题的思维来记录这个过程。
为了更好的解决城市洪涝问题,在某小区内铺设海绵城市设施(LID设施)并检验其效果,根据遗传算法的筛选,找到在不同降雨条件下小区中布置排水设施的最优方案。
另行讨论。
a) 寻找目标函数
b) 初始化
c) 进行适应度概率计算
d) 优胜劣汰(保留优项)
e) 重组、交叉、变异
f) 化为表现型,适应度概率计算
g) 迭代至满足要求
h) 按照适应度高低输出结果
a) 将子汇水区看作是基因,用1和0来表示子汇水区上面是否有排水设施(LID设施)。比如设定1表示该子汇水区存在LID设施(LID类型可能有好几种),0则代表没有设施。
b) 利用swmm软件计算初设种群的目标函数作没有优化时的对照。
c) 交叉、重组、变异之后得到子代。
交叉:例如设定交叉概率为0.5,当P>0.5时,子汇水区1与子汇水区2的LID布设方式进行交换。P<0.5时,保留原状。
变异:例如设定变异概率为0.5,当P<0.5时,对子汇水区1中的LID类型做变换。当0.8>P>0.5时,子汇水区上的LID设施不做改变。当P>0.8时,子汇水区1插入(或增设)一种LID设施。
d) 父代与子代合并,得到2n个个体。
e) 2n个个体进行非支配排序。
f) 计算拥挤度,选择拥挤度较大的目标进行探索。
g) 根据计算出的排序以及拥挤度筛选新的父代。
h) 直至达到设定的循环代数。找到pareto曲线,这条曲线上面的点都是最优解。
最后要求得到pareto前沿曲线,即第一序列曲线(最优前沿曲线),并找几个方案进行比较,可以找最极端的方案,分析最特殊的点(例如两头的点)如:当完全不考虑成本时,或当追求成本最小时,可能lid表现并不很好,但还是有一定效果。
因为流程大致是修改输入inp文件、通过inp文件模拟swmm得到输出out文件、根据out文件判断子代是否保留等、再修改输入inp文件,不断重复。swmm是个开源程序,手动实现迭代进化肯定不现实,一开始把目标放在了matswmm上。然而所需的几个关键指标不能通过matswmm直接进行提取和修改,非常繁琐,则考虑通过pyswmm实现。此外由于该流程如何实现NSGA-Ⅱ不是重点,则直接使用pymoo库实现算法。
GitHub地址在这:pymoo官方仓库
此外还有官方的简单教程:官方文档
在本问题中需要提取并修改LID的面积,仿真,得到子汇水区的径流量,得到节点的超载时间
这里先给出test文件代码,里面是进行pyswmm调用的测试,部分地方给出了注释。
"""
@File:test.py
@Author:MJZJZ
@Version:1.0
@Date:2023/04/16
@Time:10:55
"""
import numpy as np
# pyswmm需要的module
from pyswmm import Simulation, Nodes, Subcatchments, LidGroups
x = [2.66, 0.49, 0.68, 0.23, 0.06, 0.04, 0.44, 0.04, 0.03, 0.07, 0.72, 4.81, 0.47, 0.34,
3.29, 0.01, 0.09, 0.21, 0.49, 2.94, 0.26, 3.01, 0.06, 0.05, 2.34, 0.20, 0.02, 0.67,
0.13, 0.19, 0.00, 0.02, 0.17, 5.07, 0.28, 2.62, 0.09, 4.41, 2.68, 0.20, 6.28, 2.75,
0.10, 10.27, 5.00, 1.57, 0.78, 0.02, 0.50, 0.07, 0.92, 0.03, 6.03, 0.40, 0.20, 0.80,
0.01, 1.11, 0.02, 0.00, 0.07] # 测试
# 读取inp文件作为仿真对象
with Simulation(r'C:\Users\13618\Desktop\inp\P=10.inp') as sim:
LidGroups(sim)['H00000'][0].unit_area = x[0] # 设定inp文件里的LID面积
LidGroups(sim)['H00000'][1].unit_area = x[1] # 该文件里不同subcatchments(子汇水区)的LID项数不一样 手动添加所有项
LidGroups(sim)['H00001'][0].unit_area = x[2] # 对应inp文件的[LID_USAGE]
LidGroups(sim)['H00001'][1].unit_area = x[3]
LidGroups(sim)['H00002'][0].unit_area = x[4]
LidGroups(sim)['H00004'][0].unit_area = x[5]
LidGroups(sim)['H00005'][0].unit_area = x[6]
LidGroups(sim)['H00006'][0].unit_area = x[7]
LidGroups(sim)['H00007'][0].unit_area = x[8]
LidGroups(sim)['H00008'][0].unit_area = x[9]
LidGroups(sim)['H00009'][0].unit_area = x[10]
LidGroups(sim)['H00009'][1].unit_area = x[11]
LidGroups(sim)['H00010'][0].unit_area = x[12]
LidGroups(sim)['H00011'][0].unit_area = x[13]
LidGroups(sim)['H00012'][0].unit_area = x[14]
LidGroups(sim)['H00013'][0].unit_area = x[15]
LidGroups(sim)['H00014'][0].unit_area = x[16]
LidGroups(sim)['H00015'][0].unit_area = x[17]
LidGroups(sim)['H00015'][1].unit_area = x[18]
LidGroups(sim)['H00016'][0].unit_area = x[19]
LidGroups(sim)['H00017'][0].unit_area = x[20]
LidGroups(sim)['H00018'][0].unit_area = x[21]
LidGroups(sim)['H00019'][0].unit_area = x[22]
LidGroups(sim)['H00020'][0].unit_area = x[23]
LidGroups(sim)['H00021'][0].unit_area = x[24]
LidGroups(sim)['H00021'][1].unit_area = x[25]
LidGroups(sim)['H00022'][0].unit_area = x[26]
LidGroups(sim)['H00023'][0].unit_area = x[27]
LidGroups(sim)['H00024'][0].unit_area = x[28]
LidGroups(sim)['H00025'][0].unit_area = x[29]
LidGroups(sim)['H00026'][0].unit_area = x[30]
LidGroups(sim)['H00027'][0].unit_area = x[31]
LidGroups(sim)['H00029'][0].unit_area = x[32]
LidGroups(sim)['H00029'][1].unit_area = x[33]
LidGroups(sim)['H00031'][0].unit_area = x[34]
LidGroups(sim)['H00032'][0].unit_area = x[35]
LidGroups(sim)['H00032'][1].unit_area = x[36]
LidGroups(sim)['H00034'][0].unit_area = x[37]
LidGroups(sim)['H00035'][0].unit_area = x[38]
LidGroups(sim)['H00036'][0].unit_area = x[39]
LidGroups(sim)['H00036'][1].unit_area = x[40]
LidGroups(sim)['H00037'][0].unit_area = x[41]
LidGroups(sim)['H00038'][0].unit_area = x[42]
LidGroups(sim)['H00038'][1].unit_area = x[43]
LidGroups(sim)['H00039'][0].unit_area = x[44]
LidGroups(sim)['H00041'][0].unit_area = x[45]
LidGroups(sim)['H00044'][0].unit_area = x[46]
LidGroups(sim)['H00046'][0].unit_area = x[47]
LidGroups(sim)['H00047'][0].unit_area = x[48]
LidGroups(sim)['H00047'][1].unit_area = x[49]
LidGroups(sim)['H00048'][0].unit_area = x[50]
LidGroups(sim)['H00048'][1].unit_area = x[51]
LidGroups(sim)['H00049'][0].unit_area = x[52]
LidGroups(sim)['H00051'][0].unit_area = x[53]
LidGroups(sim)['H00052'][0].unit_area = x[54]
LidGroups(sim)['H00053'][0].unit_area = x[55]
LidGroups(sim)['H00053'][1].unit_area = x[56]
LidGroups(sim)['H00054'][0].unit_area = x[57]
LidGroups(sim)['H00054'][1].unit_area = x[58]
LidGroups(sim)['H00055'][0].unit_area = x[59]
LidGroups(sim)['H00056'][0].unit_area = x[60]
# 开始仿真
for step in enumerate(sim):
pass # 若需要每步的仿真都修改 则在这里添加代码
# 本问题只需完整仿真完 直接pass即可
# 仿真结束
lid_area = np.array(np.zeros(61)) # 便于后续使用所有子汇水区LID面积 放在数组里
lid_area[0] = LidGroups(sim)['H00000'][0].unit_area # 仿真后提取各子汇水区LID面积(实际则为上面设定的x,这是为了方便测试)
lid_area[1] = LidGroups(sim)['H00000'][1].unit_area
lid_area[2] = LidGroups(sim)['H00001'][0].unit_area
lid_area[3] = LidGroups(sim)['H00001'][1].unit_area
lid_area[4] = LidGroups(sim)['H00002'][0].unit_area
lid_area[5] = LidGroups(sim)['H00004'][0].unit_area
lid_area[6] = LidGroups(sim)['H00005'][0].unit_area
lid_area[7] = LidGroups(sim)['H00006'][0].unit_area
lid_area[8] = LidGroups(sim)['H00007'][0].unit_area
lid_area[9] = LidGroups(sim)['H00008'][0].unit_area
lid_area[10] = LidGroups(sim)['H00009'][0].unit_area
lid_area[11] = LidGroups(sim)['H00009'][1].unit_area
lid_area[12] = LidGroups(sim)['H00010'][0].unit_area
lid_area[13] = LidGroups(sim)['H00011'][0].unit_area
lid_area[14] = LidGroups(sim)['H00012'][0].unit_area
lid_area[15] = LidGroups(sim)['H00013'][0].unit_area
lid_area[16] = LidGroups(sim)['H00014'][0].unit_area
lid_area[17] = LidGroups(sim)['H00015'][0].unit_area
lid_area[18] = LidGroups(sim)['H00015'][1].unit_area
lid_area[19] = LidGroups(sim)['H00016'][0].unit_area
lid_area[20] = LidGroups(sim)['H00017'][0].unit_area
lid_area[21] = LidGroups(sim)['H00018'][0].unit_area
lid_area[22] = LidGroups(sim)['H00019'][0].unit_area
lid_area[23] = LidGroups(sim)['H00020'][0].unit_area
lid_area[24] = LidGroups(sim)['H00021'][0].unit_area
lid_area[25] = LidGroups(sim)['H00021'][1].unit_area
lid_area[26] = LidGroups(sim)['H00022'][0].unit_area
lid_area[27] = LidGroups(sim)['H00023'][0].unit_area
lid_area[28] = LidGroups(sim)['H00024'][0].unit_area
lid_area[29] = LidGroups(sim)['H00025'][0].unit_area
lid_area[30] = LidGroups(sim)['H00026'][0].unit_area
lid_area[31] = LidGroups(sim)['H00027'][0].unit_area
lid_area[32] = LidGroups(sim)['H00029'][0].unit_area
lid_area[33] = LidGroups(sim)['H00029'][1].unit_area
lid_area[34] = LidGroups(sim)['H00031'][0].unit_area
lid_area[35] = LidGroups(sim)['H00032'][0].unit_area
lid_area[36] = LidGroups(sim)['H00032'][1].unit_area
lid_area[37] = LidGroups(sim)['H00034'][0].unit_area
lid_area[38] = LidGroups(sim)['H00035'][0].unit_area
lid_area[39] = LidGroups(sim)['H00036'][0].unit_area
lid_area[40] = LidGroups(sim)['H00036'][1].unit_area
lid_area[41] = LidGroups(sim)['H00037'][0].unit_area
lid_area[42] = LidGroups(sim)['H00038'][0].unit_area
lid_area[43] = LidGroups(sim)['H00038'][1].unit_area
lid_area[44] = LidGroups(sim)['H00039'][0].unit_area
lid_area[45] = LidGroups(sim)['H00041'][0].unit_area
lid_area[46] = LidGroups(sim)['H00044'][0].unit_area
lid_area[47] = LidGroups(sim)['H00046'][0].unit_area
lid_area[48] = LidGroups(sim)['H00047'][0].unit_area
lid_area[49] = LidGroups(sim)['H00047'][1].unit_area
lid_area[50] = LidGroups(sim)['H00048'][0].unit_area
lid_area[51] = LidGroups(sim)['H00048'][1].unit_area
lid_area[52] = LidGroups(sim)['H00049'][0].unit_area
lid_area[53] = LidGroups(sim)['H00051'][0].unit_area
lid_area[54] = LidGroups(sim)['H00052'][0].unit_area
lid_area[55] = LidGroups(sim)['H00053'][0].unit_area
lid_area[56] = LidGroups(sim)['H00053'][1].unit_area
lid_area[57] = LidGroups(sim)['H00054'][0].unit_area
lid_area[58] = LidGroups(sim)['H00054'][1].unit_area
lid_area[59] = LidGroups(sim)['H00055'][0].unit_area
lid_area[60] = LidGroups(sim)['H00056'][0].unit_area
# 下面是优化函数1的计算 需要各类型LID的面积分别求和
a_lswd = lid_area[1] + lid_area[3] + lid_area[5] + lid_area[6] + lid_area[7] \
+ lid_area[10] + lid_area[12] + lid_area[13] + lid_area[14] + lid_area[17] \
+ lid_area[19] + lid_area[20] + lid_area[21] + lid_area[24] + lid_area[26] \
+ lid_area[27] + lid_area[28] + lid_area[32] + lid_area[34] + lid_area[39] \
+ lid_area[42] + lid_area[46] + lid_area[47] + lid_area[48] + lid_area[50] \
+ lid_area[52] + lid_area[53] + lid_area[54] + lid_area[55] + lid_area[57] \
+ lid_area[59] + lid_area[60]
b_xcsld = lid_area[0] + lid_area[2] + lid_area[11] + lid_area[18] + lid_area[25] \
+ lid_area[33] + lid_area[35] + lid_area[37] + lid_area[38] + lid_area[40] \
+ lid_area[41] + lid_area[43] + lid_area[44] + lid_area[45]
d_tslm = lid_area[4] + lid_area[8] + lid_area[9] + lid_area[15] + lid_area[16] \
+ lid_area[22] + lid_area[23] + lid_area[29] + lid_area[30] + lid_area[31] \
+ lid_area[36] + lid_area[49] + lid_area[51] + lid_area[56] + lid_area[58]
# max R 径流量
# 目前的径流量runoff只在subcatchment的statistic函数里保存 需要单独提取出来 单位不一致 需要单独换算
# 详见https://github.com/OpenWaterAnalytics/pyswmm/discussions/416 开发团队已表示pyswmm2将会认真考虑该问题
subcatchment_runoff = np.array(np.zeros(57))
for i in range(10):
subcatchment_runoff[i] = Subcatchments(sim)["H0000" + str(i)].statistics['runoff'] / Subcatchments(sim)[
"H0000" + str(i)].area / 10
for i in range(10, 57):
subcatchment_runoff[i] = Subcatchments(sim)["H000" + str(i)].statistics['runoff'] / Subcatchments(sim)[
"H000" + str(i)].area / 10
R = 0
# global Pre_runoff
# for i in range(57):
# R = R + (subcatchment_runoff[i] - Pre_runoff[i]) / Pre_runoff[i]
# Pre_runoff = subcatchment_runoff
for i in range(57):
R = R + subcatchment_runoff[i]
print(R)
# min T 节点超载时间
# 节点超载时间surcharge_duration同样在node的statistic函数里保存 这些都在官网的文档里有描述函数用法
node_surcharged_duration = np.array(np.zeros(57))
for i in range(1, 10):
node_surcharged_duration[i - 1] = Nodes(sim)[str("J00" + str(i))].statistics['surcharge_duration']
for i in range(10, 58):
node_surcharged_duration[i - 1] = Nodes(sim)["J0" + str(i)].statistics['surcharge_duration']
T = np.sum(node_surcharged_duration) / 57
# 计算三个优化函数的测试
f1 = 221.64 * a_lswd + 110.78 * b_xcsld + 303.13 * d_tslm
f2 = R / 4037.39 - 1
f3 = T
# 一些测试
print("\narea1:{} ".format(lid_area[0]))
print("area2:{} ".format(lid_area[1]))
print("area3:{}\n ".format(lid_area[2]))
print(f1)
print(f2)
print(f3)
# 更新 养成好习惯 关闭仿真
sim.close()
GitHub地址:pymoo官方仓库
官网:官方文档
用途可以说非常多了,本人基本是对着官方文档,自定义ElementwiseProblem,调用了NSGA-Ⅱ算法,将输出的Design space values、Objective spaces values、Constraint values分别保存下来。测试用例基本是按官网给的,这里就不贴了。
"""
@File:swmm_nsga2.py
@Author:MJZJZ
@Version:1.0
@Date:2023/04/03
@Time:14:31
"""
import numpy as np
from pyswmm import Simulation, Nodes, Subcatchments, LidGroups
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.core.problem import ElementwiseProblem
from pymoo.optimize import minimize
from pymoo.visualization.scatter import Scatter
# Pre_runoff = [28.84793721, 31.06321707, 11.96966298, 29.81131282, 22.76600575, 20.5654663,
# 32.03460237, 11.54445679, 11.39371698, 29.31124099, 26.40671222, 23.23278734,
# 29.09242243, 14.4631284, 13.2157434, 29.24380799, 26.48086273, 19.48246667,
# 29.14060795, 11.70136631, 12.75527874, 29.25169541, 26.61230667, 27.28638322,
# 26.29139334, 12.81874815, 13.18556032, 18.39743068, 26.2929191, 29.45805644,
# 29.632263, 24.50601238, 22.87947793, 26.18072453, 30.5640098, 28.75785111,
# 29.25407989, 28.78694888, 29.23303827, 30.4157768, 29.4229525, 29.88916333,
# 30.6586755, 29.72818431, 29.14815945, 32.80225754, 29.03260243, 15.24535308,
# 22.10563715, 28.67348727, 29.36437599, 31.8935914, 29.07932792, 23.60885133,
# 23.93630402, 29.05591441, 29.04791563]
# 用ElementwiseProblem自定义优化问题
class MyProblem(ElementwiseProblem):
# 初始化
def __init__(self):
super().__init__(n_var=61, # 自变量个数
n_obj=3, # 优化目标函数个数
n_ieq_constr=4, # 约束个数
xl=0.0, # 自变量约束 这里上下限一样就直接用一个数来表示 否则可以用数组的形式
xu=300.0)
# 重写问题 这里直接在_evaluate下写pyswmm的部分
def _evaluate(self, x, out, *args, **kwargs):
with Simulation(r'C:\Users\13618\Desktop\inp\P=1.inp') as sim:
LidGroups(sim)['H00000'][0].unit_area = x[0] # 设定inp文件里的LID面积
LidGroups(sim)['H00000'][1].unit_area = x[1] # 该文件里不同subcatchments(子汇水区)的LID项数不一样 手动添加所有项
LidGroups(sim)['H00001'][0].unit_area = x[2] # 对应inp文件的[LID_USAGE]
LidGroups(sim)['H00001'][1].unit_area = x[3]
LidGroups(sim)['H00002'][0].unit_area = x[4]
LidGroups(sim)['H00004'][0].unit_area = x[5]
LidGroups(sim)['H00005'][0].unit_area = x[6]
LidGroups(sim)['H00006'][0].unit_area = x[7]
LidGroups(sim)['H00007'][0].unit_area = x[8]
LidGroups(sim)['H00008'][0].unit_area = x[9]
LidGroups(sim)['H00009'][0].unit_area = x[10]
LidGroups(sim)['H00009'][1].unit_area = x[11]
LidGroups(sim)['H00010'][0].unit_area = x[12]
LidGroups(sim)['H00011'][0].unit_area = x[13]
LidGroups(sim)['H00012'][0].unit_area = x[14]
LidGroups(sim)['H00013'][0].unit_area = x[15]
LidGroups(sim)['H00014'][0].unit_area = x[16]
LidGroups(sim)['H00015'][0].unit_area = x[17]
LidGroups(sim)['H00015'][1].unit_area = x[18]
LidGroups(sim)['H00016'][0].unit_area = x[19]
LidGroups(sim)['H00017'][0].unit_area = x[20]
LidGroups(sim)['H00018'][0].unit_area = x[21]
LidGroups(sim)['H00019'][0].unit_area = x[22]
LidGroups(sim)['H00020'][0].unit_area = x[23]
LidGroups(sim)['H00021'][0].unit_area = x[24]
LidGroups(sim)['H00021'][1].unit_area = x[25]
LidGroups(sim)['H00022'][0].unit_area = x[26]
LidGroups(sim)['H00023'][0].unit_area = x[27]
LidGroups(sim)['H00024'][0].unit_area = x[28]
LidGroups(sim)['H00025'][0].unit_area = x[29]
LidGroups(sim)['H00026'][0].unit_area = x[30]
LidGroups(sim)['H00027'][0].unit_area = x[31]
LidGroups(sim)['H00029'][0].unit_area = x[32]
LidGroups(sim)['H00029'][1].unit_area = x[33]
LidGroups(sim)['H00031'][0].unit_area = x[34]
LidGroups(sim)['H00032'][0].unit_area = x[35]
LidGroups(sim)['H00032'][1].unit_area = x[36]
LidGroups(sim)['H00034'][0].unit_area = x[37]
LidGroups(sim)['H00035'][0].unit_area = x[38]
LidGroups(sim)['H00036'][0].unit_area = x[39]
LidGroups(sim)['H00036'][1].unit_area = x[40]
LidGroups(sim)['H00037'][0].unit_area = x[41]
LidGroups(sim)['H00038'][0].unit_area = x[42]
LidGroups(sim)['H00038'][1].unit_area = x[43]
LidGroups(sim)['H00039'][0].unit_area = x[44]
LidGroups(sim)['H00041'][0].unit_area = x[45]
LidGroups(sim)['H00044'][0].unit_area = x[46]
LidGroups(sim)['H00046'][0].unit_area = x[47]
LidGroups(sim)['H00047'][0].unit_area = x[48]
LidGroups(sim)['H00047'][1].unit_area = x[49]
LidGroups(sim)['H00048'][0].unit_area = x[50]
LidGroups(sim)['H00048'][1].unit_area = x[51]
LidGroups(sim)['H00049'][0].unit_area = x[52]
LidGroups(sim)['H00051'][0].unit_area = x[53]
LidGroups(sim)['H00052'][0].unit_area = x[54]
LidGroups(sim)['H00053'][0].unit_area = x[55]
LidGroups(sim)['H00053'][1].unit_area = x[56]
LidGroups(sim)['H00054'][0].unit_area = x[57]
LidGroups(sim)['H00054'][1].unit_area = x[58]
LidGroups(sim)['H00055'][0].unit_area = x[59]
LidGroups(sim)['H00056'][0].unit_area = x[60]
# 开始仿真
for step in enumerate(sim):
pass # 若需要每步的仿真都修改 则在这里添加代码
# 本问题只需完整仿真完 直接pass即可
# 仿真结束
lid_area = np.array(np.zeros(61)) # 便于后续使用所有子汇水区LID面积 放在数组里
lid_area[0] = LidGroups(sim)['H00000'][0].unit_area # 仿真后提取各子汇水区LID面积
lid_area[1] = LidGroups(sim)['H00000'][1].unit_area
lid_area[2] = LidGroups(sim)['H00001'][0].unit_area
lid_area[3] = LidGroups(sim)['H00001'][1].unit_area
lid_area[4] = LidGroups(sim)['H00002'][0].unit_area
lid_area[5] = LidGroups(sim)['H00004'][0].unit_area
lid_area[6] = LidGroups(sim)['H00005'][0].unit_area
lid_area[7] = LidGroups(sim)['H00006'][0].unit_area
lid_area[8] = LidGroups(sim)['H00007'][0].unit_area
lid_area[9] = LidGroups(sim)['H00008'][0].unit_area
lid_area[10] = LidGroups(sim)['H00009'][0].unit_area
lid_area[11] = LidGroups(sim)['H00009'][1].unit_area
lid_area[12] = LidGroups(sim)['H00010'][0].unit_area
lid_area[13] = LidGroups(sim)['H00011'][0].unit_area
lid_area[14] = LidGroups(sim)['H00012'][0].unit_area
lid_area[15] = LidGroups(sim)['H00013'][0].unit_area
lid_area[16] = LidGroups(sim)['H00014'][0].unit_area
lid_area[17] = LidGroups(sim)['H00015'][0].unit_area
lid_area[18] = LidGroups(sim)['H00015'][1].unit_area
lid_area[19] = LidGroups(sim)['H00016'][0].unit_area
lid_area[20] = LidGroups(sim)['H00017'][0].unit_area
lid_area[21] = LidGroups(sim)['H00018'][0].unit_area
lid_area[22] = LidGroups(sim)['H00019'][0].unit_area
lid_area[23] = LidGroups(sim)['H00020'][0].unit_area
lid_area[24] = LidGroups(sim)['H00021'][0].unit_area
lid_area[25] = LidGroups(sim)['H00021'][1].unit_area
lid_area[26] = LidGroups(sim)['H00022'][0].unit_area
lid_area[27] = LidGroups(sim)['H00023'][0].unit_area
lid_area[28] = LidGroups(sim)['H00024'][0].unit_area
lid_area[29] = LidGroups(sim)['H00025'][0].unit_area
lid_area[30] = LidGroups(sim)['H00026'][0].unit_area
lid_area[31] = LidGroups(sim)['H00027'][0].unit_area
lid_area[32] = LidGroups(sim)['H00029'][0].unit_area
lid_area[33] = LidGroups(sim)['H00029'][1].unit_area
lid_area[34] = LidGroups(sim)['H00031'][0].unit_area
lid_area[35] = LidGroups(sim)['H00032'][0].unit_area
lid_area[36] = LidGroups(sim)['H00032'][1].unit_area
lid_area[37] = LidGroups(sim)['H00034'][0].unit_area
lid_area[38] = LidGroups(sim)['H00035'][0].unit_area
lid_area[39] = LidGroups(sim)['H00036'][0].unit_area
lid_area[40] = LidGroups(sim)['H00036'][1].unit_area
lid_area[41] = LidGroups(sim)['H00037'][0].unit_area
lid_area[42] = LidGroups(sim)['H00038'][0].unit_area
lid_area[43] = LidGroups(sim)['H00038'][1].unit_area
lid_area[44] = LidGroups(sim)['H00039'][0].unit_area
lid_area[45] = LidGroups(sim)['H00041'][0].unit_area
lid_area[46] = LidGroups(sim)['H00044'][0].unit_area
lid_area[47] = LidGroups(sim)['H00046'][0].unit_area
lid_area[48] = LidGroups(sim)['H00047'][0].unit_area
lid_area[49] = LidGroups(sim)['H00047'][1].unit_area
lid_area[50] = LidGroups(sim)['H00048'][0].unit_area
lid_area[51] = LidGroups(sim)['H00048'][1].unit_area
lid_area[52] = LidGroups(sim)['H00049'][0].unit_area
lid_area[53] = LidGroups(sim)['H00051'][0].unit_area
lid_area[54] = LidGroups(sim)['H00052'][0].unit_area
lid_area[55] = LidGroups(sim)['H00053'][0].unit_area
lid_area[56] = LidGroups(sim)['H00053'][1].unit_area
lid_area[57] = LidGroups(sim)['H00054'][0].unit_area
lid_area[58] = LidGroups(sim)['H00054'][1].unit_area
lid_area[59] = LidGroups(sim)['H00055'][0].unit_area
lid_area[60] = LidGroups(sim)['H00056'][0].unit_area
# 下面是优化函数1的计算 需要各类型LID的面积分别求和
a_lswd = lid_area[1] + lid_area[3] + lid_area[5] + lid_area[6] + lid_area[7] \
+ lid_area[10] + lid_area[12] + lid_area[13] + lid_area[14] + lid_area[17] \
+ lid_area[19] + lid_area[20] + lid_area[21] + lid_area[24] + lid_area[26] \
+ lid_area[27] + lid_area[28] + lid_area[32] + lid_area[34] + lid_area[39] \
+ lid_area[42] + lid_area[46] + lid_area[47] + lid_area[48] + lid_area[50] \
+ lid_area[52] + lid_area[53] + lid_area[54] + lid_area[55] + lid_area[57] \
+ lid_area[59] + lid_area[60]
b_xcsld = lid_area[0] + lid_area[2] + lid_area[11] + lid_area[18] + lid_area[25] \
+ lid_area[33] + lid_area[35] + lid_area[37] + lid_area[38] + lid_area[40] \
+ lid_area[41] + lid_area[43] + lid_area[44] + lid_area[45]
d_tslm = lid_area[4] + lid_area[8] + lid_area[9] + lid_area[15] + lid_area[16] \
+ lid_area[22] + lid_area[23] + lid_area[29] + lid_area[30] + lid_area[31] \
+ lid_area[36] + lid_area[49] + lid_area[51] + lid_area[56] + lid_area[58]
# max R 径流量
# 目前的径流量runoff只在subcatchment的statistic函数里保存 需要单独提取出来 单位不一致 需要单独换算
# 详见https://github.com/OpenWaterAnalytics/pyswmm/discussions/416 开发团队已表示pyswmm2将会认真考虑该问题
subcatchment_runoff = np.array(np.zeros(57))
for i in range(10):
subcatchment_runoff[i] = Subcatchments(sim)["H0000" + str(i)].statistics['runoff'] / Subcatchments(sim)[
"H0000" + str(i)].area / 10
for i in range(10, 57):
subcatchment_runoff[i] = Subcatchments(sim)["H000" + str(i)].statistics['runoff'] / Subcatchments(sim)[
"H000" + str(i)].area / 10
R = 0
# global Pre_runoff
# for i in range(57):
# R = R + (subcatchment_runoff[i] - Pre_runoff[i]) / Pre_runoff[i]
# Pre_runoff = subcatchment_runoff
for i in range(57):
R = R + subcatchment_runoff[i]
R = R / 1640 - 1
# min T 节点超载时间
# 节点超载时间surcharge_duration同样在node的statistic函数里保存 这些都在官网的文档里有描述函数用法
node_surcharged_duration = np.array(np.zeros(57))
for i in range(1, 10):
node_surcharged_duration[i - 1] = Nodes(sim)[str("J00" + str(i))].statistics['surcharge_duration']
for i in range(10, 58):
node_surcharged_duration[i - 1] = Nodes(sim)["J0" + str(i)].statistics['surcharge_duration']
T = np.sum(node_surcharged_duration) / 30
# 注意优化目标函数与约束都只能是min的形式 这里上面的R已经全部添加了负号进行计算
f1 = 221.64 * a_lswd + 110.78 * b_xcsld + 303.13 * d_tslm
f2 = R
f3 = T
# 约束 同样是min的形式
g1 = a_lswd - 5500
g2 = b_xcsld - 14600
g3 = d_tslm - 3800
g4 = R
# 将优化目标函数与约束分别赋值给F、G
out["F"] = [f1, f2, f3]
out["G"] = [g1, g2, g3, g4]
# 更新 养成好习惯 关闭仿真
sim.close()
#如需单步内仿真多个inp,则需多次使用sim和sim.close()
# 照搬pymoo即可
problem = MyProblem()
algorithm = NSGA2(pop_size=100) # 种群大小100
res = minimize(problem,
algorithm,
("n_gen", 500), # 迭代500代
verbose=True, # true则在终端显示每代部分参数
# save_history=True,
seed=1) # 这里并未改动具体的变异率等,详细参数可以转到NSGA2的类型声明查看
# val = [e.opt.get("F")[0] for e in res.history]
# import matplotlib.pyplot as plt
# plt.plot(np.arange(len(val)), val)
# plt.show()
print(res.exec_time) # 打印耗时
np.savetxt(r'C:\Users\13618\Desktop\design.txt', res.X) # 保存最后pop_size大小的结果 分别是design spaces values 即自变量的值
np.savetxt(r'C:\Users\13618\Desktop\objective.txt', res.F) # objective spaces values 即优化目标函数的值
np.savetxt(r'C:\Users\13618\Desktop\constraint.txt', res.G) # constraint values 即约束的值
# 用三维散点图展示结果
plot = Scatter()
plot.add(res.F, edgecolor="red", facecolor="none")
plot.show()
对编程能力提升倒是不大,主要还是解决问题的思维锻炼,很多问题并没有现成的途径直接解决,去官网仔细阅读函数说明和examples是非常有帮助的。另外pyswmm对比matswmm真是好用极了,确实还得找仍在更新维护的工具才顺手,原开发团队很快也会发布pyswmm2,应该上手更方便些。
如果这篇文章能帮助你,感谢你的点赞收藏支持,欢迎该方面问题的任何交流。