{"action":"created","issue":{"url":"https://api.github.com/repos/jMetal/jMetal/issues/73","labels_url":"https://api.github.com/repos/jMetal/jMetal/issues/73/labels{/name}","comments_url":"https://api.github.com/repos/jMetal/jMetal/issues/73/comments","events_url":"https://api.github.com/repos/jMetal/jMetal/issues/73/events","html_url":"https://github.com/jMetal/jMetal/pull/73","id":81537477,"number":73,"title":"Add solution management features (variables, objectives, managers).","user":{"login":"matthieu-vergne","id":1774210,"avatar_url":"https://avatars.githubusercontent.com/u/1774210?v=3","gravatar_id":"","url":"https://api.github.com/users/matthieu-vergne","html_url":"https://github.com/matthieu-vergne","followers_url":"https://api.github.com/users/matthieu-vergne/followers","following_url":"https://api.github.com/users/matthieu-vergne/following{/other_user}","gists_url":"https://api.github.com/users/matthieu-vergne/gists{/gist_id}","starred_url":"https://api.github.com/users/matthieu-vergne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthieu-vergne/subscriptions","organizations_url":"https://api.github.com/users/matthieu-vergne/orgs","repos_url":"https://api.github.com/users/matthieu-vergne/repos","events_url":"https://api.github.com/users/matthieu-vergne/events{/privacy}","received_events_url":"https://api.github.com/users/matthieu-vergne/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-05-27T17:12:15Z","updated_at":"2015-06-07T21:37:19Z","closed_at":"2015-05-28T14:27:36Z","pull_request":{"url":"https://api.github.com/repos/jMetal/jMetal/pulls/73","html_url":"https://github.com/jMetal/jMetal/pull/73","diff_url":"https://github.com/jMetal/jMetal/pull/73.diff","patch_url":"https://github.com/jMetal/jMetal/pull/73.patch"},"body":"So here is how I would implement the variables/objectives management. I give you some details to explain the design choices, including the relevant code. I don't show the documentation to make it more readable, but in the commit it is fully documented.\r\n\r\nI put all of it in the `solution` package because it is all about managing solutions. As we said, the `Solution` interface is prone to disappear (keeping only the concrete implementations), so all my generics named `Solution` are not linked to this interface and thus can refer to anything.\r\n\r\n# The issue\r\n\r\nThe initial idea was that an `Algorithm` would provide the variables and objectives to consider, such that we can retrieve the corresponding values for each solution it provides. But if you remember well, we have the algorithm solution VS problem solution issue. Concretely, both algorithms and problems could provide variables and objectives, and we could see that in the last experiment I did in my [attribute branch](https://github.com/matthieu-vergne/jMetal/tree/attributes/jmetal-core/src/main/java/experimental) where I have developped two algorithms to solve the same TSP problem:\r\n- the `SpecificHillClimbing`, which stores all the necessary knowledge and just need a few parameters (e.g. the actual cities and the number of rounds to run)\r\n- the `GenericHillClimbing`, which is oblivious to the problem and just focus on the hill climbing operations (the number of rounds, but also the cost evaluation, the random and mutant generators)\r\n\r\nWith these two examples, we see clearly that it could be the algorithm or the problem which provides:\r\n- the variables (with the generic case, the algorithm does not even care about any variable)\r\n- the objectives (although the generic case use the cost evaluation, it is provided by the problem)\r\n- the solution generation (the generic case relies on the problem to provide the random and mutant generators)\r\n\r\nMore precisely, the problem provides them in the generic case while the algorithm provides them in the specific case.\r\n\r\nHowever, we could face something more entangled: the algorithm could be intended to deal with the TSP problem, thus introducing the notion of location and deal with `List<Location>` solutions, thus knowing how to generate and mutate them, but it could require the cost function from the problem, which could decide to use the length of the path, the time of travel or the fuel consumption. At the opposite, one could imagine an algorithm which provides the objectives but require the variables and solution generation to be provided. While I don't think that the latter case is frequent, I think it could be interesting for cases where you have problems which should rely on complex sets of variables, but which fall in categories where you need to deal with complex objective evaluations, each of them having their own experts. I especially have in mind an economical situation, where you have for instance a product line which can deal with a lot of variability in the product, thus having complex specific variables (e.g. for a car the amount of metal, the amount of plastic, the color, specific options, etc.), but from the point of view of the algorithm there is some generic variables to consider (e.g. a set of amount of resources, whatever it is) in order to optimize for instance the storage of the resources and plan the ordering of new resources. Such an algorithm would provide its own objectives evaluation (e.g. probability to run out of resource, delays cost, etc.). We could argue that the variables used by the algorithm could be also called objectives, because at the end it is anyway a matter of evaluation, and this reflects in my `Variable` and `Objective` interfaces, which both provide an identical `Value get(Solution solution)` method. But in any case, we see that there is a need to separate the generation of the solution, which involves the variables, and its evaluation, which involves the objectives.\r\n\r\n# Generating solutions\r\n\r\nConsequently, I made a `SolutionBuilder`:\r\n```\r\npublic interface SolutionBuilder<Solution> {\r\n\tpublic static interface Variable<Solution, Value> extends DescribedEntity {\r\n\t\tpublic Value get(Solution solution);\r\n\t}\r\n\r\n\tpublic Collection<Variable<Solution, ?>> getVariables();\r\n\r\n\tpublic <Value> void prepare(Variable<Solution, Value> variable, Value value);\r\n\r\n\tpublic Solution build();\r\n}\r\n```\r\nA `SolutionBuilder` is the one who knows about the fundamental information of the solutions, thus the one which defines what are the relevant `Variables` and how to generate a valid solution. For this generation, one would call `builder.prepare(variable, value)` on each variable and then call `builder.build()` to get the corresponding solution.\r\n\r\nNotice that `Variable` does not include a setter. This is because, from the point of view of an external user, he receives the solution as it is and deal with it like that. Having only access to the solution and the `Variable` instance gives you a kind of read-only access, while a user having the `SolutionBuilder` will be able to produce new solutions. This way to do allows to be compatible with static implementations, where you create an instance which is not designed to change (its members are usually `final` ones). Static implementations have this advantage over dynamic ones of not having to deal with side effects: the values are decided once for all and any computation can be stored without needing to be refreshed. A dynamic implementation, at the opposite, needs to manage the changes and pay attention to side effects, like cache which should be refreshed. In parallel processing, it also means that synchronization should be made to avoid conflicting changes to occur. On many aspects, static implementations are optimized ways to deal with data, and it is particularly interesting in situations where you have a lot of data but a few changes occur, making the creation of new instances more interesting than having all of them ready to be changed. And I think it is a relevant perspective in our case, because an algorithm generally deal with many instantiations rather than having a fixed set of solutions and changing them at each round.\r\n\r\nSo this `SolutionBuilder` provides the relevant `Variables` and the way to generate the solutions.\r\n\r\n# Evaluating solutions\r\n\r\nSimilarly, I introduce the `SolutionEvaluator`:\r\n```\r\npublic interface SolutionEvaluator<Solution> {\r\n\tpublic static interface Objective<Solution, Value> extends DescribedEntity {\r\n\t\tpublic Value get(Solution solution);\r\n\t}\r\n\r\n\tpublic Collection<Objective<Solution, ?>> getObjectives();\r\n}\r\n```\r\nIt is intended to evaluate the solutions, thus it provides the `Objectives` to consider for such evaluation. And that's it. Here we are not doing anything to the solution, just obtaining values for judging.\r\n\r\nActually, there could have something more: I did not look at the constraints management, but I think it is only a matter of knowing what is the constraint and checking whether or not the constraint is satisfied, or possibly how much it is satisfied. I would see an extended version of this interface like that:\r\n```\r\npublic interface SolutionEvaluator<Solution> {\r\n\tpublic static interface Objective<Solution, Value> extends DescribedEntity {\r\n\t\tpublic Value get(Solution solution);\r\n\t}\r\n\r\n\tpublic Collection<Objective<Solution, ?>> getObjectives();\r\n\r\n\tpublic static interface Constraint<Solution, ...> extends DescribedEntity {\r\n\t\t...\r\n\t}\r\n\r\n\tpublic Collection<Constraint<Solution, ...>> getConstraints();\r\n}\r\n```\r\nand an evaluator having no constraint would just return an empty collection for `getConstraints()`. Maybe it could be more relevant to have a separated interface for managing constraints, we have to see how it interacts with the objectives. If there is constraints for `Variables`, then I would see something similar for the `SolutionBuilder` interface, but then we start to touch to the value generation, and I have another branch on that, so let's that for another time (but I start to have an interesting design their too). Anyway, I did not deal with constraints here, so it is still an open issue.\r\n\r\n# How to use?\r\n\r\nBasically, I would expect that an algorithm implements both `SolutionBuilder` and `SolutionEvaluator` if it is highly specific and none of them if it is highly generic, but basically the point is to implement the right ones depending on what the algorithm provides. Similarly, the problem could surely implement the `SolutionBuilder`, because it is the one which is supposed to know what are the solutions to deal with and how to interprete them (especially for display). If we have enough knowledge in the problem to know how to evaluate the solutions, it would implement `SolutionEvaluator` too. But at the end, what would make a compatible algorithm-problem pair is a pair where we have both a `SolutionBuilder` and a `SolutionEvaluator` (both could implement them, but each interface should be implemented by at least one of them) dealing with the same type of `Solution`. Then, if both the algorithm and the problem are `SolutionEvaluators`, one can decide to use one or the other (or both) for display purpose.\r\n\r\nI also provide two factories, `VariableFactory` and `ObjectiveFactory`, I let you guess what they generate {^_°}. You can check them out, but basically I have implemented what we need to retrieve relevant instances from conventional implementations (based on getters, setters, and constructor arguments). We can add other ones if we choose to deal with other kinds of templates. They are documented and tested."},"comment":{"url":"https://api.github.com/repos/jMetal/jMetal/issues/comments/109801829","html_url":"https://github.com/jMetal/jMetal/pull/73#issuecomment-109801829","issue_url":"https://api.github.com/repos/jMetal/jMetal/issues/73","id":109801829,"user":{"login":"matthieu-vergne","id":1774210,"avatar_url":"https://avatars.githubusercontent.com/u/1774210?v=3","gravatar_id":"","url":"https://api.github.com/users/matthieu-vergne","html_url":"https://github.com/matthieu-vergne","followers_url":"https://api.github.com/users/matthieu-vergne/followers","following_url":"https://api.github.com/users/matthieu-vergne/following{/other_user}","gists_url":"https://api.github.com/users/matthieu-vergne/gists{/gist_id}","starred_url":"https://api.github.com/users/matthieu-vergne/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matthieu-vergne/subscriptions","organizations_url":"https://api.github.com/users/matthieu-vergne/orgs","repos_url":"https://api.github.com/users/matthieu-vergne/repos","events_url":"https://api.github.com/users/matthieu-vergne/events{/privacy}","received_events_url":"https://api.github.com/users/matthieu-vergne/received_events","type":"User","site_admin":false},"created_at":"2015-06-07T21:37:19Z","updated_at":"2015-06-07T21:37:19Z","body":"Let's go further on the `SolutionBuilder` and `SolutionEvaluator`.\r\n\r\n# Problem Perspective\r\n\r\n## Example background\r\n\r\nTaking back the [`PracticalContext`](https://github.com/matthieu-vergne/jMetal/blob/attributes/jmetal-core/src/main/java/experimental/PracticalContext.java) I introduced in my example for the attributes, this class aims at providing the information owned by the problem designer (i.e. the one having the problem, an instance of the TSP, and who wants to solve it). In other words, it provides the problem-related information. In particular:\r\n- it introduces the notion of `City` and provides the different cities through `getCities()`\r\n- it assumes that a solution to its problem should be represented as a `List<City>`\r\n- it evaluates such a solution through `calculatePathLength(List<City> path)`\r\n- it provides additional features to display a solution in a graphical way\r\n\r\nConsequently, we see that it has almost all the information, the only one missing is how to find a good solution, which is the aim of the algorithm (or more precisely the metaheuristic). In particular, this problem designer knows how to *build* a valid solution and how to *evaluate* it. Consequently, it can provide both a `SolutionBuilder` and a `SolutionEvaluator`.\r\n\r\n## On the unicity of the builder/evaluator\r\n\r\nWhether a class *provides* `SolutionBuilder`/`SolutionEvaluator` instances or directly *implement* them is a design choice, but initially you would probably expect to have a single builder and a single evaluator because you know well the problem and solution to use. But this unicity is the consequence of the situation, and I see (at least) 2 such situations:\r\n- the problem is known well enough to properly identify the information to encode in a solution (variables and objectives) and how to encode it (type of solution to store the data)\r\n- we take the sufficient assumptions (a priori decisions) to decide which information/encoding to use (whether it actually corresponds to the practical problem we want to solve or not)\r\n\r\nI would place in the first situation the formalized real cases, where people have enough experience to know what they are dealing with and what they need, while in the second situation I would place the experimental/research cases, where we choose some problem abstractions a priori and design specific algorithms for them.\r\n\r\nAdditionally, there is also situations where we could have *several* evaluators, meaning several ways to evaluate a solution, which is different than having a *single* evaluator with *several* objectives. A single evaluator with several objectives is typically what you would use for Pareto optimality: several dimensions to consider to properly evaluate a solution, like considering for the TSP the total fuel consumption, the total time, the number of refuel, etc. On the other hand, multiple evaluators with one or several objectives each would come from a context having several independent perspectives, so you don't expect to optimize all of them together. As an analogy, one could imagine the perspective of different departments within a company, which each holds their own view and deal with their own needs. However, it is hard to say that such an context justifies to have several evaluators, because at the end you could simply want to fulfill at best everyone, and so make a Pareto front based on all the needs of the company. Rather, I would focus on the TSP example, with a problem designer who could wonder whether to use the real distance between two cities (`Math.sqrt(dx * dx + dy * dy)`) or a simplified version (`dx * dx + dy * dy`). One could also think to use an even more simplified version (`dx + dy`) to get further improvements. In this case, it is clear that it makes no sense to evaluate them together and make a Pareto front on all of them.\r\n\r\nMoreover, having different evaluators for each allows to compare them in experiments, for instance taking one as a reference (the exact distance) and evaluating several solutions with each evaluator and comparing the results. Or more practically, optimize some simple instances of the problem with each evaluator and see which ones still provides good solutions (based on the exact distance evaluator) but increase the performances of the algorithm, and which ones are not interesting because they just evaluate something else. You could tell me that for this example, the answer is trivial: it would be preferable to use the second one because it is equivalent to the first (for the expected purpose) but requires less computation, while the third one just compute something different. But this is trivial because we know well the problem. For complex evaluations, one could miss the formal knowledge to properly assess which one is the best, delegating such assessment to an empirical experiment. Notice that one can always split a single evaluator into several (choosing which objectives to give to which evaluators) as well as merge several evaluators into a single one (aggregating all the objectives together), so you could have advanced management.\r\n\r\nSimilarly, there is situations in which we could have several builders, for instance one could wonder to encode the solution on 3 cities {a, b, c} as:\r\n1. a list of cities, like (b, a, c),\r\n2. a list of indexes where each index corresponds to a given city, like (2, 1, 3),\r\n3. a list of indexes where each index corresponds to a given city within the remaining ones, like (2, 1, 1),\r\n4. etc.\r\n\r\nTypically, depending on the encoding, the operators would change: with 1 and 2 you can freely swap two items in the list, and with 3 you can take a random value for each index independently, but you cannot apply the operator of 1 (or 2) on 3 and vice-versa, unless you add repairing features to avoid invalid solutions (e.g. duplicata of cities, out of range indexes). So one could provide several builders, each with its own variables and solution implementation, and this would have an effect on the compatibility between the problem and the algorithm.\r\n\r\n## Application to the example\r\n\r\nSo implementing `SolutionBuilder`/`SolutionEvaluator` or providing one or several instances depends first on the information we want to exploit. For the specific problem designed by [`PracticalContext`](https://github.com/matthieu-vergne/jMetal/blob/attributes/jmetal-core/src/main/java/experimental/PracticalContext.java), it could simply implement both of them, because it assumes a single way to build/evaluate the solutions:\r\n(I did not try my codes, and they surely do not compile because I focus on the most relevant parts of the interfaces)\r\n```\r\npublic class PracticalContext implements SolutionBuilder<List<City>>,\r\n                                         SolutionEvaluator<List<City>> {\r\n  \r\n  // ...\r\n  // already implemented stuff\r\n  // ...\r\n  \r\n  /******************\r\n   * Builder stuff\r\n   ******************/\r\n  \r\n  // I define a variable for each of the 5 cities, but it is also possible\r\n  // to make simply a single variable for the full list. I show such an example\r\n  // in the algorithm perspective later. This is an example of situation\r\n  // for multiple builders, which would require to use different operators.\r\n  // you could also imagine to combine the different types of variables to \r\n  // exploit all the operators, but this is more advanced.\r\n  private static class CityAccessor implements Variable<List<City>, City> {\r\n    \r\n    private final int index;\r\n    \r\n    public CityAccessor(int index) {\r\n      this.index = index;\r\n    }\r\n    \r\n    public City get(List<City> solution) {\r\n      return solution.get(index);\r\n    }\r\n  }\r\n  \r\n  private final Variable<List<City>, City> city1 = new CityAccessor(0);\r\n  private final Variable<List<City>, City> city2 = new CityAccessor(1);\r\n  private final Variable<List<City>, City> city3 = new CityAccessor(2);\r\n  private final Variable<List<City>, City> city4 = new CityAccessor(3);\r\n  private final Variable<List<City>, City> city5 = new CityAccessor(4);\r\n  \r\n  public Collection<Variable<List<City>, ?>> getVariables() {\r\n    return Arrays.asList(city1, city2, city3, city4, city5);\r\n  }\r\n  \r\n  private final Map<Variable<List<City>, Value>, Value> preparedSolution\r\n                     = new HashMap<Variable<List<City>, Value>, Value>();\r\n  \r\n  public <Value> void prepare(Variable<List<City>, Value> variable, Value value) {\r\n    // typically you would add some integrity checks on the specific variable here\r\n    preparedSolution.put(variable, value);\r\n  }\r\n  \r\n  public List<City> build() {\r\n    // typically you would add some integrity checks between all the variables here\r\n    List<City> solution = new LinkedList<City>();\r\n    solution.add(preparedSolution.get(city1));\r\n    solution.add(preparedSolution.get(city2));\r\n    solution.add(preparedSolution.get(city3));\r\n    solution.add(preparedSolution.get(city4));\r\n    solution.add(preparedSolution.get(city5));\r\n    return solution;\r\n  }\r\n  \r\n  /******************\r\n   * Evaluator stuff\r\n   ******************/\r\n  \r\n  private final Objective<List<City>, Double> lengthObjective\r\n                        = new Objective<List<City>, Double> {\r\n    public Double get(List<City> solution) {\r\n      return calculatePathLength(solution);\r\n    }\r\n  }\r\n  \r\n  public Collection<Objective<List<City>, ?>> getObjectives() {\r\n    return Arrays.asList(lengthObjective);\r\n  }\r\n}\r\n```\r\n\r\nGoing further, as a problem can provide one or several builders/evaluators, it could also provide no evaluator (if it does not know what is relevant to evaluate for the kind of problem it deals with) and no builder (if it does not know how to encode a solution). But this is easier to understand with the next section.\r\n\r\n# Algorithm Perspective\r\n\r\n## Application to the example\r\n\r\nIf we consider the [`SpecificHillClimbing`](https://github.com/matthieu-vergne/jMetal/blob/attributes/jmetal-core/src/main/java/experimental/specific/SpecificHillClimbing.java) implementation of my example, it provides an algorithm specialized for a precise type of problem. Consequently, it makes detailed assumptions to exploit. As such, it already implement the building and evaluation of solutions, so like [`PracticalContext`](https://github.com/matthieu-vergne/jMetal/blob/attributes/jmetal-core/src/main/java/experimental/PracticalContext.java) it can implement both `SolutionBuilder` and `SolutionEvaluator`:\r\n```\r\npublic class SpecificHillClimbing implements Algorithm<Path>,\r\n                                             SolutionBuilder<Path>,\r\n                                             SolutionEvaluator<Path> {\r\n  \r\n  // ...\r\n  // already implemented stuff\r\n  // ...\r\n  \r\n  /******************\r\n   * Builder stuff\r\n   ******************/\r\n  \r\n  // this time we ue a single variable to return the full list as a whole\r\n  private final Variable<Path, List<Location>> locations\r\n                                   = new Variable<Path, List<Location>> {\r\n    public List<Location> get(Path solution) {\r\n      // We could directly return the solution, but we return an unmodifiable proxy\r\n      // on it to forbid the modification of a solution, so we avoid unexpected\r\n      // side effects.\r\n      return Collections.unmodifiableList(solution);\r\n    }\r\n  };\r\n  \r\n  public Collection<Variable<List<City>, ?>> getVariables() {\r\n    return Arrays.asList(locations);\r\n  }\r\n  \r\n  private final Map<Variable<List<City>, Value>, Value> preparedSolution\r\n                               = new HashMap<Variable<List<City>, Value>, Value>();\r\n  \r\n  public <Value> void prepare(Variable<List<City>, Value> variable, Value value) {\r\n    // typically you would add some integrity checks on the specific variable here\r\n    preparedSolution.put(variable, value);\r\n  }\r\n  \r\n  public List<City> build() {\r\n    Path solution = new Path(preparedSolution.get(cities));\r\n    return solution;\r\n  }\r\n  \r\n  /******************\r\n   * Evaluator stuff\r\n   ******************/\r\n  \r\n  private final Objective<Path, Double> lengthObjective = new Objective<Path, Double> {\r\n    public Double get(Path solution) {\r\n      return evaluate(solution);\r\n    }\r\n  }\r\n  \r\n  public Collection<Objective<List<City>, ?>> getObjectives() {\r\n    return Arrays.asList(lengthObjective);\r\n  }\r\n}\r\n```\r\n\r\nThus, an algorithm can provide both a builder and an evaluator too. Once this is understood, it is simpler to understand how a problem can provide no evaluator and no builder at all. Taking a real TSP instance, one could have all the relevant information, like the cities, their locations, etc., but have never heard about any TSP problem, and is actually a complete noob in optimization. This problem designer knows that he wants to minimize the fuel cost, but has no idea of how to compute reliably the fuel consumption, for instance because it is not just a matter of straight line distance and we should consider also the mountains, zigzags, speed limits, etc. Now you have a friend who has implemented a metaheuristic which computes all of that, for instance by exploiting the Google Maps API to get the exact distance (not a mere sqrt(dx^2+dy^2)) and also use the fuel cost estimation of the API. All it requires is to get the geographical locations of the points to pass through. So the problem designer can provide his information to the metaheuristic without needing to tell how to build a solution nor to evaluate it, because the metaheuristic already does this job.\r\n\r\n## On the unicity of the builder/evaluator\r\n\r\nCould an algorithm provide several builders? Nothing forbid it, for instance the algorithm could be designed to deal with a generic `List<Location>` as well as a highly optimized encoding. But the chance to face such a situation is probably really low. Could an algorithm provide several evaluators? Same thing, dealing with different sets of assumptions would usually lead to design different algorithms, but one can try to implement a complex algorithm able to deal with such a variability. Would it be smarter to use generalizations rather than mixing different assumptions? Probably, but it is not always possible (the immediate parent class could be `Object` and you could have no control on it, so you cannot generalize properly). So basically, while an algorithm is prone to be upper bounded to 1 builder and 1 evaluator, nothing forbids to provide several of them.\r\n\r\nTaking the opposite direction, could an algorithm provide no builder nor evaluator? In the absolute, it should always be related to a builder and an evaluator, because you cannot explore the solution space if you cannot *build* solutions, and you cannot find optimized ones if you cannot *evaluate* them. However, it could be oblivious to the building/evaluation *process*. This is the case for instance of my [`GenericHillClimbing`](https://github.com/matthieu-vergne/jMetal/blob/attributes/jmetal-core/src/main/java/experimental/generic/GenericHillClimbing.java) implementation: it requests the random and mutant generators, as well as the cost evaluation, as parameters. One could say that it is then able to provide an evaluator, but this is just because the evaluator only requires the list of objectives. It becomes clearer if we consider the builder: this implementation can surely provide solutions, but only random solutions and mutants (solutions slightly different to another one). It has no control at all (and actually no information at all) regarding the variables used. And even if you add the variables to the parameters, for a reason or another, it is still unable to generate a solution by using these variables, because it has no clue of the type of solution to use and how to instantiate it. Thus, it could provide a full builder only if it receives a builder (or something equivalent) through its parameters. This is the same for the evaluator: it can provide one only because it get something equivalent (the (set of) objective(s)) which can be translated into an evaluator. But fundamentally, this [`GenericHillClimbing`](https://github.com/matthieu-vergne/jMetal/blob/attributes/jmetal-core/src/main/java/experimental/generic/GenericHillClimbing.java) cannot provide any builder/evaluator by itself.\r\n\r\n# On the use of Builders/Evaluators\r\n\r\nWith the examples above I show how, practically, the notions of solution building and evaluation are, although fundamental (otherwise no algorithm running), decoupled from the notions of problem and algorithm, which can provide one, several, or no builder/evaluator at all. Now, knowing that they are decoupled is nice, but what would be their utility? Does it make sense to have them in the core of the framework, or is it just some experiment facilities?\r\n\r\n## Within Experiments\r\n\r\nAn experiment is a trivial context where one could use builders and evaluators. For instance, if you combine [`PracticalContext`](https://github.com/matthieu-vergne/jMetal/blob/attributes/jmetal-core/src/main/java/experimental/PracticalContext.java) and [`SpecificHillClimbing`](https://github.com/matthieu-vergne/jMetal/blob/attributes/jmetal-core/src/main/java/experimental/specific/SpecificHillClimbing.java), you have then 2 builders and 2 evaluators and, while the algorithm is designed to use its own builder and evaluator, nothing forbids you to use the evaluator of the problem to assess that the algorithm is adapted to solve it.\r\n\r\nFor example, you can design an experiment which takes an `Algorithm` (already parametered) and a `SolutionEvaluator`, both being related by the type of `Solution` they manage. By executing the `Algorithm`, you obtain a (set of) `Solution` that you can then evaluate through the `SolutionEvaluator`. This is the most basic experiment: you run the algorithm and see what it gives. Typically, you would use the `SolutionEvaluator` coming from the `Problem` to properly assess the efficiency of the `Algorithm`, but you could also use the one of the `Algorithm` if the problem does not provide one. This would occur for instance for the example given above, of the TSP problem where the problem designer has no idea on how to reliably compute the fuel cost. By using the evaluator of the `Algorithm`, one would just assess the behaviour of the algorithm on the specific problem instance, for instance how long it takes to reach a plateau, does it reach a different one if we re-run it, etc.\r\n\r\nWhat about the builder? You can use it in an experiment to build extra solutions. For instance, if there is already a known (set of) optimal solution(s), you can use the builder to create them (from a file or let the user do it through a GUI) and then use some additional distance computations to evaluate how far the solutions of the `Algorithm` fall compared to the optimal solution(s). If you have several builders, we can imagine many things: for the case where you have one builder from the problem and another one from the algorithm, you would use the right builder depending on which evaluator you use, to ensure the compatibility. If you just get several builders from the same problem/algorithm, then it all depends what you want to do with them, but if you also have translators to pass from one encoding to another, then you can just choose your preferred builder and use the translator to get the right encoding for the evaluation. This is rather open.\r\n\r\n## Within Operators\r\n\r\nThere is another relevant context in which we can imagine to use solution builders: generic operators. I already mentionned (although I don't remember in which discussion) that operators could be designed to focus on processing the variables rather than the solution themselves. The solution builder allows precisely that. For instance you can create an operator dedicated to item swapping for lists:\r\n```\r\npublic class ItemSwapOperator<Solution, Item> implements Operator<Solution, Solution> {\r\n  \r\n  private final SolutionBuilder<Solution> builder;\r\n  private final Variable<Solution, List<Item>> listVariable;\r\n  private final Random rand = new Random();\r\n  \r\n  public ItemSwapOperator(SolutionBuilder<Solution> builder,\r\n                          Variable<Solution, List<Item>> listVariable) {\r\n    this.builder = builder;\r\n    this.listVariable = listVariable;\r\n  }\r\n  \r\n  public Solution execute(Solution source) {\r\n    // we get the ordered items of the source\r\n    List<Item> items = listVariable.get(source);\r\n    \r\n    // we create a dynamic instance that we can modify\r\n    // (static implementations of List can throw exceptions\r\n    // on usual methods like set(index, item))\r\n    items = new LinkedList(items);\r\n    \r\n    // we make the random swap\r\n    int index1 = rand.nextInt(items.size());\r\n    int index2 = rand.nextInt(items.size());\r\n    Item temp = items.get(index1);\r\n    items.set(index1, items.get(index2));\r\n    items.set(index2, temp);\r\n    \r\n    // we build and return the solution\r\n    builder.prepare(listVariable, items);\r\n    return builder.build();\r\n  }\r\n}\r\n```\r\nAs you can see, we mainly focus on the variable-related data. The solution-related lines being one at the beginning and two at the end.\r\n\r\nA problem with this implementation is that it requires a variable which, although it is not constrained for the type of `solution` and `Item`, should provide a `List<Item>`. This is the most economical way, where all the information come at hand in a well encoded manner. But if for instance you have one variable for each item, then it is not adapted. However, it can be easily extended by adding the corresponding constructor:\r\n```\r\n  public ItemSwapOperator(final SolutionBuilder<Solution> builder,\r\n                          final List<Variable<Solution, Item>> itemVariables) {\r\n    // we create the list variable which reuses the separated item variables, so\r\n    // we can get an aggregated List<Item> rather than each item separately.\r\n    this.listVariable = new VariableVariable<Solution, List<Item>> {\r\n      public List<Item> get(Solution solution) {\r\n        List<Item> items = new LinkedList<Item>();\r\n        for(Variable<Solution, Item> itemVariable : itemVariables) {\r\n          items.add(itemVariable.get(solution));\r\n        }\r\n        return items;\r\n      }\r\n    };\r\n    \r\n    // because the variable should be compatible with the builder, we create\r\n    // the builder which will be compatible with our own listVariable, and\r\n    // which reuses the original builder to actually build solutions.\r\n    this.builder = new SolutionBuilder<Solution> {\r\n      public Collection<Variable<Solution, ?>> getVariables() {\r\n        return Arrays.asList(listVariable);\r\n      }\r\n      \r\n      public <Value> void prepare(Variable<Solution, Value> variable, Value value) {\r\n        if (variable != listVariable) {\r\n          throw new IllegalArgumentException(variable + \" is not a managed variable.\");\r\n        } else if (! (value instanceof List)) {\r\n          throw new IllegalArgumentException(value + \" is not a list of items.\");\r\n        } else {\r\n          List<Item> items = (List<Item>) value;\r\n          for(int i = 0 ; i < items.size ; i++) {\r\n            Variable<Solution, Item> itemVariable = itemVariables.get(i);\r\n            Item item = items.get(i);\r\n            builder.prepare(itemVariable, item);\r\n          }\r\n        }\r\n      }\r\n      \r\n      public Solution build() {\r\n        builder.build();\r\n      }\r\n    };\r\n  }\r\n```\r\n\r\nNow, here we see that the `SolutionBuilder` could be exploited in operators, but at the same time it is not the best adaptation we can have: the operator requires not only the builder, but also the specific variable to use, which should be one of the variables of the builder. We could imagine to have a different interface which already enforce such alignment and probably reduce the number of arguments to one. So is it correct to consider that `SolutionBuilder` is relevant for the operator context, or is it just close enough to another, better, operator-specific concept? And more broadly, is it correct to consider that it is relevant out of the experiment context? I don't know, it is a matter of design. Moreover, we don't use the `SolutionEvaluator`, and I don't have a concrete example of operator in mind to exploit an evaluator, although we could imagine operators which exploit objective values to select the best way to build a mutant for instance. Still it would be reduced to having the right objective, not the evaluator itself (which is nothing more than a set of objectives).\r\n\r\n## Finally, where these concepts belongs to?\r\n\r\nSo in the absolute, it seems to me relevant to have the notions of variables and objectives in the core, while the builder and evaluator seems to me relevant too, but mainly from an experiment perspective (at least). Furthermore, if we introduce the objectives in the core, surely we will have to deal with sets of objectives (to deal with Pareto optimality), so what the evaluator actually provides, and thus having it in the experiment would make no sense because it is already there from the core. Similarly, having the variables in the core would lead to manage list of variables, which is part of the actual `SolutionBuilder`, while the part interesting for the experiments is the preparation/building methods.\r\n\r\nIn short, we could imagine to have in the core `Variable`, `Objective`, but also `SolutionEvaluator` and an extra `SolutionReader` (which focuses on the `getVariables()` that we initially have in `SolutionBuilder`), and add in the experiments the `SolutionBuilder` which focuses on the preparation+building of the solutions, possibly depending on/extending a `SolutionReader` (or whatever the name).\r\n\r\nTo conclude, there is still matter to discuss regarding the organization, but I think that I have shown the interest of the different concepts I have introduced so far."}}