FUEL = FUnctional Evolutionary aLgorithms
FUEL is a succinct framework for implementing metaheuristic algorithms, in particular evolutionary algorithms, in Scala. It is written primarily in functional style, with most objects implemented as immutable, and using object-oriented style rather sparingly.
Features:
- Simple and lightweight (<2000 lines of code, including several examples of usage)
- Easy manipulation of components (e.g., hybridizing algorithms, search operators, etc.)
- Most components implemented as immutable
- Applicable to single- and multiobjective problems
- Ready-to-use basic operators for solutions represented as vectors and permutations.
- Support for parallelization
- Easily interoperable with Java
- No dependencies on external libraries
Examples of use
Solving the Max-Ones problem using traditional genetic algorithm (actually implemented as Min-Ones, i.e., the algorithm attempts to zero all bits).
object MaxOnes extends App {
new OptColl {
RunExperiment(SimpleEA(moves = BitSetMoves(100),
eval = (s: BitSet) => s.size,
stop = (s: BitSet, e: Int) => e == 0))
}
}
A variant with some parameters set manually:
object MaxOnes extends App {
new OptColl('numVars -> 500, 'maxGenerations -> 200, 'printResults -> true) {
RunExperiment(SimpleEA(
moves = BitSetMoves(opt('numVars , (_: Int) > 0)),
eval = (s: BitSet) => s.size,
optimalValue = 0))
}
}
Solving a (randomly generated) Travelling Salesperson Problem (TSP):
object TSP extends App {
new OptColl('numCities -> 30, 'maxGenerations -> 300) {
// Generate random distance matrix
val numCities = opt('numCities , (_: Int) > 0)
val cities = Seq.fill(numCities)((rng.nextDouble, rng.nextDouble))
val distances = for (i <- cities) yield for (j <- cities)
yield math.hypot(i._1 - j._1, i._2 - j._2)
// Fitness function
def eval(s: Seq[Int]) =
Range(0, s.size).map(i => distances(s(i))(s((i + 1) % s.size))).sum
RunExperiment(SimpleEA(PermutationMoves(numCities), eval))
}
}
Source
FUEL is available on github under the (very permissive) MIT license.