Let’s say you have an external problem (in C/C++) that plugs in to the MOEAframework. This post covers how to calculate constraints and pass them back and forth from the C/C++ program to the Java code. First we’ll show the two code examples and then we’ll explain some of the details of the calculations.

Class definition in the java script:

public static class myProblem extends ExternalProblem { public myProblem() throws IOException{ super("./myPath/myCPPExecutable"); } @Override public String getName() { return "myProblem"; } @Override public int getNumberOfVariables(){ return 5; } @Override public int getNumberOfObjectives(){ return 6; } @Override public int getNumberOfConstraints(){ return 3; } @Override public Solution newSolution(){ Solution solution = new Solution( getNumberOfVariables(), getNumberOfObjectives(), getNumberOfConstraints() ); for (int i = 0; i < getNumberOfVariables(); i++) { solution.setVariable(i, new RealVariable(0.0, 1.0)); } return solution; } }

As you can see, the Java excerpt is not really any different than the traditional example, other than that the number of constraints is nonzero. In the C++ code, one must actually give some values to the MOEA, which represents the constraint **violations **of each solution. The constraints are such that **any nonzero value is considered a constraint violation,**** whereas feasible solutions have constraint violation = 0. **The below example shows how to calculate constraints for three objectives, named objectiveA, objectiveB, and objectiveC. The constraints are of type “greater than”, “less than”, and “equal”, respectively. The example treats all constraint violations as negative, but it is also OK to have the constraint violations positive, as long as they are nonzero.

Note: The above paragraph was edited 14 August 2012, with a small fix made. The way it was written originally was not wrong, we just clarified it a bit.

#include <stdio.h> #include <stdlib.h> #include <math.h> #include "moeaframework.h" int nvars = 5; int nobjs = 6; int nconstrs = 3; //define the number of constraints here void evaluate (double *vars, double *objs, double *constrs) { //a generic function to calculate objective functions objs = myObjFun(vars); //let's say you want to constrain the first three objectives to be above, below //or equal to a given level. Pull out the values of the objectives: double objA = objs[0]; double objB = objs[1]; double objC = objs[2]; //Set the desired level of the objectives: double levelA = 0.98; double levelB = 1.1; double levelC = 0.0; //Now calculate the constraint violations. //The 0th constraint is a greater than or equal to constraint on objA constrs[0] = objA / levelA - 1.0; //The 1st constraint is less than or equal to on objB constrs[1] = 1.0 - objB / levelB; //The 2nd constraint is an equality constraint on level C if (objC == levelC) constrs[2] = 0.0; else constrs[2] = -1.0*abs( (levelC - objC) / levelC ); for (int i = 0; i < nconstrs; i++) { if (constrs[i] > 0.0) constrs[i] = 0.0; } return; } int main (int argc, char* argv[]) { double vars[nvars]; double objs[nobjs]; double constrs[nconstrs]; MOEA_Init(nobjs, nconstrs); //the second argument here is the number of constraints while (MOEA_Next_solution() == MOEA_SUCCESS) { MOEA_Read_doubles(nvars, vars); evaluate(vars, objs, constrs); MOEA_Write(objs, constrs); } MOEA_Terminate(); return EXIT_SUCCESS; }

So the constraint array is very similar to the objectives, but it has negative values when solutions are infeasible, and zero otherwise. Let us know if you have any questions!

So, in other words the framework handles constraints by treating them as objectives?

No, that’s not the case. There’s documentation on the website about constraint handling; basically a feasible solution will always dominate an infeasible solution, and then if all solutions are infeasible, solutions with the lowest constraint violation survive. Thanks for your question!

Pingback: Water Programming Blog Guide (Part I) – Water Programming: A Collaborative Research Blog