在市政给水管网当中,管网平差的目的是在已知节点流量、管段长度的情况下,求得各管段流量和对应的经济管径。本科生学习阶段了解并掌握管网平差原理及方法是必不可少的环节。

在下面的程序当中,将利用哈代克罗斯法求得管段流量。

程序分为三个.py文件:

init_input.py主要是用来输入管网节点编号列表、节点流量列表、管段列表(两端节点列表表示)、管段长度列表。所有的元素应当在列表的对应位置。第一个节点流量为负,表示水厂输入水至管网当中。管段列表当中应当是小节点编号在前,大节点编号在后。

pingcha.py主要是用来对init_input.py文件中的数据进行处理,通过numpy当中的np.linalg.lstsq得出初始流量,准备在back_cal.py当中进行哈代克罗斯法迭代求解管段流量。另外在文件中用算法求出所有环路。算法的原理近乎暴力。首先遍历搜索出所有始、终两点的路径。再判断始、终两点是否直接连接,若是,则成环保留,反之舍去路径。

back_cal.py主要用来哈代克罗斯法迭代,输出结果,并计算程序运行时间。

运用此程序,应先在init_input.py仿照格式填写出管网特征,保存。之后可双击运行back_cal.py,也可在python自带的IDLE下运行。

值得注意的是当有deadlink时,应把支状部分简化到最近的环路节点上。

init_input.py

 '''
dot_set = [0, 1, 2, 3, 4]
dot_set_quantity = [-100, 10, 20, 50, 20]
path_set = [[0, 1],
[0, 2],
[1, 3],
[2, 3],
[2, 4],
[3, 4]]
diameter_set = [200, 200, 200, 200, 200, 200]#管径列表
length_set = [300, 300, 300, 300, 300, 300]#管长列表
#生成图
graph = {}
for k in dot_set:
graph[k] = []
print(graph)
for k, v in path_set:
graph[k].append(v)
graph[v].append(k)
print(graph)
''' dot_set = [i for i in range(13)]
dot_set_quantity = [-440,
50, 40, 50, 30, 20,
30, 25, 50, 25, 50,
30, 40]
path_set = [[0, 11],
[0, 12],
[1,2],
[1,4],
[2,3], [2,8],
[3,11],
[4,5],
[4,7],
[5,6], [5,9],
[6,10],
[7,8],
[7,9],
[8,11], [8,12],
[9,10],
[10,12]
]
diameter_set = [250 for i in range(18)]#管径列表
length_set = [400, 200, 400, 200, 200,
200, 200, 200, 200, 200,
200, 200, 200, 200, 200,
400, 200, 200]#管长列表
#生成图
graph = {}
for k in dot_set:
graph[k] = []
#print(graph)
for k, v in path_set:
graph[k].append(v)
graph[v].append(k)
#print(graph)

pingcha.py

 import numpy as np
import init_input class dot(object):
def __init__(self, number, quantity_of_flow):
self.n = number
self.q = quantity_of_flow
class path(object):
def __init__(self, number, start, finish, quantity_of_flow, diameter, length):
self.n = number
self.s = start
self.f = finish
self.q = quantity_of_flow
self.d = diameter
self.l = length
class net(object):
def __init__(self, dot_set, path_set):
self.dote_set = dot_set
self.path_set = path_set '''管网模型参数'''
dot_set = init_input.dot_set
dot_set_quantity = init_input.dot_set_quantity
path_set = init_input.path_set
diameter_set = init_input.diameter_set
length_set = init_input.length_set
graph = init_input.graph '''创建节点类'''
dot_list = [] # dot类列表
for i in range(len(dot_set)):
dot(i, dot_set_quantity[i]).n = i
dot(i, dot_set_quantity[i]).q = dot_set_quantity[i]
#print(dot(i, dot_set_quantity[i]).n, dot(i, dot_set_quantity[i]).q)
D = dot(i, dot_set_quantity[i])
dot_list.append(D)
#print(D) '''创建管道类,初始流量为0'''
path_list = [] # path类列表
for i in range(len(path_set)):
path(i, path_set[i][0], path_set[i][1], 0, diameter_set[i], length_set[i]).s = path_set[i][0]
path(i, path_set[i][0], path_set[i][1], 0, diameter_set[i], length_set[i]).f = path_set[i][1]
#print(i, path_set[i][0], path_set[i][1], 0)
L = dot(i, path(i, path_set[i][0], path_set[i][1], 0, diameter_set[i], length_set[i]))
path_list.append(L)
A = np.zeros((len(dot_set), len(dot_set))) # A是节点连接矩阵
for i in path_set:
A[i[0]][i[1]] = 1
A[i[1]][i[0]] = 1
#print(A) #****************************************************************************
# 假设某些管段流量,再求初始管段流量
v = len(dot_set)
e = len(path_set)
r = 2 + e - v
#print(v, e, r)
C = np.zeros((v, e))
for i in range(len(path_set)):
m = 1
for j in path_set[i]:
C[j][i] = m
m = -1
#print(C)
#解方程,得出一组初始流量
init_q, useless1, u2, u3 = np.linalg.lstsq(C, dot_set_quantity, rcond=0)
#print(init_q) # 搜索所有环算法***************************************************************
# 找到所有从start到end的路径
def findAllPath(graph, start, end, path=[]):
path = path + [start]
if start == end:
return [path] paths = [] # 存储所有路径
for node in graph[start]:
if node not in path:
newpaths = findAllPath(graph, node, end, path)
for newpath in newpaths:
paths.append(newpath)
return paths allpath_list = []
for i in range(len(dot_set)):
for j in range(i + 1, len(dot_set)):
if A[i][j] == 1:
allpath = findAllPath(graph, i, j)
allpath_list.append(allpath) i = True
while i == True:
if len(allpath_list) != 1:
allpath_list[0].extend(allpath_list[1])
del allpath_list[1]
else:
i = False
allpath_list = allpath_list[0] for i in range(len(allpath_list) - 1):
if len(allpath_list[i]) == 2:
allpath_list[i] = []
continue
for j in range(i + 1, len(allpath_list)):
if sorted(allpath_list[i]) == sorted(allpath_list[j]):
allpath_list[j] = [] if len(allpath_list[-1]) == 2:
allpath_list[-1] = []
m = 0
for i in allpath_list:
if i == []:
m += 1
for i in range(m):
allpath_list.remove([])
#print(allpath_list)

