Skip to content

Commit

Permalink
version 0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
drdwo committed Nov 7, 2020
0 parents commit 0ba45f1
Show file tree
Hide file tree
Showing 32 changed files with 6,863 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target/
92 changes: 92 additions & 0 deletions CTOC11.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
:encoding: utf-8
:imagesdir: img
:cpp: C++

== CTOC11

https://github.com/dietmarwo/fcmaes-java/blob/master/README.adoc[fcmaes-java]
was created for our participation at the 11th China Trajectory Optimization Competition
https://ctoc11.skyeststudio.com/[CTOC11].
No functionality was added to the Python optimization library https://github.com/dietmarwo/fast-cma-es[fcmaes]
but a JVM based implementation has advantages required by the competition:

* Fast objective function execution.
* Thread based parallelization works better on Windows than Python process based parallelization used by fcmaes.
* A space flight related utility implementation was available in Java.

The CTOC11 problem https://ctoc11.skyeststudio.com/uploadfiles/CTOC11problemdescription.pdf
involves the the computation of the trajectory of two different satellites to observe multiple
fixed and moving targets over a period of 240 days. The time interval between two adjacent impulses of each
satellite is required to be no less than 0.5 days. This means, if viewed as an optimization problem,
CTOC11 has up to 480 * 3 + 3 decision variables, three for the initial orbit (inclination, true anomaly and the
argument of the periapsis) and three for each impulse. Too much for a single optimization, so we optimized the
impulses successively. One of four available relay satellites had to be visited after
at most 30 target observations to transfer the data. We successively determined the impulses for each segment
between two relay visits and restricted us to two or three impulses for each segment. This means we have only
six or nine decision variables for each optimization.

== How to get a fast solution for CTOC11

The usual approach to this kind of problems is to use an approximation which is faster to compute, but
it is tricky to preserve the observations when transforming finally into the real model. We tried a different
idea:

* Speed up the integration using the given ODEs.
* Instead of an approximation we directly applied the ODEs to compute the final trajectory of the
satellites. Quite similar to the F8 example here
https://github.com/dietmarwo/fcmaes-java/blob/master/src/main/java/examples/F8.java[F8.java] .
https://github.com/dietmarwo/fcmaes-java/blob/master/cppsrc/ascent.cpp[ascent.cpp] shows how the
ODEs both for the F8 example and for CTOC11 are implemented based on the https://github.com/AnyarInc/Ascent[Ascent] library.
By executing the F8 example you can see how fast the Ascent based integration is. You may compare with the F8 results
given in http://www.midaco-solver.com/data/pub/The_Oracle_Penalty_Method.pdf[Oracle Penalty].

This simple approach is useful for prototyping, when you want to estimate what is possible. You get a result
very fast, for CTOC11 almost 80% of the optimum using only about 20% of the effort.

== How to apply fcmaes-java for CTOC11

The 240 days flight time for both satellites are divided in three different tasks with different targets and goals.
You need four different objective functions, one for the start and one for each task. Each objective function
propagates a satellite between two relay visits. One of the satellites has an optical sensor, the other an
infrared one. Since the optical satellite requires daylight it is more constrained. We chose to compute the
optical satellite first, so that the infrared can focus on the targets the optical didn't reach.

Dependent on the task we defined a number of objectives and used the weighted sum approach to map these objectives
to a single one. Objectives are:

* Fuel consumption.
* Number of visited targets.
* The preliminary score for the specific task.
* The time used.
* The minimal distance to the nearest relay for the flight path.
* Average height of the satellite.

No explicit "planning" of the relay visits, just a related objective. Minimization of this objective "steered" the
satellite to the next relay. To speed up the computation of this objective, we stored the possible positions of the
four relays in a big TreeMap. A similar table based approach was used to speed up the computation of the distance
to the nearest target.

The optimization was performed using one of the following three algorithms,
see https://github.com/dietmarwo/fcmaes-java/blob/master/src/main/java/fcmaes/core/Optimizers.java[Optimizers.java]
all implemented in C++ using the Eigen library:

* DE - a differential evolution variant by Dietmar Wolz https://github.com/dietmarwo/fcmaes-java/blob/master/cppsrc/deoptimizer.cpp[deoptimizer.cpp]
* GCLDE - a differential evolution variant by Mingcheng Zuo https://github.com/dietmarwo/fcmaes-java/blob/master/cppsrc/gcldeoptimizer.cpp[gcldeoptimizer.cpp]
* DANL - dual annealing without local optimization derived from the Scipy Python library code https://github.com/dietmarwo/fcmaes-java/blob/master/cppsrc/daoptimizer.cpp[daoptimizer.cpp]

We executed 320 optimization runs, 32 in parallel on a 16 core / 32 thread processor node.
[source,java]
----
Task1Fit fit = new Task1Fit(numberImpulses, maxTime, minTimeToNextDV, maxDV);
Utils.startTiming();
Optimizer opt = new GCLDE();
Result res = fit.minimizeN(320, opt, fit.lower(), fit.upper(), null, null, 20000, 31, 0);
System.out.println(Utils.measuredMillis() + " ms");
----

