Python 线性规划,将输入限制为零或范围

问题描述

在线性程序中,我最小化加权输入向量和目标向量之间的距离。我使用 Scipyto 计算我需要的权重值。目前它们介于 0 和 1 之间,但如果它们小于 .2,我希望它们为零,例如,x_i 应该是 0 或 [.2; 1]。我被指出混合整数线性规划,但我仍然找不到解决我的问题的任何方法。我该如何解决这个问题?

tldr:我想使用 (0,0) 或 (.3,1) 作为每个 x 的边界,我该如何实现?

这是我的 SciPy 代码

    # minimize the distance between weighted input vectors and a target vector
def milp_objective_function(weights):
    scaled_matrix = input_matrix * weights[:,np.newaxis] # scale input_matrix columns by weights
    sum_vector = sum(scaled_matrix) # sum weighted_input_matrix columns
    difference_vector = sum_vector - target_vector
    return np.sqrt(difference_vector.dot(difference_vector)) # return the distance between the sum_vector and the target_vector

# sum of weights should equal 100%
def milp_constraint(weights):
    return sum(weights) - 1

def main():
    # bounds should be 0 or [.2; 1] -> mixed integer linear programming?
    weight_bounds = tuple([(0,1) for i in input_matrix])
    # random guess,will implement later
    initial_guess = milp_guess_weights()
    
    constraint_obj = {'type': 'eq','fun': milp_constraint}
    result = minimize(milp_objective_function,x0=initial_guess,bounds=weight_bounds,constraints=constraint_obj)

解决方法

位于 {0} ∪ [L,U] 中的变量称为半连续变量。高级 MIP 求解器内置支持这些类型的变量。

请注意,SciPy 根本没有 MIP 求解器。

我还想指出,如果您的 MIP 求解器不支持半连续变量,您可以使用二进制变量对其进行模拟:

 L ⋅ δ(i) ≤ x(i) ≤ U ⋅ δ(i) 
 δ(i) ∈ {0,1}