I have a class that evaluates a result for a given input list of parameters. I would like to know the best set of parameters that minimises the result given by the class. Since the input must remain integer, I read that Pulp might be a solution compared to Scipy.minimize().
I tried to implement it, but the line prob += ... doesn't work. Here is a simplified version of the code that reproduces the problem I have. It seems that I don't understand something important about Pulp.
import pandas as pdimport pulp as plclass ComplexClass(): def __init__(self, path_data:str): # self.data = pd.read_csv(path_data) d = {'col1': [i for i in range(100)], 'col2': [i**2 for i in range(100)]} self.df = pd.DataFrame(data=d) def eval_value(self, param: list): self.p1 = param[0] self.p2 = param[1] # [...] Complexe stuff manipulating pandas DataFrame self.df['col3'] = self.df['col1'].rolling(window=self.p1).mean() self.df['col4'] = self.df['col2'].rolling(window=self.p2).mean() self.df['col5'] = self.df['col3']+self.df['col4'] self.best_value = self.df['col5'].iloc[-1] def func_to_minimize(input_parm:list, initialized_class): initialized_class.eval_value(input_parm) return initialized_class.best_valuepath = './path2data/data.csv'my_class = ComplexClass(path_data=path)# ===== INIT TEST =====my_param = [2, 10]print(f'For input {my_param}\n => Value to minimize = {func_to_minimize(input_parm=my_param, initialized_class=my_class)}')# ====== OPTIMIZATION WITH PULP =====# Create the 'prob' variable to contain the problem dataprob = pl.LpProblem("Best_Param", pl.LpMinimize)# The 2 variables Beef and Chicken are created with a lower limit of zerox1 = pl.LpVariable("param1", lowBound=2, upBound=10, cat=pl.LpInteger)x2 = pl.LpVariable("param2", lowBound=2, upBound=20, cat=pl.LpInteger)# The objective function is added to 'prob' firstprob += func_to_minimize([x1, x2], my_class) # <= doesn't work# The problem data is written to an .lp fileprob.writeLP("Best_Param.lp")# The problem is solved using PuLP's choice of Solverprob.solve()The error message is when evaluating self.df['col3'] = self.df['col1'].rolling(window=self.p1).mean() and is: ValueError: window must be an integer 0 or greater. Indeed, the self.p1 used in window is a LpVariable and not an integer.
How to minimize a problem using Pulp when the result to be minimised must be evaluated by a function and not by a line?
Thank you.