Newer
Older
abgabensammlungSS15 / ea / project / EaVolleyballProject / src / eva2 / problems / simple / HyperVolleyballProblem.java
@MaxXximus92 MaxXximus92 on 6 Jul 2015 5 KB ea project
package eva2.problems.simple;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

import eva2.util.annotation.Description;
import eva2.util.annotation.Parameter;

/**
 * @author Maximus Mutschler & Jan-Peter Hohloch
 *
 */

@Description("Getting an Ass in Hypervolleyball.")
public class HyperVolleyballProblem extends SimpleProblemDouble {
	private static final long serialVersionUID = 2796213693976730881L;
	/**
	 * Problem dimension
	 */
	private int dimension = 4;

	private int spaceDimension = dimension - 1;

	private Random r = new Random();

	/**
	 * Regular court's side's size.
	 */
	private final double courtSize = 9;

	/**
	 * 2^(n)+1 players on the court. Where n is the number of space dimensions.
	 * This means, in a two dimensional court, there are 5 players arranged like
	 * a cross.
	 */
	private int numberOfPlayers = getNumberOfPlayers();

	public List<Player> players = new ArrayList<HyperVolleyballProblem.Player>();

	/**
	 * same range for all players
	 */
	private double sigma = 1;

	public HyperVolleyballProblem() {
		calcPlayers();
	}

	private void calcPlayers() {
		players.clear();
		double[] position = new double[spaceDimension];
		Arrays.fill(position, courtSize / 2);
		players.add(new Player(position, sigma));

		double[][] positions = new double[numberOfPlayers - 1][spaceDimension];
		playerPositions(0, numberOfPlayers - 1, positions, 0);

		for (double[] p : positions) {
			players.add(new Player(p, sigma));
		}
	}

	/**
	 * 
	 * @param begin
	 *            index
	 * @param end
	 *            index
	 * @param positions
	 *            will get filled with the positions of the players
	 * @param index
	 *            current dimension.
	 */
	private void playerPositions(int begin, int end, double[][] positions,
			int index) {
		if (index == positions[0].length) {
			return;
		}
		int center = (((end - begin) / 2) + begin);
		for (int i = begin; i < center; i++) {
			positions[i][index] = courtSize / 4;
		}
		for (int i = center; i < end; i++) {
			positions[i][index] = (courtSize * 3) / 4;
		}
		playerPositions(begin, center, positions, index + 1);
		playerPositions(center, end, positions, index + 1);
	}

	private double density(double[] position) {
		double dens = 0;
		for (Player p : players) {
			dens += normDistribution(distance(position, p.getPosition()), 0,
					p.getSigma());
		}
		return dens;
	}

	private double distance(double[] a, double[] b) {
		double dist = 0;
		for (int i = 0; i < b.length; i++) {
			dist += (a[i] - b[i]) * (a[i] - b[i]);
		}
		return Math.sqrt(dist);
	}

	private double normDistribution(double x, double mu, double sigma) {
		return (1 / (Math.sqrt(2 * Math.PI) * sigma))
				* Math.exp((-0.5 * (x - mu) * (x - mu)) / (sigma * sigma));
	}

	@Override
	public double[] evaluate(double[] individual) {
		double force = individual[0];
		int penalty = 1;
		if (force <= 0) {
			return new double[] { penalty - force };
		}
		double[] position = Arrays
				.copyOfRange(individual, 1, individual.length);

		for (int i = 0; i < position.length; i++) {
			position[i] += r.nextGaussian() * force;
		}

		for (double p : position) {
			if ((p > courtSize) || (p < 0)) {
				return new double[] { p < 0 ? penalty - p
						: (penalty - courtSize) + p };// abweichung
				// vom
				// feld
				// nehmen
			}
		}

		return new double[] { density(position) // individual[0] = velocity.
				/ force };
	}

	@Override
	public int getProblemDimension() {
		return dimension;
	}

	public int getDimension() {
		return this.dimension;
	}

	/**
	 * Set the problem dimension.
	 *
	 * @param d
	 *            The dimension.
	 */
	@Parameter(description = "Set 2 <= Dimension <= 100.")
	public void setDimension(int d) {
		if (d < 2) {
			d = 2;
		}
		if (d > 100) {
			d = 100;
		}
		dimension = d;
		spaceDimension = dimension - 1;
		numberOfPlayers = getNumberOfPlayers();
		calcPlayers();

	}

	private int getNumberOfPlayers() {
		return (int) Math.pow(2, (spaceDimension)) + 1;
	}

	@Parameter(description = "Set 0 < Sigma (Players \"range\")")
	public void setPlayerSigma(double sigma) {
		if (sigma != 0) {
			this.sigma = Math.abs(sigma);
		}
	}

	public double getPlayerSigma() {
		return sigma;
	}

	public class Player {
		private static final long serialVersionUID = 2796413693976730841L;
		private double[] position;
		private double sigma;

		public Player() {
			setPosition(new double[] { 0, 0, 0 });
			setSigma(1);
		}

		public Player(double[] position, double sigma) {
			this.setPosition(position);
			this.setSigma(sigma);
		}

		@Override
		public String toString() {
			return Arrays.toString(getPosition()) + "  sigma:" + getSigma();
		}

		/**
		 * @return the position
		 */
		public double[] getPosition() {
			return position;
		}

		/**
		 * @param position
		 *            the position to set
		 */
		public void setPosition(double[] position) {
			this.position = position;
		}

		/**
		 * @return the sigma
		 */
		public double getSigma() {
			return sigma;
		}

		/**
		 * @param sigma
		 *            the sigma to set
		 */
		public void setSigma(double sigma) {
			this.sigma = sigma;
		}

	}

	// public static void main(String[] args) {
	// HyperVolleyballProblem p = new HyperVolleyballProblem();
	// for (Player pl : p.players) {
	// System.out.println(pl);
	// }
	// }
}