I have tried to optimize smooth objective (cost function) with tough non-linear constraints using diffevo algorithm. And I cant understand how to define such parameters as: constraints, bounds and init vectors.
My obj - just a sum of budget:
def minimize_me_reach(budgetA, *args):
# start = time.time()
# budget = args[0]
# # trp_total = args[0]
# freq = args[1]
# DF_GROUP = args[2]
# MEMBER = args[3]
# DF_GROUP['bud_part'] = 0
# DF_GROUP.loc[DF_GROUP['Prime'] == 1, 'bud_part'] = budgetA
# DF_GROUP.loc[DF_GROUP['Prime'] == 2, 'bud_part'] = budgetA
# DF_GROUP['budget_total'] = DF_GROUP['bud_part'] * budget
# execution of above program is :",(end - start), "sec")
return np.nan_to_num(budgetA).sum()
My constraint - 1 for now. Planing to add some more constraints
def constr_reach(x_all):
#budget = x_all[-1]
x = x_all[:-1]
print(DF_GROUP.info())
DF_GROUP['bud_part'] = 0
print(MEMBER.info())
DF_GROUP.loc[DF_GROUP['Prime'] == 1, 'bud_part'] = x
DF_GROUP.loc[DF_GROUP['Prime'] == 2, 'bud_part'] = x
DF_GROUP['budget_total'] = DF_GROUP['bud_part']
DF_GROUP['trp'] = DF_GROUP['budget_total'] / DF_GROUP['tcpp'] * DF_GROUP['trp_mult']
DF_GROUP['Q'] = pd.DataFrame([DF_GROUP['trp'] / DF_GROUP['Tvr_Origin'], DF_GROUP['COUNT'] - 1]).min()
test1 = tv_planet.calc_reach(MEMBER, DF_GROUP)
sOPT = test1.loc[freq - 1, '%']
return sOPT
I tried to optimize (minimize) it like this
stepmon = VerboseMonitor(50)
solver = DifferentialEvolutionSolver2(dim=53,NP=len(init_bud))
solver.SetConstraints(constr_reach)
#solver.SetInitialPoints(x0=x0, radius=0.1)
solver.SetGenerationMonitor(stepmon)
solver.enable_signal_handler()
solver.Solve(minimize_me_reach, termination=VTR(0.01), strategy=Best1Exp, \
CrossProbability=1.0, ScalingFactor=0.9, \
disp=True, ExtraArgs=(reach, freq, DF_GROUP, MEMBER, days))
result = solver.Solution()
iterations = len(stepmon)
cost = stepmon.y[-1]
print("Generation %d has best Chi-Squared: %f" % (iterations, cost))
print(result)
And this
result = diffev(minimize_me_reach, x0=x0, npop=len(init_bud), args=(reach, freq, DF_GROUP, MEMBER, days),
bounds=my_bounds, ftol=0.05, gtol=100,
maxiter=100, maxfun=None, cross=0.9, scale=0.8, full_output=False,
disp=1, retall=0, callback=None, strategy=Best1Exp, constraints=constr_reach)
But I have always encountered errors relative to constraint parameter. For instance.
File "d:\tvplan\tv-planner-backend\TV_PLANER2\top_to_bottom.py", line 1179, in optimizeReach_DE
solver.Solve(minimize_me_reach, termination=VTR(0.01), strategy=Best1Exp, \
File "C:\Users\Mi\AppData\Local\Programs\Python\Python310\lib\site-packages\mystic\differential_evolution.py", line 661, in Solve
super(DifferentialEvolutionSolver2, self).Solve(cost, termination,\
File "C:\Users\Mi\AppData\Local\Programs\Python\Python310\lib\site-packages\mystic\abstract_solver.py", line 1180, in Solve
self._Solve(cost, ExtraArgs, **settings)
File "C:\Users\Mi\AppData\Local\Programs\Python\Python310\lib\site-packages\mystic\abstract_solver.py", line 1123, in _Solve
stop = self.Step(**settings) #XXX: remove need to pass settings?
File "C:\Users\Mi\AppData\Local\Programs\Python\Python310\lib\site-packages\mystic\abstract_solver.py", line 1096, in Step
self._Step(**kwds) #FIXME: not all kwds are given in __doc__
File "C:\Users\Mi\AppData\Local\Programs\Python\Python310\lib\site-packages\mystic\differential_evolution.py", line 552, in _Step
self.trialSolution[candidate][:] = constraints(self.trialSolution[candidate])
TypeError: can only assign an iterable
I also tried to optimize it with set of SciPy algorithms. But had always failed. Could someone provide me example with optimization smooth function wit non-linear constraints on Mystic diffevo algorithms? Or any advise how to define my constraint to reach the solution?
I'm the author of
mystic. First, it seems thatDF_GROUPis not defined inside ofconstr_reach, so it may fail with aNameError. Regardless, your constraints function seems to not meet the interface requirements.We define an objective as
y = f(x), wherexis a list andyis a scalar. You can do multi-objective optimization, but let's keep it simple. Soft constraints (i.e. a penalty) are defined asy' = p(x)wherexis a list, andy'is a scalar penalty that is representative of the amount that the soft constraint is violated. Hard constraints (i.e. operators / transforms / constraints) are defined asx= c(x)wherexandx'` are a list representing the inputs.An objective that is both hard and soft constrained (internally to mystic) looks like this:
y' = f(c(x)) + p(x)Thus,
cis applied to transform the inputs (critically, so it produces a list of inputs where the constraint has been applied), and penaltypis then added to the cost of the objective to penalize where the soft constraints are violated.There are maybe 30 examples of applying nonlinear and other complex constraints here: https://github.com/uqfoundation/mystic/tree/master/examples2
There are several examples with even more complex constraints examples (i.e. moment constraints) here: https://github.com/uqfoundation/mystic/tree/master/examples3
mysticprovides several pre-built constraints functions that you can use to help you construct your own constraint function, if you like. They are, for the most part, in: https://github.com/uqfoundation/mystic/blob/master/mystic/constraints.py and a few more are in: https://github.com/uqfoundation/mystic/blob/master/mystic/tools.pyA simple, but instructive, example, from the
mystic.constraintsdoc is: