Storing a non-accepted eval on a chain; candidate exchange chains with replacement.
-
Updated set_eval!() to store best value only if eval is accepted. A function evaluation that returns eval.status < 0 will also have eval.value = -1 because of the way the Eval object is initialised. This value is mistakenly saved in the chain if one does not condition on ev.accepted==true, as it is always smaller than anything else on the chain up to that point.
-
Candidate exchange pairs of chains are chosen WITH replacement according to Baragatti et al (2013) "N pairs of chains are chosen uniformly in all possible pairs with replacement".
hi! thanks for the contribution. regarding 1. there is the allAccepted method. I prefer to save all values on the chain. True if you stop after iteration 1, your best value is -1 one. but then you have other problems to deal with :-)
regarding 2., it may be a sensible addition to allow for this to be an option to be set by the user. in my exerpience the algorithm is extremely sensitive to all the related tuning parameters (which I consider this one to be). What worked for them (i.e. resampling) need not work for other applications. i think i set that to false to maximize mixing between chains. if you want to modify the PR to add this as a kw-arg, I'd be happy to accept.
any idea why travis is failing?
-
I see. I adapted the code to my specific application and am not using allAccepted. Nevertheless, in my case, in one chain the objective function returned
ev.status < 0(thusev.value = -1) in the 200th+ iteration. Then that chain never accepted any other subsequent value (typicalev.valuein the range of10.0-15.0) because-1was the very best it could get. -
I agree, it should be a user-set parameter.
No idea about travis, sorry!
then something else seems to be wrong... the algo should not use non-accpepted values to update, that doesn't make much sense:
https://github.com/floswald/SMM.jl/blob/master/src/mopt/AlgoBGP.jl#L312
eval_old = getLastAccepted(c)
if eval_new.status < 0
eval_new.prob = 0.0
eval_new.accepted = false
else
Thanks Florian.
Regarding 1: Still, if one does not condition on ev.accepted==true, then set_eval!() updates the chain's best value with ev.value even if ev.value is negative, i.e. perhaps from an error in the objective function.
if (ev.value < c.best_val[c.iter-1]) c.best_val[c.iter] = ev.value c.best_id[c.iter] = c.iter else ... end
I would expect that c.curr_val stores ev.value no matter what that is, while c.best_val keeps track of the true best value.
I see, that makes sense! There seems to be an issue with this indeed. happy to accept any proposals! :-)