/* * Copyright 2015 S. Webber * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.oakgp.rank.tournament; import java.util.Collection; import java.util.Collections; import org.oakgp.node.Node; import org.oakgp.rank.GenerationRanker; import org.oakgp.rank.RankedCandidate; import org.oakgp.rank.RankedCandidates; /** Ranks and sorts the fitness of {@code Node} instances using a {@code TwoPlayerGame} in a round-robin tournament. */ public final class RoundRobinTournament implements GenerationRanker { private final TwoPlayerGame game; /** Creates a {@code RoundRobinTournament} for the given {@code TwoPlayerGame}. */ public RoundRobinTournament(TwoPlayerGame game) { this.game = game; } @Override public RankedCandidates rank(Collection<Node> input) { Node[] inputAsArray = input.toArray(new Node[input.size()]); double[] fitness = evaluateFitness(inputAsArray); return toRankedCandidates(inputAsArray, fitness); } private double[] evaluateFitness(Node[] input) { int size = input.length; double[] fitness = new double[size]; for (int i1 = 0; i1 < size - 1; i1++) { Node player1 = input[i1]; for (int i2 = i1 + 1; i2 < size; i2++) { Node player2 = input[i2]; double result = game.evaluate(player1, player2); fitness[i1] += result; fitness[i2] += -result; } } return fitness; } private RankedCandidates toRankedCandidates(Node[] input, double[] fitness) { int size = fitness.length; RankedCandidate[] output = new RankedCandidate[size]; for (int i = 0; i < size; i++) { output[i] = new RankedCandidate(input[i], fitness[i]); } return new RankedCandidates(output, Collections.reverseOrder()); } }