I am trying to use simulated annealing / basinhopping to find a minimum description length of a grammar object and the data according to that grammar.
I define the grammar object myself, as well as a take_step
(which is a mutation on the grammar):
def total_energy(self, grammar_and_data): #the objective function
# ...operations....
return encoder.totalLength(grammar,data)
def optimize(self, data):
initial_grammar_and_data = array((initial_grammar, data))
take_mutation = MyTakeStep()
ret = basinhopping(self.total_energy,
initial_grammar_and_data,
niter=100,
T=1.0,
#stepsize=0.5,
#minimizer_kwargs=None,
take_step=take_mutation,
#accept_test=None,
#callback=None,
#interval=50,
#disp=False,
#niter_success=None
)
The problem: I get an error:
File "C:\Users\Sefi\Anaconda3\lib\site-packages\scipy\optimize\optimize.py", line 556, in _approx_fprime_helper
grad[k] = (f(*((xk + d,) + args)) - f0) / d[k]
TypeError: unsupported operand type(s) for +: 'Grammar' and 'float'
How can I make the algorithm refer to the take-step function -alone- in order to find neighbors near the current value of the objective function? A small step-size is not definable here.
Perhaps the basin hopping cannot work with non-numerical arguments? If so, are you aware of generalized simulated annealing algorithms in Python that will do the trick (I could write one myself, but it will be far less efficient than scipy...)?