如何修复Matplotlib中线性规划可行域的填充错误?
线性规划可行域Matplotlib填充问题解决方法
问题背景
需要用Matplotlib填充线性规划的可行域,约束不等式对应的曲线计算代码如下:
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2000, 1000) y1 = (3600 - 3*x) / 5 y2 = (1600 - x) / 2 y3 = (48000 - 50*x) / 20
当前填充代码无法正确渲染可行域:
fig, ax = plt.subplots() ax.plot(x, y1, label='3x+5y<=3600') ax.plot(x, y2, label='x+2y<=1600') ax.plot(x, y3, label='50x+20y<=48000') ax.fill_between(x, 0, y3, where=(y1<= (3600-3*x)/5) & (y2<= (1600-x)/2) & (y3<= (48000-50*x)/20), alpha=0.2) # plot the vertices for vertex in vertices: ax.plot(vertex[0], vertex[1], 'ro') plt.xlim(xmin=0) plt.ylim(ymin=0) plt.xlabel('x') plt.ylabel('y') plt.title('Feasible Region') plt.legend() plt.show()
错误原因分析
- where条件无效:
y1 = (3600-3*x)/5,所以y1 <= (3600-3*x)/5是恒成立的等式,同理y2、y3的条件也都是恒真,等于没有添加任何约束筛选。 - 填充上限错误:可行域是所有约束曲线的下方区域,即每个x对应的y需要同时小于等于y1、y2、y3,而不是固定以y3为上限。
- 未处理负y值:当x超过约束的临界值后,y1/y2/y3会出现负数,这部分不符合
y>=0的约束,需要排除。
修正方案
计算每个x位置上,三个约束曲线的最小y值(同时确保y≥0),以此作为填充的上限,直接填充0到该最小值的区域即可:
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 2000, 1000) y1 = (3600 - 3*x) / 5 y2 = (1600 - x) / 2 y3 = (48000 - 50*x) / 20 # 计算每个x对应的可行y上限:取三个约束的最小值,且不小于0 y_upper = np.min([y1, y2, y3], axis=0) y_upper = np.maximum(y_upper, 0) # 确保y不小于0 fig, ax = plt.subplots() ax.plot(x, y1, label='3x+5y<=3600') ax.plot(x, y2, label='x+2y<=1600') ax.plot(x, y3, label='50x+20y<=48000') # 填充可行域:从y=0到y_upper,x范围默认是整个x数组(但y_upper已处理负数值) ax.fill_between(x, 0, y_upper, alpha=0.2) # 绘制顶点(假设vertices是已计算好的可行域顶点列表) if 'vertices' in locals(): for vertex in vertices: ax.plot(vertex[0], vertex[1], 'ro') plt.xlim(xmin=0) plt.ylim(ymin=0) plt.xlabel('x') plt.ylabel('y') plt.title('Feasible Region') plt.legend() plt.show()
关键修改点
- 用
np.min([y1,y2,y3], axis=0)获取每个x对应的最小约束y值,保证同时满足所有y<=约束的条件。 - 用
np.maximum(y_upper, 0)过滤掉y为负的部分,符合y≥0的约束。 - 去掉无效的where条件,直接基于计算好的y_upper填充,逻辑更清晰且准确。
内容的提问来源于stack exchange,提问作者Arwa
相关产品推荐
相关产品推荐

