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

如何用Scipy.minimise求解元素仅为-1或1的最优整数数组

问题解答

能否直接使用scipy.minimize()实现?

不能。scipy.minimize()内置的主流求解器(如SLSQP、L-BFGS-B、BFGS等)均面向连续变量优化场景设计,无法原生支持变量仅取-1、1的离散约束,直接调用会得到连续域的浮点解,不符合你的需求。

可行实现方案

下面提供两种适配不同场景的实现方案:

方案1:暴力枚举(适用于x长度≤20的场景)

你的示例中x长度仅为5,总共有2^5=32种可能的取值组合,暴力遍历所有情况既快又能保证得到全局最优解,是当前场景的最优选择。
代码示例:

import random
import itertools

data = random.sample(range(1, 100), 5)

def f(x, data):
    prod = [a * b for a, b in zip(data, x)]
    return abs(sum(prod))

# 生成所有可能的x组合(元素仅为-1或1)
all_x = itertools.product([-1, 1], repeat=len(data))
# 遍历找最优解
min_f = float('inf')
best_x = None
for x in all_x:
    current_f = f(x, data)
    if current_f < min_f:
        min_f = current_f
        best_x = x
        # 最优可能为0,找到即可提前退出
        if min_f == 0:
            break

print(f"最优x:{best_x}")
print(f"最小f(x):{min_f}")

方案2:启发式全局优化(适用于x长度较大的场景)

如果x长度超过20,暴力枚举算力不足,可以用scipy.optimize.differential_evolution(差分进化算法)实现,它支持整数约束,我们可以通过变量转换满足-1/1的取值要求:
令中间变量y为仅取0、1的整数变量,那么x = 2*y -1自然仅能取-1、1,无需额外约束。
代码示例:

import random
from scipy.optimize import differential_evolution

data = random.sample(range(1, 100), 5)
n = len(data)

def f(y, data):
    x = 2 * y - 1 # 转换为-1/1的x
    prod = [a * b for a, b in zip(data, x)]
    return abs(sum(prod))

# 每个y的取值边界是0到1,且为整数
bounds = [(0, 1)] * n
# integrality参数标记所有变量为整数类型
res = differential_evolution(f, bounds, args=(data,), integrality=[True]*n, seed=42)

best_y = res.x
best_x = 2 * best_y - 1
min_f = res.fun

print(f"最优x:{best_x}")
print(f"最小f(x):{min_f}")

注意:差分进化是启发式算法,不保证100%得到全局最优解,可通过调整popsize、maxiter等参数提升求解效果。

其他可选方案

如果x长度很大且对最优性要求高,可以使用专门的整数规划求解库(如PuLP、OR-Tools)建模求解0-1整数规划问题,精度和效率会优于通用启发式算法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:45:03