Multiple processor nodes can compute several of these 320 optimization runs at the same time. After they finish, the best
partial solutions are chosen for extension and distributed on the available nodes. Then the optimization process is
started again. This process repeats until a task is finished. Then the objective function for the next task is used for optimization.

We used only six 16 core processor nodes for about 30 hours to compute a solution for all three tasks. The process should scale well if more
processing resources are available.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) [2020] [Dietmar Wolz]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
61 changes: 61 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
:encoding: utf-8
:imagesdir: img
:cpp: C++

= fcmaes-java - a Java gradient-free optimization library

fcmaes-java provides fast {cpp}/Eigen based implementations of its gradient free optimization algorithms.
It supports parallel optimization and parallel function evaluation. A new coordinated parallel retry mechanism
can be viewed as a meta algorithm operating on a population of user defined optimization runs.
fcmaes-java provides the same functionality as its Python variant https://github.com/dietmarwo/fast-cma-es[fcmaes].
It was used by the team Jena & Wuhan for the 11th China Trajectory Optimization Competition https://ctoc11.skyeststudio.com/[CTOC11]
see https://github.com/dietmarwo/fcmaes-java/blob/master/CTOC11.adoc[fcmaes for CTOC11].

=== Features

- fcmaes-java is focused on optimization problems hard to solve.
- Minimized algorithm overhead - relative to the objective function evaluation time - even for high dimensions.
- Parallel coordinated retry of sequences and random choices of optimization algorithms.
- Parallel function evaluation.
- New DE (differential evolution) variant optimized for usage with parallel coordinated retry.
- GCL-DE (differential evolution) variant from Mingcheng Zuo.
- Fast C++ implementations of CMA-ES, differential evolution, dual annealing and the Harris hawks algorithm.
- Supports Linux and Windows

=== Compilation

* `mvn install`

=== Usage

See the F8 example https://github.com/dietmarwo/fcmaes-java/blob/master/src/main/java/examples/F8.java[F8.java].
Many other examples can be found in the test cases
https://github.com/dietmarwo/fcmaes-java/blob/master/src/test/java/fcmaes/core/OptimizerTest.java[OptimizerTest.java].

=== Dependencies

Runtime:

- see https://github.com/dietmarwo/fcmaes-java/blob/master/pom.xml

Compile time (binaries for Linux and Windows are included):

- Eigen https://gitlab.com/libeigen/eigen (version >= 3.9 is required for CMA).
- pcg-cpp: https://github.com/imneme/pcg-cpp - used in all {cpp} optimization algorithms.
- LBFGSpp: https://github.com/yixuan/LBFGSpp/tree/master/include - used for dual annealing local optimization.
- Ascent: https://github.com/AnyarInc/Ascent/tree/master/include - used for fast ODE integration

=== Performance

On a single AMD 3950x CPU using the parallel coordinated retry mechanism
solves ESAs 26-dimensional https://www.esa.int/gsp/ACT/projects/gtop/messenger_full/[Messenger full] problem
in about 1.5 hours on average. The Messenger full benchmark models a
multi-gravity assist interplanetary space mission from Earth to Mercury. In 2009 the first good solution (6.9 km/s)
was submitted. It took more than five years to reach 1.959 km/s and three more years until 2017 to find the optimum 1.958 km/s.
The picture below shows the progress of the whole science community since 2009:

image::Fsc.png[]

For comparison: http://www.midaco-solver.com/data/pub/PDPTA20_Messenger.pdf[MXHCP paper] shows that using 1000 cores of the the
Hokudai Supercomputer using Intel Xeon Gold 6148 CPU’s with a clock rate of 2.7 GHz Messenger Full can be solved
in about 1 hour using the MXHCP algorithm.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# fcmaes
A Python 3 gradient-free optimization library.

- [README](https://github.com/dietmarwo/fcmaes-java/blob/master/README.adoc)
- [CTOC11](https://github.com/dietmarwo/fcmaes-java/blob/master/CTOC11.adoc)
30 changes: 30 additions & 0 deletions cppsrc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# This is a CMake makefile. You can find the cmake utility and
# information about it at http://www.cmake.org
#
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -march=native")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")

INCLUDE_DIRECTORIES(/home/xxx/python/fcmaes-java/cppsrc/include)
INCLUDE_DIRECTORIES(/home/xxx/.sdkman/candidates/java/current/include)
INCLUDE_DIRECTORIES(/home/xxx/.sdkman/candidates/java/current/include/linux)

#set default build type to Release
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING
"Choose the type of build, options are: Debug Release
RelWithDebInfo MinSizeRel." FORCE)
endif()

PROJECT(fcmaeslib)

add_library(fcmaeslib SHARED acmaesoptimizer.cpp hawksoptimizer.cpp deoptimizer.cpp daoptimizer.cpp gcldeoptimizer.cpp lcldeoptimizer.cpp ldeoptimizer.cpp ascent.cpp)

set(CMAKE_INSTALL_LIBDIR /home/xxx/python/fcmaes-java/src/main/resources/natives)

install(TARGETS fcmaeslib LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

Loading

0 comments on commit 0ba45f1

Please sign in to comment.