我有4个不同的发电站。每个电站都有其相应的效率函数。如果我需要生产特定数量的总功率,每个发电站将有一个(或几个)生产量配置,这将导致最大可能的总效率。我想找出每个发电站的具体生产值,这些值将导致这个最大的总效率。我在代码中指定了我的总功率需求。
在我的代码中,我已经指定了每个发电站的生产量和相应的效率值。我正在使用scipy.optimize模块中的“minimize”函数。
代码返回的答案乍看起来可能合理,但不一定是最优的解决方案。例如,发电站“East”在P = 28.52时的最大效率为86.34%。因此,如果我将total_effect设置为28.52,则最佳解决方案将是仅以28.52 MW运行发电站East,并将所有其他发电站设置为0。这不是我得到的结果。
我应该如何更改我的代码?有什么明显的错误吗?我还应该使用其他模块或函数吗?
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
# Defining arrays for effevt (P) and efficiency (eta) for each power plant
P_North = np.array([0.11, 0.23, 0.45, 0.75, 1.11, 1.45, 1.75, 2.01, 2.17, 2.30, 2.27])
eta_North = np.array([4.584, 18.362, 32.330, 50.288, 64.760, 74.638, 80.022, 83.494, 84.771, 85.635, 84.254])
P_West = np.array([3.63, 4.59, 5.51, 6.50, 7.35, 8.35, 8.94])
eta_West = np.array([82.717, 83.711, 84.341, 84.629, 83.793, 82.765, 80.756])
P_South = np.array([4.541, 9.181, 13.771, 18.561, 22.971, 27.851, 31.821])
eta_South = np.array([80.3471, 83.1261, 84.3591, 85.4051, 85.6741, 85.6191, 84.4601])
P_East = np.array([18.00, 20.00, 25.00, 32.00, 35.00, 36.00])
eta_East = np.array([81.360, 83.253, 85.589, 85.642, 85.624, 82.931])
tot_names = ["North", "West", "South", "East"]
P_tot = [P_North, P_West, P_South, P_East]
eta_tot = [eta_North, eta_West, eta_South, eta_East]
# Constructing polynomial functions of the efficiency
coefficient = [np.polyfit(P[0:], eta[0:], 2) for P, eta in zip(P_tot, eta_tot)]
polynomal = [np.poly1d(coefficient) for coefficient in coefficient]
min_cost = float('inf')
best_solution = None
total_effect = float(input("How much effect shall be produced this hour?: ")) # MWh
initial_distribution = total_effect / 4
# Defining "neg_function" which is reversly propotional with the sum of all the efficiencies. Goal: maximize total efficiency by minimizing the negative sum of the efficiencies
def neg_function(x):
efficiencies = [x[i] * polynomal[i](x[i]) for i in range(4)]
return - sum(efficiencies) / total_effect
constraints = [{'type': 'eq', 'fun': lambda x: sum(x) - total_effect}]
bounds = [(0, max(P)) for P in P_tot]
x0 = np.array([min(initial_distribution, max(P)) for P in P_tot])
# No idea if it's necessary to use the SLSQP here. Have tried several different methods
solution = minimize(neg_function, x0, method='SLSQP', constraints=constraints, bounds=bounds)
if solution.fun < min_cost:
min_cost = solution.fun
best_solution = solution
# Print the optimal power outputs for each station
for i in range(len(tot_names)):
print(f"Optimal effect for {tot_names[i]}: {round(best_solution.x[i], 2)} MW")
# Plotting efficiency curves
P_poly = [np.arange(P[0], P[-1]+0.001, 0.001) for P in P_tot]
eta_poly= [polynomal(P_poly) for P_poly, polynomal in zip(P_poly, polynomal)]
fig = plt.figure(figsize=(13, 6))
gs = gridspec.GridSpec(3, 4)
axes = [
fig.add_subplot(gs[0, 0]),
fig.add_subplot(gs[0, 1]),
fig.add_subplot(gs[0, 2]),
fig.add_subplot(gs[0, 3]),
]
data = []
for i in range(len(P_tot)):
data1 = (P_tot[i], eta_tot[i], P_poly[i], eta_poly[i], tot_names[i])
data.append(data1)
for ax, (x, y, x_int, y_int, title) in zip(axes, data):
ax.plot(x, y, 'o', x_int, y_int, '-')
ax.set_title(title)
ax.set_xlabel('Effect [MW]')
ax.set_ylabel('Efficiency [%]')
# Vertical line at the optimal production level
index = tot_names.index(title)
ax.axvline(x=best_solution.x[index], color='b', linestyle='--')
plt.tight_layout()
plt.show()
字符串
2条答案
按热度按时间0qx6xfy61#
这里有一个稍微不同的方法,它使问题保持离散,并详尽地列举了可能的解决方案。这在该情况下是可行的,因为仅存在3234个组合。在这种方法中存在对于太稀疏的数据可能已经明显的不准确性,但是显然它不排除首先拟合多项式并且然后使用那些来插值并且然后使用更细粒度的数据来抑制这种不期望的效果的可能性。在这里,每个值数组的稀疏度降低了四倍,给出了946125个组合,但运行时间仍然很短。
字符串
插值:
型
优化:
型
示例用法:
型
印刷品
型
说明:
首先,针对四个方向中的每一个拟合2次多项式
f(P, eta)
。接下来,每对数组(P, eta)
通过将数组P
中的点的数量粗略地增加四倍(参见interp_factor
)(保持范围相同,除了一些buffer
)并应用获得的多项式来获得eta
的值。然后,函数
get_optimal_configuration
简单地遍历每个组合,并选择任何高于指定total_effect
(但不超过total_effect * max_relative_deviation
)的组合,其效率之和最高(相当于最小化减去效率之和与total_effect的比率),如果存在任何这样的组合。yc0p9oo02#
我不认为你做了足够的限制你的权力设置到有效的范围,在几个地方:在你的
input
中,以及在你的边界中。如果您没有任何接近0的低效应值的效率数据,那么0肯定不是有效的功效效应。我首先用上界和下界进行演示。
如果强制执行这些界限,那么/4的分布显然是无效的,因为这将超出某些电厂的范围。
功率和效率的实际值的交叉比垂直线更能提供信息,并且我不认为按发电机分隔子图有多大价值-它们可以在同一个图上,特别是如果您使用半对数。
个字符
x1c 0d1x的数据
发电站“East”在P = 28.52处具有86.34%的最大效率。因此,如果我将total_effect设置为28.52,则最优解决方案将是仅运行28.52MW的East发电站,并将所有其他发电站设置为
结果可能相同,但成本标准不同:考虑到手头的实际问题,最大化效率值之和可能没有用,因为它们没有相同的权重。相反,你应该 * 最小化 * 中的总功率,根据单个效率计算。将其应用于28.52 MW的数字,并将假设更改为接受0作为有效效应,解决方案看起来更像
的字符串
的
将您建议的解决方案与上面代码中的解决方案进行比较
型
我们得到
型
他们很亲密。这可以通过以下方式进一步调整
或者更好的方法是,分析计算最小值,因为(在边界内)你的成本函数是连续的和可微的。