facebookresearch / nevergrad

A Python toolbox for performing gradient-free optimization
https://facebookresearch.github.io/nevergrad/
MIT License
3.95k stars 353 forks source link

How to perform an equality constraint #1471

Open redcican opened 2 years ago

redcican commented 2 years ago

I was wondering how to perform an equality constrain by using nevergrad:

the objective is defined as:

def objective(X):
  t1 = np.sum(X*price_list)
  t2 = reg.predict(np.append(feature_mean, [np.sum(X[:10]), np.sum(X[10:])]).reshape(1,-1))

  return t1 + t2

where reg is a linear regression function, price_list is array of shape (20,) I want to minimize this objective function.

let's say I have a array of shape (20,) to optimize, it has lower bound of 0, and upper bound of 100.

instrum = ng.p.Instrumentation(
    ng.p.Array(shape=(20,)).set_bounds(lower=0, upper=100),
)

The constraint is:

optimizer.parametrization.register_cheap_constraint(lambda X: np.sum(X[:10])*chemi_list[0] + np.sum(X[10:])*chemi_list[1] - chemi_to_achieve)`

which means the first 10 elements of array times the first array of chemi_list plus last 10 elements of array times the second array of chemi_list0 minus chemi_to_achieve should equal to 0.

the all constants arrays look like below:

price_list = np.array([0.28, 0.27, 0.25, 0.27, 0.28, 0.26, 0.28, 0.28, 0.27, 0.29, 0.32,
       0.28, 0.28, 0.31, 0.32, 0.29, 0.3 , 0.29, 0.33, 0.29])

chemi_list = np.array([[8.200e-02, 5.700e-03, 0.000e+00, 9.000e-05, 3.700e-04, 0.000e+00,
        6.475e-01, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
        0.000e+00, 0.000e+00, 0.000e+00],
       [1.400e-03, 7.520e-01, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
        0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00,
        1.400e-02, 0.000e+00, 0.000e+00]])

chemi_to_achieve = np.array([15, 3, 0, 3.5, 0, 0, 120, 8, 8, 0, 0, 0, 0, 0, 0])

But I kept getting error

from concurrent import futures

with futures.ThreadPoolExecutor(max_workers=optimizer.num_workers) as executor:
  recommendation = optimizer.minimize(objective, verbosity=2, executor=executor, batch_mode=False)

TypeError: can only concatenate tuple (not "dict") to tuple

can anyone tell me how to solve this?

HugoChikli commented 1 year ago

Hi,

Could you specify how you defined 'feature_mean'?

Thank you

nhansendev commented 1 year ago

The constraint is:

optimizer.parametrization.register_cheap_constraint(lambda X: np.sum(X[:10])*chemi_list[0] + np.sum(X[10:])*chemi_list[1] - chemi_to_achieve)`

which means the first 10 elements of array times the first array of chemi_list plus last 10 elements of array times the second array of chemi_list0 minus chemi_to_achieve should equal to 0.

There is a discrepancy between the documentation on the website and in the code. On the website >= 0 is a passing value, but in the code this is reversed and any value > 0 is a fail.

Please check if your code works after taking this into account.