Re: [boost] Proposal for a Differential Evolution C++ library

On 1/9/2012 9:41 AM, Brian Schrom wrote:
Thanks.
The way I see it, the only common point between different optimization algorithms (if they are generic enough) is the objective function, which should have a very simple prototype: double f( std::vector< double > ); so in theory if different algorithms are implemented to accept the same types (in C++ sense) of objective functions, then you could run them interchangeably between GA, DE etc without any modification to the function or algorithm.
There are many real-life applications that I believe would benefit immediately from a maybe less than perfect implementation, so if it were my choice, I would rather release an initial version sooner and enhance it based on experience gathered from its practical use. Adrian Michel www.tradery.com

On 1/10/2012 1:37 AM, Adrian Michel wrote:
That ignores multi-objective optimization. In that case the return type would be, at a minimum std:vector<double>, and might require information on what characteristics are maximized. Also, this assumes for the input that we are talking about straight real numerical optimization. Even if we stay with numerical optimization we could be dealing with complex number, vector quantities, matrix quantities, perhaps even more sophisticated types like tensors. And still within what most would consider within the bounds of classic numerical optimization would be discrete constraints (of course, Goedel numbering allows us to encode /anything/ formal as one big integer which can then be encoded as a arbitrarily large vector of doubles, but then why bother with a program types at all? ... just Goedel number it). Its a small step from classic numerical optimization to numerical approximation/fitting, where the task is to select a formula in addition to selecting optimum parameters for it (currently on my todo list is to look at the "Eureqa" program, e.g., http://hplusmagazine.com/2011/03/25/eureqa-signs-of-the-singularity/, which is of this type). But the suggestion was for a general learning library. That's perhaps too broad, but combinatorial optimization or metaheuristic optimization seems reasonable. And these lead to a much broader range of inputs. Furthermore, many problems are much more efficient working with an objective delta function rather than directly with the objective function. The input here is the previous state and the changes made to it. For example, I'm currently developing a "School Timetabling" package. Re-evaluating the effects on the objective function of all the assignments (including their side effects on other assignments, e.g., when a timeslot is assigned to a section one term, it is highely desirable but not required that the corresponding timeslot be assigned to the same section in the next term) that remain the same between each increment would add a very large (albeit, linear in some descriptions of problem size) cost to the system. But just looking at the objective function is too narrow a view. We really only have two commonalities to every algorithm: an objective function and a possible solution (or possible partial solution) representation. The latter is clearly very open-ended while, as I discussed above, even the interface to the former has a lot of variation. But, addressing only what is universal misses the point, I think. There /is /a lot of pairwise overlap in various algorithms. Almost all involve some concept of mutators (to choose one term for them). If I want, for example, to try both a genetic algorithm and simulated annealing I might wish to use the same "local operators" in both. That would apply even more strongly if I wanted to compare two closely related algorithms, like, for example, simulated annealing and quantum annealing (no, the latter does not require a quantum computer), or neural networks and state machines. Also, the right representation would simplify constructing hybrid algorithms (e.g., in my school timetabling system, I first apply a greedy rule-based system to build a "fairly good" solution that meets all the hard constraints then apply simulated annealing with validity preserving mutators; or one could apply simulated annealing to each mutation in a genetic algorithm, or one might accept candidates in a genetic algorithm using the Boltzmann criteria from simulated annealing, or, again from my current work, my validity preserving operator in my SA phase is to randomly undo a some number of existing assignments and then use the rule based system with some random noise added to bring it back to a complete valid solution). I think delaying inclusion until all this has been nailed down would be a mistake. But thinking about traits, concepts, standards (e.g., does optimization mean minimization or maximization?), decisions about how both algorithm specific and somewhat shared algorithm parametrization (e.g., cooling schedule, population size) are to be specified, mutator interfaces (parametrized, presumably, with candidate solution representation), and certainly things that I have not yet considered, before locking it down, would probably be useful -- avoiding having to put too thick an adaptor interface around it later. I'd volunteer to work on this, but this note is one of the biggest breaks except for life necessities I've taken from working on this projectfor several weeks (I've run over, of course, and from here on out, I'm working for free). Perhaps later I'll be able to make a commitment -- but I am not even making a commitment to later making a commitment later. Topher

On 1/10/2012 2:00 PM, Topher Cooper wrote:
I was thinking about this as I was going to sleep last night. I had some thoughts about the direction this should go. This is no where near anything that could be called a design, but this what I thought of as a start. The key, I think, is separation of concerns -- even when those concerns can't entirely be separated. The idea of having a function prototype for the objective function that looks anything like:
while natural for this narrow context, is, in the context of a more general interface, wrong. The central entity, I think, is an object representing /a point in the solution space/, i.e., a candidate solution or partial solution with additional information such as history. Then, similarly to the algorithms library, metaheuristics like genetic algorithms, neural nets, etc. could be written abstractly to operate on these. I'm really not ready for any solid design, obviously, but, if we call the point in the solution space SSPoint (presumably, we are dealing with template duck typing rather than class heirarchy), the objective function interface could look something like: double SSPoint::objective(SSPoint::ObjectiveSelector dim = SSPoint::ObjectiveSelector::Primary); // ObjectiveSelector probably an enum template < size_t N> std::array< double, N > SSPoint::objective(std::array< SSPoint::ObjectiveSelector, N >); // Other sequence in/out alternatives in addition or instead of. (Here is where the real handwaving starts): SSPoint would (in my thinking) also provide lists of operators (mutators and/or combiners) filtered by an appropriate filter on the request. An operator might be deterministic (e.g., it might, internally, execute code equivalent to "private_v[13] *= 1.3;") or non-deterministic (e.g., "private_v[13] *= 1.0 + this->stdNrmGen()*0.1;"). The filters would restrict the kinds of operators (e.g., you wouldn't want a combiner for simulated annealing). There would also be additional information with the operator that would allow the metaheuristic to choose non-uniformly among them. Or perhaps instead of a filter there would be a specification for how to choose an operator. Combiners add some complexity here, since the characteristic of the other SSPoint (or SSPoints) might effect the selection criteria (even if we are not using biased operator choice, we might want to count a combiner with three candidate partners as if it were three operators in order to act as a uniform selector). Hand wave, hand wave ... The separation of concerns is that SSPoint understands its own representation, how it can be manipulated and how it can be measured (not only the objective function(s), but also information necessary for heuristic weighting, solution similarity, mate selection, local optima detection, schedule adjustment, and termination criteria) while the metaheuristic understands its requirements and how to sequence and select a series of operations on a point in a solution space to look for an optima. In practice, I imagine, there generally would be concurrent development of the two interacting pieces, but separation of concerns does not mean that choices in the different domains are not influenced or determined by global knowledge of the requirements in their interaction. There is a lot to pin down in terms of concepts, traits etc. and such fundamentals as whether an operator is applied destructively. In the long term, I could imagine (if this catches on sufficiently) a rich set of adaptors and building blocks for various metaheuristics and various kinds of problem representations, plus perhaps useful tools and data structures of more general use (e.g., a Fibonacci heap for efficient prioritization with frequent insertions and deletions between pops, packages for keeping solution histories and doing backtracking or taboo search (keeping a list of recent solutions and blocking, deterministically or nondeterministically repeats or near repeats), or coordinating distributed solvers). But maybe this is too ambitious. Topher Cooper
participants (2)
-
Adrian Michel
-
Topher Cooper