This section gives an overview over guidelines to create own operators. Note that most of the information given here is only required if you would like to use your operators in the GUI.
No software tool can provide all operators that may be used in evolutionary algorithms. The Evolvica core library
already contains some, but there most likely the need to implement user-defined operators. The design of the core
library was carefully done to fit this requirement. Although the creation of operators is normally reduced to
implementing one single method there are some rules to follow if a user may wish to view and use his operators
in the GUI.
The design of the operators in Evolvica follows Sun's
JavaBeans Component Architecture with some
small extensions. Therefore some knowledge about JavaBeans is required although the main facts are discussed in this
section.
All information about a genetic operator is held in a descriptor. The appropriate descriptor class is org.evolvica.engine.OperatorDescriptor. Each genetic operator has an assigned descriptor which can be retrieved via the method descriptor(). The descriptor itself extends java.beans.BeanDescriptor and add some methods related to algorithms. These methods provide read/write access to information about an operator, like vendor, name, input- and outputsize, datatype and so on. Information can be set via an appropriate set-method. Please consult the API documentation to find out which information can be set in a descriptor.
A property is simply an attribute of an operator. For instance the mutation propability is an attribute of
a mutator.
There are attributes that are common all genetic operator while other attributes are specific to certain
operator classes (i.e. the already mentioned mutation propability).
There are three properties that are essentially important for operators in algorithms: the inputsize, the
outputsize and the datatype. The input- and outputsize (or together: the interface) property shows how
many inputs and outputs an operator has. For a mutator the interface is (1,1) - that means 1 input and 1 output.
For a router the interface is (1,2) - 1 input, 2 outputs. The input- and outputsize can be set in an operator
via descriptor().setInputSize( int ) and descriptor().setOutputSize( int ). If you derive your
operator from one of the provided base classes (AbstractSelector, AbstractMutator and so on) you don't have
to set the interface manually, this is already done. But if you plan to create an own operator from scratch
you will have to to this.
Each operator always works with a certain datatype. It does not make any sense to try to apply a float
mutator on a binary string. The datatype an operator is designed for must be set in the descriptor. The
method call is descriptor().setDatatype( IDatatype ). An instance of IDatatype can be retrieved from
org.evolvica.core.GenotypeRepository. In case your operator is independent from a certain datatype
(like a duplicator or a router) use org.evolvica.engine.IDatatype.UniversalDatatype.