I have a simple optimization problem, where I am trying to optimize the number of leads, each of which have a certain cost (which varies based on the number of leads, e.g. 1 lead may cost 1$ while 2 leads may cost 1.5$ each). The cost of each lead is calculated using the following function. The comments are tries I made to fix different issues.
# Here x is leads and returns spend
def objective_inverse(x, a, b, c):
if c == 0:
return 0
else:
return np.real(a + (x/c)**(1./b))
Here is the variable reg_feats , where each tuple in the list is (a,b,c) in the previous function.
reg_feats = [(0.0, 1.0, 0.0008237661018136143), (0.9999999999999811, 0.8536915943397881, 0.004454688129841911), (0.0, 1.0, 0.0004855869694355375), (0.0, 1.0, 0.00038427101866404334), (8.308985001840891e-10, 1.097417548409198, 0.0009170956872015353), (0.999999999998488, 1.9999999897072056, 1.144122017534284e-07), (0.9999999999825329, 0.8097037523302283, 0.20606857088111075), (0.9999999999999963, 1.1649279015402045, 0.009316713936903972), (0.0, 1.0, 0.0034430519212229715), (0.0, 1.0, 0.0007980573950249244), (0.0, 1.0, 0.0009069008844368589)]
and also have a list for each variable's bound.
bounds = [(0, 4), (0, 20), (0, 3), (0, 1), (0, 114), (0, 14), (0, 208), (0, 529), (0, 1), (0, 4), (0, 4)]
Here is the code for the optimization:
m = GEKKO(remote=not bool(i))
m.options.SOLVER=1
# optional solver settings with APOPT
m.solver_options = ['minlp_maximum_iterations 50000', \
# minlp iterations with integer solution
'minlp_max_iter_with_int_sol 100', \
# treat minlp as nlp
'minlp_as_nlp 0', \
# nlp sub-problem max iterations
'nlp_maximum_iterations 500', \
# 1 = depth first, 2 = breadth first
'minlp_branch_method 1', \
# maximum deviation from whole number
'minlp_integer_tol 0.05', \
# covergence tolerance
'minlp_gap_tol 0.01']
Here x is the number of leads for each campaign.
x = m.Array(m.Var, (len(bounds)),integer=True)
# Here x is the number of leads and is the decision variable
# x variables are nb of leads, not $ to be allocated
for i, xi in enumerate(x):
lb, ub = bounds[i]
xi.lower = lb
xi.upper = ub
xi.value = ub
This intermediate variable is to get the cost of each lead. This is used in the next constraint.
sums = [m.Intermediate(objective_inverse(xi,*y)) for xi,y in zip(x,reg_feats)]
max_budget = 150000
m.Maximize(m.sum(x))
c = m.Const(max_budget, 'Budget')
m.Equation(m.sum(sums) < c)
m.solve(disp=True)
Here, if I run this code, I get an error saying no solution has been found and Warning: no more possible trial points and no integer solution
Also, if I remove the max_budget constraint, I get a solution where the total amount spent is lower than the max_budget, which means that adding the constraint shouldn't change the solution.
I know there is a problem as to how I defined the constraint, but don;t know how to fix it.