= Documentation not up-to-date = {{{ #!html
As of HeuristicLab 3.3.11 configuring the ExternalEvaluationProblem has been made considerably easier. This is not yet reflected in this documentation. Please refer to this article for a more up-to-date documentation.
}}} [[PageOutline]] = How to ... optimize external applications = Sometimes it is not possible to directly write a new problem for HeuristicLab and integrate it through the plugin system. Some people already have an application of which at least a part represents a NP hard problem that they'd like to solve. This guide explains how to use the `ExternalEvaluationProblem` that is available in HeuristicLab 3.3 to optimize problems written in a language other than C# or written using different frameworks, to name just a few possibilities. First the architecture is described, then a more detailed look into the API is given and finally a short tutorial should give the reader an idea of how to apply this to his/her case. The most important part in any optimization problem is the evaluation function. Without knowing about the quality of a certain solution configuration the algorithm is not able to come close to an optimal solution. In NP hard problems evaluating a solution is usually a rather simple task, whereas finding the best solution is extremely difficult. Of course there can be complex problems which require high computational effort to calculate the quality of a solution, but in many cases the evaluation of a solution is rather straight forward. So, if the problem is not a HeuristicLab plugin we assume that it is available in another kind of executable format, either in an application itself or as part of another framework for example. We thus have a situation where we need inter-process communication (IPC). There are several possibilities of how to do IPC, in the following we will explain the approach we offer in HeuristicLab 3.3. == Architecture Overview == === Technology & Background === Recently [http://www.google.com Google], released parts of their core RPC technologies to the general public. The framework that they call [http://code.google.com/p/protobuf/ Protocol Buffers] combines a domain specific language (DSL) for describing messages within an RPC framework that is used to pass these messages among different servers. The RPC framework itself is not released, but the DSL for describing messages and translating them to objects of several supported programming languages was released under the BSD license. Google directly supports C++, Java, and Python, but many developers have programmed ports of protocol buffers to different languages such as C#, Visual Basic, Objective C, Perl, Haskell, and [http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns many more]. The [http://code.google.com/apis/protocolbuffers/docs/overview.html documentation] on protocol buffers is extremely helpful in understanding the framework. Protocol buffers provide convenient ways to define messages, manipulate them, and serialize them to small sizes at high speeds. In HeuristicLab using remote procedure calls seems to fit very well with what we are trying to achieve in "exporting" the problem definition. The problem, to an optimizer, is basically the evaluation function and the solution representation is their common knowledge. A client is provided in HeuristicLab as well as a framework that enables developers to write a service which exposes the evaluation function to HeuristicLab. Using this service foreign language applications and problems can effectively communicate with HeuristicLab and have their parameters optimized by HeuristicLab's powerful optimization library. Communication also requires a given media over which to exchange the information and the preferred choice in HeuristicLab is to communicate via the TCP/IP network: The external program is started independently from HeuristicLab and opens a TCP/IP port for communicating over a network. Regardless of the chosen media, the solution receiving and quality sending processes are abstracted from the developer through our service framework. For writing services, generally two types of services are supported by our framework: Push Service and Poll Service. Generally, the poll service is a simple to use solution that should fit most needs. The implementation of these service frameworks are attached to the end of this page and are available in Java and in C# in binary as well as source code: * Download the [[attachment:HL3ExternalEvaluation.jar|Java JAR library]] (binary) * Download the [[attachment:HL3ExternalEvaluationCSharp.zip|C# library]] (binary) * Download the [[attachment:HeuristicLab.Problems.ExternalEvaluation (src).zip|Source code]] - useful for understanding how to use the library === Application Scenarios === One of the application scenarios that we had in mind when designing this interface is the field of simulation-based optimization. There, a simulation model defines a number of parameters which need to be adjusted such that a measured output of the model improves. This can be inventory sizes in a supply-chain scenario, or similarly buffer sizes in an assembly line, or training the weights in a neural network simulator. There are numerous optimization problems that are implemented as simulation models and one of the main problems is talking to them. Many different frameworks exist with which one can conveniently build, run, and test a simulation model, and most of them already have some support for optimization. However that support often is of proprietary nature and little information is available on how these methods perform. HeuristicLab aims to provide an open source alternative and the means of this interface allows simulation experts to use HeuristicLab in the optimization tasks. Naturally, there exist several more reasons why a problem cannot be modeled in HeuristicLab, such as language or platform dependency and for these purposes this interface should provide a solution. == Architecture Details == Optimizing external applications divides into two parts: 1. Providing an evaluation service for HeuristicLab in the external application 2. Preparing an `ExternalEvaluationProblem` in HeuristicLab These two tasks are described in this section in more detail. === Providing an evaluation service === Attached to this wiki page you can find a java library that enables a quick connection with HeuristicLab over a TCP/IP connection. In this library there is an abstract base class `Channel` on the one hand which provides methods for sending and receiving messages and several concrete implementations and on the other hand an abstract base class `Service` that provides the concrete `PollService` and `PushService`. A `Listener` listens for connections and opens several channels out of which the service will receive solutions and send back qualities. As a user of the library you will prepare an `IListenerFactory` and hand this to your service instance. Then, depending on the type of service, you can get solutions out of it and push the qualities back. It is quite easy. Similarly a C# port of this library has also been added, which is handy when your application cannot be compiled to a dll and called directly from your C# problem plugin. In the following code sample you may find some test applications that provide very simple examples of how to use the service framework. They do not really evaluate a solution, but return a random number in the interval [0;1) for every received solution. ==== Usage examples ==== Here is the java code for the `RandomSocketPollEvaluator` {{{#!java public static void main(String[] args) { ServerSocketListenerFactory factory = new ServerSocketListenerFactory(8842); PollService service = new PollService(factory, 1); service.start(); Random random = new Random(); while (true) { SolutionMessage msg = service.getSolution(); double quality = 0; // replace the line below to quality the quality quality = random.nextDouble(); // for the simple purpose here it's just a random number try { service.sendQuality(msg, quality); } catch (IOException e) { e.printStackTrace(); } } } }}} This code shows a concrete example of how to use the !PollService and the ease of integrating this into an external java application. As of July 2012 you can also extend the quality message with own fields and transmit them back to HeuristicLab. If you provide a simple plugin with your own evaluator you may further process this information inside HeuristicLab, e.g. through an Analyzer that includes these in the results. The source code contains a simple plugin with an extended protocol buffer message that would add a repetition field to return the number of repetitions that have been performed. This is just for demo purposes, you can use add any number of extensions that you like. === Preparing an `ExternalEvaluationProblem` === In the HeuristicLab Optimizer a number of algorithms and problems are available which can be created, viewed and parameterized. A problem in HeuristicLab consists of several parameters whose values describe the problem instance, but also consists of several operators. The two most important operators are the //Evaluator// which is used to evaluate a solution and the //SolutionCreator// which is used to create new solution configurations from scratch. Although solutions are usually created randomly, for some problem one might use certain heuristics and start with partly optimal solutions. Finally every problem also contains an //operator list// of operators that are known to work with the problem's solution representations. This list is usually hidden in many problems as the list is populated all by itself by discovering all operators that implement a certain interface for example. Among these problems, there is a special problem designed for the purpose of calling an external evaluation function called `ExternalEvaluationProblem`. The problem allows the user to define a customized solution representation, as well as configure the operator list with operators that are available to solve the problem. The following screenshot shows the default parameters of this problem. [[Image(ExternalEvaluationProblemParameters.png)]] The list of parameters that are available there are briefly described: * '''!BestKnownQuality''' - Displays the best known quality of the problem, this is updated through a special analyzer. * '''!BestKnownSolution''' - Houses the best known solution so far, that is the scope that contains the solution representation * '''Client''' - The client that transmits the solution to the external application. The user configures the client by defining the appropriate channel and channel connection information. * '''Evaluator''' - The evaluator is an operator that collects variables from the scope and includes them in a message which will be sent to the external application. The user has to configure the evaluator such that it can find the variables to collect. * '''Maximization''' - Is necessary for the algorithm to know whether it should minimize or maximize the quality value. * '''Operators''' - Contains a list of operators that the problem provides to the algorithm. In this list any Crossover, Manipulation or other operator will be passed to the algorithm and will be made selectable there. * '''!SolutionCreator''' - Is an operator that creates a solution. This operator can also be adjusted by the user as needed. One can use the included representation generators in the !HeuristicLab.Encodings namespace, or use own generators from an own plugin. In the tutorial section it will be shown how to configure these parameters to solve a real problem. For completeness reasons a class diagram of the !HeuristicLab.Problems.!ExternalEvaluation namespace shall also be given. The interaction of the classes shall be explained and the operators described. [[Image(ExternalEvaluationCD.png)]] The equivalent to the channels in the java service framework are implemented also in C# for use in HeuristicLab. There is an Interface //IEvaluationChannel// that defines a channel. As can be seen from the class diagram the methods that each channel has to provide are exactly the same as in the java service framework. Basically a channel can be //opened// and //closed// and there are two functions for //sending// and //receiving//. In HeuristicLab however there exists a third channel, the `EvaluationProcessChannel`, that provides a convenience wrapper around an `EvaluationStreamChannel` that is attached to the stdin and stdout streams of a process started from HeuristicLab. Also shown in the class diagram are a number of converters that are used to convert HeuristicLab data types, such as the variables that contain the solution representation, to a `SolutionMessage`. The `SolutionMessageBuilder` is the class that contains a number of converters and allows the `ExternalEvaluator` to construct the message. Which converter shall be used can be configured in the GUI when creating the `ExternalEvaluationProblem` and the converters are naturally extensible. A user can define an own converter implementing `IItemToSolutionMessageConverter` and add it to the `SolutionMessageBuilder` in the GUI. By default the `SolutionMessageBuilder` is configured with all the converters that can be seen which in turn cover all the data types in the !HeuristicLab.Data namespace. The solution representations in !HeuristicLab.Encodings are derived from those, so the converters also cover them too. But any solution representation not derived directly from one of the objects in !HeuristicLab.Data naturally requires an own converter (e.g. !HeuristicLab.Encodings.!SymbolicExpressionTree is such a type). Next in the class diagram is the `EvaluationServiceClient` which holds a Channel and allows the `ExternalEvaluator` to communicate with the remote process. Finally, there is a class that describes the `ExternalEvaluationPRoblem` itself, as well as the `QualityMessage` (the expected answer from the service) and the `SolutionMessage`. These two are automatically created by parsing the !ExternalEvaluationMessages.proto file with the compiler tools of Google's protocol buffer framework. [=#Tutorial] == Tutorial == In this tutorial we're going to connect the HeuristicLab 3.3 Optimizer with the Race Car Setup Optimization Competition that was organized for the !EvoStar 2010 conference. Unfortunately the submission is already closed for this year, but let's hope there will be another competition hopefully in 2011. The problem is a classic "simulation-based optimization problem" so there is a simulator, a simulation model, and several configuration parameters that have to be optimized. Additionally there might or might not be noise present in the evaluation of a configuration. More concretely the simulator is called [http://torcs.sourceforge.net/ TORCS], the simulation model consists of a certain simulated driver that tries to race as fast as possible and the configuration parameters are various settings of the race car that can be tuned. The challenging part in this problem is the limitation of the number of simulation time. Each optimizing run is given a certain number of simulation time in which the best parameter has to be found. Each solution is evaluated with a certain slice of that simulation time. It is possible to choose the size of this slice such that one evaluates a shorter time, with more noise on the quality values, but with a bigger number of possible evaluated solutions or a longer time with less noise, but the algorithm can calculate fewer generations. The driver in the simulation model starts where it left off after the last configuration, so there is some noise that depends on the driver's position on the track and some that depends on the previous configuration, which could have sent the driver off the track. To prepare for this tutorial there's a couple of things that we need to obtain. 1. Download the simulator TORCS from http://torcs.sourceforge.net/ 2. Download the Windows Server, Java Client and the manual from http://cig.dei.polimi.it/?page_id=103 3. Follow the instructions in the excellent manual that you just downloaded to learn more about the problem situation and how to perform the setup Once you're done, you should get a latest copy of HeuristicLab 3.3 and unzip it into a folder or [DevelopersManual#BuildSources build it from source] using Visual Studio. We're now going to configure the problem in HeuristicLab and then take a look at the client and finally let it run. === Configuring the Race Car Configuration Problem in HeuristicLab === In the Optimizer we select New from the File menu and choose the '''External Evaluation Problem''' from the list of //Creatables// among which we find the section //Problems//. You may have to scroll down a little until you reach the Problems. [[Image(Tutorial_CreateNewExternalEvaluationProblem.png)]] Now we are presented with a new External Evaluation Problem such as we have seen in the architecture description above. It shall be shown here again. [[Image(ExternalEvaluationProblemParameters.png)]] So, first let's give the problem a proper name and a proper description so that when we load the problem later we know what this is all about. * In the title type "Race Car Configuration Problem (!EvoStar 2010)" * In the description type "Problem that represents race car configuration challenge of !EvoStar 2010" Now we want to configure the solution representation and for this purpose we click the operator called '''!SolutionCreator''' and get following screen. [[Image(Tutorial_ConfigureSolutionCreator.png)]] We can examine the operators parameters by selecting the "Parameters" tab, and we will see that there is only a "Successor" parameter defined which is null. This parameter defines the next operator that would be executed after the !SolutionCreator, but we don't need to bother with this parameter in this case and switch back to the "Operators" tab. There is a button with a yellow plus icon that we're going to press. [[Image(Tutorial_TypeSelector.png)]] The type selector appears that has the ability to show every HeuristicLab object, but in this case, because the !SolutionCreator exposes a list of only `IOperator`s we see a dialog with only operators to choose from. We're interested in creating our solution representation and given that our simulation model expects a vector of real values that describe the car's configuration, we will look into the '''HeuristicLab.Encodings.!RealVectorEncoding''' namespace. Click on the "+" infront of that namespace to list all the available operators there. [[Image(Tutorial_TypeSelector_RealVectorEncoding.png)]] That is quite a list of operators, but don't get confused. From the names we can see what they are doing, there are several crossovers, manipulators, and a few other operators. Each of these operators has a description that you can see when you click onto it. The description is very helpful in describing what the operator does and there are even references to publications for operators that are taken from the literature. The one operator we are looking for to create a vector of real values is the '''!UniformRandomRealVectorCreator'''. Look for it in the list down the bottom and click OK. [[Image(Tutorial_UniformRandomRealVectorCreator.png)]] Views are usually nested in each other and when you click on the operator you should see its view opening to the right. If you can't see the operator's details due to low screen resolution you can double click the operator and it will open in a completely new view and in a new tab next to the tab of the problem. What we have to do next is configure this operator. We see in the operators details that it has five parameters: Bounds, Length, Random, !RealVector, and Successor. Like before we can ignore the Successor parameter, but the other 4 are interesting to us. You can click on any of these parameters to get a helpful description in the parameter's own view (which is nested again), you can also double click a parameter to open a view in a new tab. The Bounds parameter tells us that it represents "A 2 column matrix specifying the lower and upper bound for each dimension. If there are less rows than dimension the bounds vector is cycled." This is very helpful information indeed! We know, from reading the challenge's manual that the solution vector is bound in every dimension by 0 and 1 and now we have two choices. We could now click on the button with the pencil icon and create a new Bounds matrix directly in the parameter of this operator or we can set the //Actual Name// of this parameter to the name of the parameter that we create in a higher level. If we'd create the parameter directly in the parameter, other operators do not have access to it and because the Bounds are also needed in other operators like Crossover and Mutation it is a better idea to create the bounds matrix at the problem level. So we click the yellow plus icon in the parameters list of our problem (marked in the following screenshot). If you have opened the operator in a new tab, switch to the tab of our problem (it starts with "Race Car Configuration..."). [[Image(Tutorial_CreateBounds.png, width=1000)]] Again we see a dialog similar to the type selector. [[Image(Tutorial_TypeSelector_NewParameter.png)]] This time it is restricted to all kinds of `IParameter`s of which there are some in the !HeuristicLab.Parameters namespace. There are several kinds of parameters of which there are two important types: 1. Lookup parameters 2. Value parameters Lookup parameters do not have a value of their own, but rather search for this value in a higher scope. Value parameters on the other hand contain a value of their own and do not look for the value in a higher scope. The combination of the two is a !ValueLookupParameter that either has a value in which case it will not look in a higher scope or it does not have a value in which case it will look in a higher scope. So it's the best of the two worlds. Usually when a parameter can be either set directly or looked up a !ValueLookupParameter is well suited. The Bounds parameter for example of the solution creator is such a parameter. In this case however, we're at the problem scope and there's no higher scope so what we need is a new '''!ValueParameter