MOEAFramework Training Part 1: Connecting an External Problem

The goal of this training is to step a user through becoming familiar with the capabilities of MOEAFramework, a free and open source Java library created by Dave Hadka, that allows the user to design, execute, and test out a variety of popular multi-objective evolutionary algorithms (MOEAs). In this series, we will demonstrate the capabilities of MOEAFramework in 4 parts. Part 1 demonstrates how to hook up an external optimization problem to MOEAFramework. Part 2 will cover the optimization of the problem using a variety of algorithms. Part 3 will illustrate how to calculate metrics to assess the performance of the algorithms. Finally, Part 4 will step through generation of relevant figures from the metrics that convey the effectiveness, efficiency, reliability, and controllability of the algorithms.

The example test case that will be used throughout this tutorial is the DPS version of the Lake Problem. The code is written and adapted by Dr. Julianne Quinn and can be found here. However, the tutorial will be set up so that the user can easily swap in their own problem formulation.

Finally, this guide is specifically built to connect an external problem that is written in C++ but Dave Hadka’s Beginner Guide to the MOEA Framework, has examples of how to create the Java executable for problems written in a language other than C++.

Connecting Your Problem

Before starting this training, it is recommended to set up a directory in a Linux environment with Java installed. If you are a student in Reed Research Group, create a folder in your Cube directory called “MOEA_Diagnostics_Tutorial”. Throughout the training, we will be adding various subdirectories and files to this folder. For this part of the tutorial, you will need the following in your directory:

  1. MOEAFramework Demo .jar file which can be found by clicking on “Demo Application” on the far right.
  2. The C++ version of the Lake Problem
  3. SOWs_Type6.txt (natural inflows read in by the .cpp file)
  4. moeaframework.c and moeaframework.h found here

Once you have the .cpp file, the next step is to get it set up to be recognized by MOEAFramework. I have made these changes in this file in my GitHub repo. If you compare with the file in 2, you will see some changes.

First, I have commented out all parts of the code related to Borg, which the problem was originally set up to be optimized with. For this tutorial, we will be optimizing with multiple algorithms and comparing their performance. Secondly, in lines 55-57, I have use the #define directive to declare the number of variables, objectives, and constraints to be constants. Lines 300-309 is where the direct connection to MOEAFramework comes in. MOEA_Init initializes the communication between C++ and MOEAFramework and takes the number of objectives and constraints as arguments. Then we can start reading and evaluating solutions. MOEA_Read_doubles extracts the decision variables and stores them in an array, vars. Line 304 calls the lake_problem function that we would like to evaluate, along with the variables, and constraints. This results in the objs array being filled. Finally, MOEA_Write writes the objectives back into the framework. When all solutions are done being read and written, MOEA_Terminate closes the connection. The important thing here is just to make sure that you are passing the names of the arguments of your lake_problem function correctly.

Next, we must make an executable of the C++ file that Java can read. The makefile is located here and takes lake.cpp, moeaframework.c, moeaframework.h, and some relevant libraries and compiles them into an executable called “lake”. In order to run this file, simply type “make”.

Finally, we must turn our executable into a java class. The relevant java file can be found here. This file can be found in the MOEAFramework documentation, but must be tailored to an external problem. Lines 21-25 import in the relevant tools from MOEAFramework that help to configure and solve the problem. Lines 40, 42, 43, and 48 show the first change from the original file. Here we insert the name of our executable that was generated in the last step, “lake”. In lines 53, 58, and 63, we state the number of decision variables, objectives, and constraints. Finally, in lines 67-75, we create a newSolution ( ) method to specify that our solution should have 6 real-valued decision variables between 0 and 1.

In order to create a class file, simply type:

 

javac -classpath MOEAFramework-2.12-Demo.jar lake.java 

 

A file called lake.class will be created.

The first part of training is done! Next time, we will set up some scripts, call these executables, and optimize the lake problem with a variety of different algorithms.

 

 

 

Speed up your Bash sessions with “alias”

Some of you probably already know about this, but I just discovered it and wanted to share.

Tired of typing in the same terminal commands all the time? Try this:

alias cy='ssh -Y jdh33@cyberstar.psu.edu'

Now when you type “cy” in the terminal, it automatically replaces it with the command you specify in quotes.

