110 lines
2.5 KiB
Python
110 lines
2.5 KiB
Python
import wntr
|
|
import pandas as pd
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
import sklearn.cluster
|
|
import os
|
|
|
|
|
|
|
|
class QD_KMeans(object):
|
|
def __init__(self, wn, num_monitors):
|
|
# self.inp = inp
|
|
self.cluster_num = num_monitors # 聚类中心个数,也即测压点个数
|
|
self.wn=wn
|
|
self.monitor_nodes = []
|
|
self.coords = []
|
|
self.junction_nodes = {} # Added missing initialization
|
|
|
|
|
|
def get_junctions_coordinates(self):
|
|
|
|
for junction_name in self.wn.junction_name_list:
|
|
junction = self.wn.get_node(junction_name)
|
|
self.junction_nodes[junction_name] = junction.coordinates
|
|
self.coords.append(junction.coordinates )
|
|
|
|
# print(f"Total junctions: {self.junction_coordinates}")
|
|
|
|
def select_monitoring_points(self):
|
|
if not self.coords: # Add check if coordinates are collected
|
|
self.get_junctions_coordinates()
|
|
coords = np.array(self.coords)
|
|
coords_normalized = (coords - coords.min(axis=0)) / (coords.max(axis=0) - coords.min(axis=0))
|
|
kmeans = sklearn.cluster.KMeans(n_clusters= self.cluster_num, random_state=42)
|
|
kmeans.fit(coords_normalized)
|
|
|
|
for center in kmeans.cluster_centers_:
|
|
distances = np.sum((coords_normalized - center) ** 2, axis=1)
|
|
nearest_node = self.wn.junction_name_list[np.argmin(distances)]
|
|
self.monitor_nodes.append(nearest_node)
|
|
|
|
return self.monitor_nodes
|
|
|
|
|
|
def visualize_network(self):
|
|
"""Visualize network with monitoring points"""
|
|
ax=wntr.graphics.plot_network(self.wn,
|
|
node_attribute=self.monitor_nodes,
|
|
node_size=30,
|
|
title='Optimal sensor')
|
|
plt.show()
|
|
|
|
|
|
|
|
|
|
def kmeans_sensor_placement(name: str, sensor_num: int, min_diameter: int) -> list:
|
|
inp_name = f'./db_inp/{name}.db.inp'
|
|
wn= wntr.network.WaterNetworkModel(inp_name)
|
|
wn_cluster=QD_KMeans(wn, sensor_num)
|
|
|
|
# Select monitoring pointse
|
|
sensor_ids= wn_cluster.select_monitoring_points()
|
|
|
|
# wn_cluster.visualize_network()
|
|
|
|
return sensor_ids
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
#sensorindex = get_ID(name='suzhouhe_2024_cloud_0817', sensor_num=30, min_diameter=500)
|
|
sensorindex = kmeans_sensor_placement(name='szh', sensor_num=50, min_diameter=300)
|
|
print(sensorindex)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|