back_cal.py

 import time
time_1 = time.process_time() import numpy as np
import pingcha
A = pingcha.C
#print(A)
q = pingcha.init_q
print('初始流量:\n',q)
Q = pingcha.dot_set_quantity
#print(Q)
#allpath_list = [[0, 2, 3, 1], [0, 2, 4, 3, 1], [2, 4, 3]]
allpath_list = pingcha.allpath_list
#allpath_list点转换成线编号,存入pathlist_p,用管段标号表示环路
pathlist_p = []
for i in allpath_list:
l = []
for j in range(len(i)):
a = [i[j-1], i[j]]
for n in range(len(pingcha.path_set)):
if a[1]==pingcha.path_set[n][0] and a[0]==pingcha.path_set[n][1]:
l.append(n)
break
elif a[0]==pingcha.path_set[n][0] and a[1]==pingcha.path_set[n][1]:
l.append(-n)
else:
None
pathlist_p.append(l)
#print(pathlist_p)#挑选出的闭合环路 l = [[0 for i in range(len(pingcha.path_set))] for j in range(len(pathlist_p))]
for i in range(len(pathlist_p)):
for j in pathlist_p[i]:
if j >= 0:
l[i][j] = 1
else:
l[i][-j] = -1
L = np.array(l)
#print(L)
s = [64*pingcha.length_set[i]/(3.1415926**2*100**2*pingcha.diameter_set[i]) for i in range(len(q))]
h = [s[i]*(q[i]**2) for i in range(len(q))]
#print('h:', h) x = 0
t = 1#闭合环路的水头误差,当所有环路小于0.01m,即完成平差
while t > 0.01:
x+=1
closure_error_list = []#各环的闭合差组成的列表
for a in pathlist_p:
closure_error = 0#a环的闭合差
sum_sq = 0#环路sq之和
for b in a:
sum_sq += s[abs(b)]*abs(q[abs(b)])
if b >= 0:#可能会有bug,0号管没法判定方向
closure_error += h[abs(b)]
else:
closure_error -= h[abs(b)]
closure_error_list.append(closure_error)
rivision_q = closure_error/(2*sum_sq)#校正流量
for b in a:
if (b>=0 and q[abs(b)]>0) or\
(b<0 and q[abs(b)]<0):
q[abs(b)] -= rivision_q
elif (b<0 and q[abs(b)]>0) or\
(b>=0 and q[abs(b)]<0):
q[abs(b)] += rivision_q #根据经济流速选管径
t1 = 0
while True:
t1 += 1
if t1 == 4:
break
v = abs((q[abs(b)]*1000))/(3.1415926*(pingcha.diameter_set[abs(b)]/2)**2)#流速
if v<0.6:
if pingcha.diameter_set[abs(b)] <= 100:
break
else:
pingcha.diameter_set[abs(b)] -= 50
elif v>0.9:
if pingcha.diameter_set[abs(b)] >= 400:
break
else:
pingcha.diameter_set[abs(b)] += 50
else:
#print(pingcha.diameter_set[abs(b)])
#print(v)
break
#print(pingcha.diameter_set[abs(b)])
#print(v) #print(rivision_q)
h = [s[i]*(q[i]**2) for i in range(len(q))]
t = max([abs(i) for i in closure_error_list])
print('第', x,'次平差')
#print('h:', h)
print('管段流量:\n', q)
print('管径:', [i for i in pingcha.diameter_set])
#print('closure_error_list:', closure_error_list)
print('环路最大水头闭合差:', t) time_2 = time.process_time()
print('耗时:',time_2-time_1)