You can do this for each session, but even more helpful is to put these alias commands in your .bashrc file so that they are run whenever you start bash (the “rc” in “bashrc” stands for “run commands” … at least I think it does). If you’re using cygwin, this file will be located at C:\cygwin\home\(your username)\.bashrc. Open it in a text editor and put your alias commands somewhere in the middle. (On the cluster, your .bashrc file is located in your home directory, ~.)

Some useful possibilities:

  • On your computer, create aliases to log into different clusters (“cy” for cyberstar, “lx” for Lion-XO, etc.)
  • On the cluster, create aliases for common queue operations (“qme” for “qstat -u jdh33”, for example, which is a good idea I got from Ryan. Or “killall” for “qdel $(qselect -u jdh33)”. Pretty handy!)
  • Any long commands you find yourself repeating can be aliased! Just be careful not to overwrite any existing Linux commands when you do it.
You can check your current aliases at any time by running alias without any arguments.

That’s all, thanks for reading.

Programming Language Overview

This post details the programming languages commonly used in our group.  For each language, we have included installation instructions, suggested reading materials, and other notes.

C

Description Procedural
API Reference http://www.cplusplus.com/reference/clibrary/
Windows Installation MinGW (Blog post about installing this is here), Cygwin
Linux Installation sudo apt-get install gcc
Notes
  • Be cautious of string functions, many built-in C functions are unsafe
  • GNU GCC allows mixing Fortran and C/C++ object files (i.e., call Fortran method from C/C++)

C++

Description Object Oriented
Tutorial http://www.cplusplus.com/doc/tutorial/
API Reference http://www.cplusplus.com/reference/
Windows Installation MinGW (Blog post about installing this is here), Cygwin
Linux Installation sudo apt-get install g++
Notes
  • The Boost libraries contain many reusable components

Java

Description Object Oriented, Managed Memory
Tutorial http://docs.oracle.com/javase/tutorial/
API Reference http://docs.oracle.com/javase/6/docs/api/
Books Effective Java by Joshua Bloch
Windows Installation JDK 6
Linux Installation sudo apt-get install openjdk-6-jdk
Notes
  • Java is a verbose language, but the verbosity allows stronger type safety
  • Consider developing in Eclipse or NetBeans
  • Oracle recently released version 7, which is backwards-compatible with earlier versions

Python

Description Object Oriented, Functional, Managed Memory
Tutorial http://docs.python.org/tutorial/index.html
API Reference http://docs.python.org/
Books Dive into Python by Mark Pilgrim
Windows Installation Python 2.7.2
Linux Installation sudo apt-get install python
Notes
  • There are two major versions of Python, 2.7 and 3.2.  They share similarities, but are not compatible
  • Use easy_install to quickly install packages
  • Use matplotlib for Matlab-like plotting

The Ternary Operator

The ternary operator (the question mark and colon in the expression a ? b: c) is a tricky one.  It’s use is relatively uncommon, but it’s present in many programming languages, and sometimes it drastically simplifies a conditional assignment.  I bring it up because it was in the first version I saw of the GAA objective function, and it was doing something it shouldn’t have been.  Before I took up the GAA problem, some of the work involved allowing a 3 percent constraint violation.  This was still present in the objective function when I got my hands on it, although we no longer wanted to allow a 3 percent constraint violation.

Here’s what it looked like:


constr[0] = CV_TOTAL > 0.03 ? CV_TOTAL : 0.0;

What it does is assign CV_TOTAL to constr[0] only if CV_TOTAL is greater than 0.03, and otherwise it assigns 0 to constr[0].  It works this way because in general, the expression a ? b : c evaluates to b if a is true, and to c if a is false. So writing d = a ? b : c is a shorthand way of saying, “assign b to d if a is true, and assign c to d if a is false.”  And what it does in this case is allow 3% constraint violation.

My advice: there’s nothing wrong with using the ternary operator, but don’t be stingy with your comments.  Writing it like this could save you a lot of time:


constr[0] = CV_TOTAL > 0.03 ? CV_TOTAL : 0.0; // allow 3% constraint violation!

Of the  languages that I’ve used, the ternary operator shows up in this form in C, C++, Java, and Ruby.