onclave / NSGA-II

an implementation of NSGA-II in java
MIT License
43 stars 22 forks source link

Require more info on how to add more objective functions and also implementing fitness func #10

Closed RJoshlan closed 3 years ago

RJoshlan commented 3 years ago

Can you provide more information on how to provide my own objective function and fitness function. I read the content on get started doc but can you make it more clear or give an example to explain it further as i was struggling to understand when trying to extend AbstractObjectiveFunction class to implement the functions? I want to add fitness function to maximise relevance and minimise redundancy when performing feature selection using NSGA2 on a dataset.

onclave commented 3 years ago

For understanding how to add your own objective functions, see this section of Getting Started.

You may add as many objective functions as you want. The library will use all of them while comparing chromosomes. However, the library shall give no graphical graph plot output if the number of objectives is more than 2, since currently the library can plot only 2D graphs. I have no intention to add higher dimensional graph plots as of now. Pull requests are always welcome if you intend to do so.

All your objective functions should have their own class and must extend the AbstractObjectiveFunction class and override the getValue(Chromosome) method. It returns a double value. Provide your objective calculations here. Since every objective function depends on the chromosome they are working with, the getValue() method takes a Chromosome object. At runtime, the algorithm shall call these objective functions by their getValue() method with the appropriate chromosomes as and when required. All you need to do is provide the objective function calculation.

Take a look at the predefined objective function classes in the com.debacharya.nsgaii.objectivefunction package to understand how to implement your own objective functions. Consider them as examples.

You can also take a look at a forked version of this repository by another user to see how they have implemented their complex objective functions in a similar way.

Once done, add all your objective functions to a list of AbstractObjectiveFunction and pass it to a Configuration object. Finally, pass this configuration object to your NSGA2 object. Again. all this is detailed in this section of Getting Started.


About your query on fitness function, the NSGA2 algorithm does not have any explicit fitness function / fitness calculator. It is implicitly embedded into the algorithm in the form of diversity preservation via. crowding distance assignment, non-dominated sorting (to some extent), density estimation and the crowded-comparison operator. Hence, I am not really sure what you mean by having your own fitness function. NSGA2 does not select chromosomes based on any externally provided fitness function. All it requires are your objective functions.

However, in case you may need to perform any extra computation on the chromosome during the initial parent population creation or during each objective function calculation, you can provide your own implementation of the FitnessCalculator interface in your implementation of the PopulationProducer and / or in the overloaded constructor of AbstractObjectiveFunction class, i.e., all your objective functions can take a FitnessCalculator instance and you have access to it within your getValue() method.

The FitnessCalculator interface has only one method, calculate(Chromosome), that takes a chromosome and returns a double, so you can perform any computation required on the chromosome.

Take a look here as an example on how you can implement your own FitnessCalculator.