Free cookie consent management tool by TermsFeed Policy Generator
wiki:Documentation/Howto/Implement a Basic Algorithm

Version 9 (modified by abeham, 4 years ago) (diff)

docs out of date

Please note that in HeuristicLab 3.3.16 the persistence layer has changed and some of this documentation has not been updated.

How to ... create a basic HeuristicLab algorithm

This guide should give you a very quick overview of how to create a simple algorithm in HeuristicLab.

Prerequisites

We assume that you have checked out and built (see how to download and build the sources) the HeuristicLab sources and followed the guide on how to create a HeuristicLab plugin.

A random algorithm

We will now implement an algorithm for HeuristicLab which does nothing more then just create a random number. To give you an overview of how the structure of the algorithm should look like, have a look at the operator graph of the algorithm:

RandomCreator is the initial operator which gets executed (therefore the green color). The RandomCreator creates a random number generator. It can be configured to have a fixed seed as well as the type of the random number generator. The second operator is the VariableCreator which can be parameterized to create variables. In this case one variable (ResultValue) is configured to be created. The UniformRandomizer will later save it's result into this variable. UniformRandomizer samples random numbers between Min and Max with the random number generator created by RandomCreator. The last operator is the ResultsCollector which collects the value of our ResultValue. This value can then be viewed in HeuristicLab Optimizer in the results tab.

It is often a good idea to model algorithms first graphically in HeuristicLab because it is easier and allows for more flexibility when playing around with different ideas. You can find the HL file for this graphically modeled algorithm in the attachment section of this page. Have a look at the Operator Graph view and you will find the operator graph from the screenshot above. You can now simply click the Play button and it will give you a random number in the Results tab.

Implementation

Because we want to roughly create the same algorithm now in code, we create a new class in your HeuristicLab plugin and call it RandomAlgorithm. Before we can actually implement our algorithm, we have to first add references to some plugins that we need. Add the following references (just as you added the reference to Plugin Infrastructure):

  • HeuristicLab.Collections-3.3
  • HeuristicLab.Common-3.3
  • HeuristicLab.Core-3.3
  • HeuristicLab.Data-3.3
  • HeuristicLab.Operators-3.3
  • HeuristicLab.Optimization-3.3
  • HeuristicLab.Optimization.Operators-3.3
  • HeuristicLab.Parameters-3.3
  • HeuristicLab.Persistence-3.3
  • HeuristicLab.Random-3.3

We also need to add these references to our Plugin.cs file to tell the Plugin Infrastructure which plugins we need:

[Plugin("HeuristicLab.Algorithms.MyAlgorithm", "1.0.0.0")]
[PluginFile("HeuristicLab.Algorithms.MyAlgorithm.dll", PluginFileType.Assembly)]
[PluginDependency("HeuristicLab.Collections", "3.3")]
[PluginDependency("HeuristicLab.Common", "3.3")]
[PluginDependency("HeuristicLab.Core", "3.3")]
[PluginDependency("HeuristicLab.Data", "3.3")]
[PluginDependency("HeuristicLab.Operators", "3.3")]
[PluginDependency("HeuristicLab.Optimization", "3.3")]
[PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
[PluginDependency("HeuristicLab.Random", "3.3")]
[PluginDependency("HeuristicLab.Parameters", "3.3")]
[PluginDependency("HeuristicLab.Persistence", "3.3")]
public class MyAlgorithmPlugin : PluginBase {
}

Now we can start implementing the algorithm. The first thing that we do is inherit RandomAlgorithm from EngineAlgorithm. There are various base classes for different types of algorithms, e.g. there is a special type for heuristic algorithms. As we are not writing a new meta-heuristic, EngineAlgorithm should be sufficient. We also add two attributes to our class: The Item attribute contains some meta information about our algorithm, the Creatable attribute is the category of the class we are writing. This attribute is later responsible that we see our algorithm in the File->New dialog in HL. Here is the code so far:

[Item("RandomAlgorithm", "A algorithm which generates random numbers.")]
[Creatable("Algorithms")]
public sealed class RandomAlgorithm : EngineAlgorithm { 
    private RandomAlgorithm(RandomAlgorithm original, Cloner cloner)
      : base(original, cloner) {
    }
    public override IDeepCloneable Clone(Cloner cloner) {
      return new RandomAlgorithm(this, cloner);
    }
  
    public RandomAlgorithm() : base() {
  
    }
}

You can see that we have also added a default constructor as well as two methods needed for the HL cloning mechanism. As we don't have any properties that need cloning the CloningConstructor is empty. We will start now to construct the algorithms operator graph by extending the constructor:

 public RandomAlgorithm()
      : base() {
  RandomCreator randomCreator = new RandomCreator();
  VariableCreator variableCreator = new VariableCreator();
  UniformRandomizer uniformRandomizer = new UniformRandomizer();
  ResultsCollector resultsCollector = new ResultsCollector();

  //build the operator graph
  OperatorGraph.InitialOperator = randomCreator;
  randomCreator.Successor = variableCreator;
  variableCreator.Successor = uniformRandomizer;
  uniformRandomizer.Successor = resultsCollector;
}

In the first few lines we initialize the operators which are the same as the ones from the picture above. We then define that the initial operator is the RandomCreator and chain the operators by assigning the Successor property. In the next step we need to tell the variable creator which variable of which type it should create and the result collector that this variable is a result and should be collected:

//configure variableCreator
variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("Value", new DoubleValue(0.0)));

//configure result collector
resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Value"));

The name for our variable is now Value as the UniformRandomizer saves its result by default in this variable and therefore we simply use this default name. What is still missing and what would be nice is a way for the user to configure our algorithm in the Parameters tab in the HL Optimizer. This can be done by adding parameters to the parameter collection:

Parameters.Add(new ValueParameter<DoubleValue>("Max", "The upper bound for the generated number. ", new DoubleValue(100.0)));
Parameters.Add(new ValueParameter<DoubleValue>("Min", "The lower bound for the generated number. ", new DoubleValue(0.0)));

The 2 parameters we add here are so called ValueParameters. This are parameters which contain a value, in contrast to a LookUpParameter, which has no value but looks up values of e.g. ValueParameters. We call these 2 parameters Min and Max, as the UniformRandomizer looks for theses two parameters and uses them as the lower and upper bound for generating random numbers. We also initialize them with default values which the user will later be able to edit in HeuristicLab. An that's all we need to do for our RandomAlgorithm. You can now compile and start HeuristicLab. When you click on File->New, you should now see the algorithm in the dialog:

On the Parameters page you can now edit the Min and Max parameter values:

And if you click on run, you can view the result on the Results tab page:

You can find the source file of the algorithm in the attachments section of this page.

Attachments (6)

Download all attachments as: .zip