Skip to content

Commit

Permalink
Doc changes.
Browse files Browse the repository at this point in the history
- A couple of minor typos fixed and other very minor changes in the docs
  explaining EAs.
  • Loading branch information
gialmisi committed Nov 26, 2024
1 parent 898284b commit 72f01d5
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions docs/explanation/templates_and_pub_sub.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Finally, we discuss how the Publish-Subscribe pattern can be used to improve the

## EA Components

In DESDEO, the components of an EA are implemented as classes with equivalent components sharing the same interface. As we will see later in Section [Publisher-Subscriber Pattern](#Publisher-Subscriber-Pattern), all components are implemented as subclasses to the Subscriber class. However, for now, we will describe the structure of a typical EA component in a more general way.
In DESDEO, the components of an EA are implemented as classes with equivalent components sharing the same interface. As we will see later in Section [Publish-Subscribe Pattern](#Publish-Subscribe-Pattern), all components are implemented as subclasses to the Subscriber class. However, for now, we will describe the structure of a typical EA component in a more general way.

In general, an EA component has needs two main methods:
In general, an EA component has two main methods:

1. Component initializer: This method initializes the component with the necessary parameters. For example, the initializer of a crossover operator would take the probability of crossover as a parameter. The initializer should accept user provided hyperparameters and set the default values for the rest. The default `__init__` method of the class is used for this purpose. The function signature of the initializer of each component may be different (even for components of the same type).

Expand Down Expand Up @@ -43,10 +43,10 @@ def template(
return EMOResult(solutions=solutions, outputs=outputs)
```

The template takes care of the general order in which the components are executed. Note that the template itself makes no assumptions about the exact nature of the components, or that of the problem. The same template can be used for continuous, discrete, or mixed-integer optimization problems, as long as the components are implemented correctly.
The template takes care of the general order in which the components are executed. Note that the template itself makes no assumptions about the exact nature of the components, or that of the problem. The same template can be used for continuous, discrete, or mixed-integer optimization problems, as long as the components are implemented correctly and they support the specific problem type.
The initialization of the components is done outside the template, and this step can be used to make sure that the components actually support the problem at hand.

The template also provides a basic pathway for the flow of information between components. In the example above, the outputs of the mutation operator are passed to the evaluator, and the outputs of the evaluator are passed to the selection operator. This is only possible because the components of the same type have the same signature for the execution method. However, this approach has a few shortcoming. In reality, different operators of the same kind may require different information. For example, there may be self-adaptive operators that take previous populations, or the expended budget of optimization as inputs. In general, it is not possible to predict the exact information that each operator may require. Changing the signature of the execution method of each component to accommodate all possible information is not a good idea, as it would make the components less modular, and the templates less reusable. In the next section, we discuss how the Publish-Subscribe pattern can be used to improve the flow of information between components.
The template also provides a basic pathway for the flow of information between components. In the example above, the outputs of the mutation operator are passed to the evaluator, and the outputs of the evaluator are passed to the selection operator. This is only possible because the components of the same type have the same signature for the execution method. However, this approach has a few shortcomings. In reality, different operators of the same kind may require different information. For example, there may be self-adaptive operators that take previous populations, or the expended budget of optimization as inputs. In general, it is not possible to predict the exact information that each operator may require. Changing the signature of the execution method of each component to accommodate all possible information is not a good idea, as it would make the components less modular, and the templates less reusable. In the next section, we discuss how the Publish-Subscribe pattern can be used to improve the flow of information between components.

## Publish-Subscribe Pattern

Expand All @@ -66,7 +66,7 @@ To enable this pattern, each component must implement the `Subscriber` class. Th

4. Method `update`: This method is used to receive messages from the Publisher. The method should accept a list of `Message` objects. Based on the content of the messages, the component can update its internal state.

Note that the template itself does not need to be modified to accommodate the Publish-Subscribe pattern. In fact, the template does not invoke the publisher at all. Sending messages to the publisher (and therefore, the publisher sending the messages to other components) is done by interrupting the control flow of the template. However, the users of DESDEO, or even the developers of DESDEO do not need to worry about this as most of the heavy lifting is done by the Publisher and the Subscribers base classes. As long as the components are implemented correctly, with the information provided as stated above, the Publish-Subscribe pattern should work seamlessly.
Note that the template itself does not need to be modified to accommodate the Publish-Subscribe pattern. In fact, the template does not invoke the publisher at all. Sending messages to the publisher (and therefore, the publisher sending the messages to other components) is done by interrupting the control flow of the template. However, the users of DESDEO, or even the developers of DESDEO do not need to worry about this as most of the heavy lifting is done by the Publisher and the Subscriber base classes. As long as the components are implemented correctly, with the information provided as stated above, the Publish-Subscribe pattern should work seamlessly.

Note that another benefit of using the Publish-Subscribe pattern for the flow of information is that we are not limited to only using the components needed by the template. Additional components, such as archiving or visualization components can be registered to the publisher, and can receive messages from the other components. These components will work as expected even though the template itself does not invoke them. This allows for a more flexible and modular approach to implementing EAs in DESDEO.

Expand Down

0 comments on commit 72f01d5

Please sign in to comment.