管网平差的python程序的更多相关文章

  1. 运行python程序

    1 在windows下运行python程序 1)从DOS命令行运行python脚本 用python解释器来执行python脚本,在windows下面python解释器是python.exe,我的pyt ...

  2. 【python之路2】CMD中执行python程序中文显示乱码

    在IDLE中执行下面代码,中文显示正常: # -*- coding:utf-8 -*- st=raw_input("请输入内容")print st 但在CMD中执行e:\hello ...

  3. Python程序高效地调试

    现在我在debug python程序就只是简单在有可能错误的地方print出来看一下,不知道python有没像c++的一些IDE一样有单步调试这类的工具?或者说各位python大神一般是怎么debug ...

  4. python学习笔记-python程序运行

    小白初学python,写下自己的一些想法.大神请忽略. 安装python编辑器,并配置环境(见http://www.cnblogs.com/lynn-li/p/5885001.html中 python ...

  5. python程序一直在后台运行的解决办法

    刚写了个python程序,要一直在后台运行,即使断开ssh进程也在,下面是解决办法: 假如Python程序为test.py 编写shell脚本start.sh #!/bin/bash python t ...

  6. 第一个python程序

    一个python程序的两种执行方式: 1.第一种方式是通过python解释器: cmd->python->进入python解释器->编写python代码->回车. 2.第二种方 ...

  7. Python程序的首行

    >问题 >>在一些python程序中的首行往往能够看见下面这两行语句中的一句 >>>#!/usr/bin/Python >>>#!/usr/bin ...

  8. Python程序员的进化史

    各种程序员所写的阶乘算法代码 # -*- coding: utf-8 -*- #新手程序员(递归) def factorial(x): if x == 0: return 1 else: return ...

  9. Python程序的常见错误(收集篇)

    关于Python Python是一门解释性的,面向对象的,并具有动态语义的高级编程语言.它高级的内置数据结构,结合其动态类型和动态绑定的特性,使得它在快速应用程序开发(Rapid Applicatio ...

随机推荐

  1. UiPath之获取邮件相关信息

    大家好,小U又来给大家分享UiPath文章,争取每一篇文章都给大家带来满满的干货. 本次案例是告诉大家如何使用GetOutLookMailMessage这个Activity, 案例的目的是将某个特定人 ...

  2. .Net Core 3.0 使用 Serilog 把日志记录到 SqlServer

    Serilog简介 Serilog是.net中的诊断日志库,可以在所有的.net平台上面运行.Serilog支持结构化日志记录,对复杂.分布式.异步应用程序的支持非常出色.Serilog可以通过插件的 ...

  3. [从今天开始修炼数据结构]串、KMP模式匹配算法

    [从今天开始修炼数据结构]基本概念 [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList [从今天开始修炼数据结构]栈.斐波那契数列.逆波兰四则运 ...

  4. ansible roles 介绍和使用

    目录 roles roles 介绍 创建role的步骤 role内个目录中可用的文件 案例 roles roles 介绍 ansible 自1.2版本引入的新特性,用于层次性.结构化地组织playbo ...

  5. Solr搜索引擎【索引管理】

    一.索引存储 当文档提交到索引之后,directory目录组件会将它们写入到持久化存储器.Solr的目录组件具有以下重要特点: 1.隐藏持久存储的读写细节,例如,将文档写入到磁盘或通过JDBC在数据库 ...

  6. pyecharts实现星巴克门店分布可视化分析

    项目介绍 使用pyecharts对星巴克门店分布进行可视化分析: 全球门店分布/拥有星巴克门店最多的10个国家或地区: 拥有星巴克门店最多的10个城市: 门店所有权占比: 中国地区门店分布热点图. 数 ...

  7. 使用PDO连接数据库

    PDO(PHP数据对象) 是一个轻量级的.具有兼容接口的PHP数据连接拓展,是一个PHP官方的PECL库,随PHP 5.1发布,需要PHP 5的面向对象支持,因而在更早的版本上无法使用.它所提供的数据 ...

  8. Python如何爬取实时变化的WebSocket数据【华为云技术分享】

    一.前言 作为一名爬虫工程师,在工作中常常会遇到爬取实时数据的需求,比如体育赛事实时数据.股市实时数据或币圈实时变化的数据.如下图: Web 领域中,用于实现数据'实时'更新的手段有轮询和 WebSo ...

  9. 【nodejs原理&源码赏析(2)】KOA中间件的基本运作原理

    [摘要] KOA中间件的基本运作原理 示例代码托管在:http://www.github.com/dashnowords/blogs 在中间件系统的实现上,KOA中间件通过async/await来在不 ...

  10. Python-TCP客户端程序开发

    TCP客户端,需要与服务端建立连接,连接建立成功后才可以进行数据的传输. # 1.导入模块 import socket if __name__ == '__main__': # 2.创建套接字对象 t ...