You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Scipy中表示由集合并集构成的可行域?

处理Scipy中并集形式可行域的非线性优化问题

对于可行域为多个集合并集的优化问题,Scipy的minimize无法直接通过单一约束描述(默认约束为交集逻辑),最可靠的解决方式是拆分到每个子集单独求解,再比较结果取全局最优。

问题分析

你的可行域由三个子集组成:

  • 子集A:$x_0^2 + x_1^2 \leq 4$,且 $-2 \leq x_0 \leq 1$、$-2 \leq x_1 \leq 1$
  • 子集B:$-4 \leq x_0 \leq 0$,且 $0 \leq x_1 \leq 1$
  • 子集C:$0 \leq x_0 \leq 1$,且 $-4 \leq x_1 \leq 0$

原代码的约束函数逻辑错误,无法正确描述并集可行域,导致求解结果不符合预期。

修正后的实现方案

分别在三个子集上求解优化问题,最后对比三个结果的目标函数值,选择最小的解作为全局最优解:

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np
from scipy.optimize import NonlinearConstraint, Bounds, minimize

############ 绘图部分(保留原逻辑)############
def in_region(x):
    return (x[0]**2 + x[1]**2 <= 4 and -2 <= x[0] <= 1 and -2 <= x[1] <= 1) or \
           (-4 <= x[0] <= 0 and 0 <= x[1] <= 1) or \
           (-4 <= x[1] <= 0 and 0 <= x[0] <= 1)

X, Y = np.meshgrid(np.linspace(-4, 1, 500), np.linspace(-4, 1, 500))
Z = np.zeros_like(X)
for i in range(X.shape[0]):
    for j in range(X.shape[1]):
        Z[i,j] = in_region([X[i,j], Y[i,j]])

fig, ax = plt.subplots(figsize=(8,8))
ax.pcolormesh(X, Y, Z, cmap='binary')

rect1 = Rectangle((-2,-2), 3, 3, linewidth=1, edgecolor='r', facecolor='none')  # 修正矩形范围,覆盖x0到1、x1到1
ax.add_patch(rect1)
rect2 = Rectangle((-4,0), 4, 1, linewidth=1, edgecolor='r', facecolor='none')
ax.add_patch(rect2)
rect3 = Rectangle((0,-4), 1, 4, linewidth=1, edgecolor='r', facecolor='none')
ax.add_patch(rect3)

ax.set_xlim([-4, 1])
ax.set_ylim([-4, 1])
ax.set_xlabel('x[0]')
ax.set_ylabel('x[1]')
plt.show()

############ 求解部分(拆分到三个子集)############
# 目标函数
def objective(x):
    return x[0] + x[1]

# --- 子集A求解 ---
def constraint_A(x):
    return x[0]**2 + x[1]**2 - 4  # 约束:x0²+x1² ≤4 → 函数值 ≤0
bounds_A = Bounds([-2, -2], [1, 1])
cons_A = NonlinearConstraint(constraint_A, -np.inf, 0)
result_A = minimize(objective, [-2, -2], bounds=bounds_A, constraints=cons_A)

# --- 子集B求解 ---
bounds_B = Bounds([-4, 0], [0, 1])
result_B = minimize(objective, [-4, 1], bounds=bounds_B)

# --- 子集C求解 ---
bounds_C = Bounds([0, -4], [1, 0])
result_C = minimize(objective, [1, -4], bounds=bounds_C)

# 比较三个子集的最优解
results = [result_A, result_B, result_C]
min_idx = np.argmin([res.fun for res in results])
best_result = results[min_idx]

print("全局最优解:")
print(f"x1 = {best_result.x[0]:.4f}, x2 = {best_result.x[1]:.4f}")
print(f"最小目标函数值:{best_result.fun:.4f}")

关键说明

  1. 子集拆分逻辑:每个子集对应独立的约束/边界条件,确保每个求解过程的可行域是原并集中的一个子集。
  2. 初始点选择:为每个子集选择靠近潜在最优解的初始点(比如子集A选(-2,-2),子集B选(-4,1),子集C选(1,-4)),避免优化器陷入局部最优。
  3. 结果对比:直接对比三个子集的目标函数值,取最小对应的解作为全局最优。

内容的提问来源于stack exchange,提问作者Leelou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:08:10