Minimizing of function that has a list of tuples as arguments

40 Views Asked by At

I need to minimize a function objective() that takes a list of tuples x as argument. But there's a catch : the tuples can only be choosen in a predefined set of tuples.

A minimal example would be:

import numpy as np
from scipy.optimize import minimize

initial_guess = [(2.,0.6), (0.9,8.1)]
possible_values = [(0.,0.), (1.7,2.2), (10.,1.2), (0.,0.15), (4.1,6.2)]

def objective(x:list):
    return np.sum([item[0]**2 + item[1]**2 for item in x])

# Need to add a constraint to select elements of x in elements of possible_values

# Minimize objective function
result = minimize(fun = objective,
                  x0 = initial_guess)

print(result.x)

This code procudes the following error:

ValueError: 'x0' must only have one dimension.

Thanks

2

There are 2 best solutions below

0
it's jayway On

You can keep just the tuples in x that are present in possible_values:

def objective(x: list):
    x = [t for t in x if t in possible_values]
    return np.sum([item[0]**2 + item[1]**2 for item in x])

0
joni On

If you're aiming to find the tuple that yields the smallest vector norm, using scipy.optimize.minimize is not the best fit. To tackle this type of problem effectively, it's essential to work with binary decision variables. This transforms your task into a mixed-integer programming problem, where opting for milp is the way to go:

import numpy as np
from scipy.optimize import milp, LinearConstraint, Bounds

possible_values = [(0.,0.), (1.7,2.2), (10.,1.2), (0.,0.15), (4.1,6.2)]

c = np.array([v[0]**2 + v[1]**2 for v in possible_values])

A_eq = np.ones((1, len(possible_values)))
b_eq = np.array([1])
constraints = LinearConstraint(A=A_eq, lb=b_eq, ub=b_eq)
bounds = Bounds(lb=np.zeros(len(possible_values)), ub=np.ones(len(possible_values)))
integrality = np.ones(len(possible_values))

res = milp(c, integrality=integrality, constraints=constraints, bounds=bounds)