source: java/ecj/app/numbers_game/MultiDimensionalNumbersGame.java @ 42

Last change on this file since 42 was 42, checked in by mszubert, 14 years ago

refactored cecj; framsticks package added

File size: 3.9 KB
Line 
1package cecj.app.numbers_game;
2
3import java.math.BigDecimal;
4import java.math.BigInteger;
5import java.math.RoundingMode;
6import java.util.ArrayList;
7import java.util.List;
8
9import cecj.interaction.InteractionResult;
10import cecj.problems.SymmetricTestBasedProblem;
11import cecj.statistics.ObjectiveFitnessCalculator;
12import cecj.utils.Pair;
13
14import ec.EvolutionState;
15import ec.Individual;
16import ec.util.Parameter;
17import ec.vector.BitVectorIndividual;
18
19public abstract class MultiDimensionalNumbersGame extends SymmetricTestBasedProblem implements
20                ObjectiveFitnessCalculator {
21
22        private static final String P_DIMENSIONS = "dimensions";
23        private static final String P_DIM_SIZE = "dimension-size";
24
25        private int numDimensions;
26        private int dimensionSize;
27        private int expectedGenomeLength;
28
29        @Override
30        public void setup(EvolutionState state, Parameter base) {
31                super.setup(state, base);
32               
33                Parameter numDimensionsParam = base.push(P_DIMENSIONS);
34                numDimensions = state.parameters.getInt(numDimensionsParam, null, 1);
35                if (numDimensions <= 0) {
36                        state.output
37                                .fatal("Multi Dimensional Numbers Game dimensions must be specified and >= 0\n", numDimensionsParam);
38                }
39
40                Parameter dimensionSizeParam = base.push(P_DIM_SIZE);
41                dimensionSize = state.parameters.getInt(dimensionSizeParam, null, 1);
42                if (dimensionSize <= 0) {
43                        state.output
44                                .fatal("Multi Dimensional Numbers Game dimension size must be specified and >= 0\n", dimensionSizeParam);
45                }
46
47                expectedGenomeLength = numDimensions * dimensionSize;
48        }
49
50        @Override
51        public Pair<? extends InteractionResult> test(EvolutionState state, Individual candidate,
52                        Individual test) {
53                if (!(candidate instanceof BitVectorIndividual) || !(test instanceof BitVectorIndividual)) {
54                        state.output
55                                .error("NumbersGame player's individual should be represented by bit vector\n");
56                }
57
58                BitVectorIndividual bitCandidate = (BitVectorIndividual) candidate;
59                BitVectorIndividual bitTest = (BitVectorIndividual) test;
60
61                if (bitCandidate.genomeLength() != bitTest.genomeLength()) {
62                        state.output.error("NumbersGame players' bit vectors should be equal length\n");
63                }
64
65                if (bitCandidate.genomeLength() != expectedGenomeLength) {
66                        state.output
67                                .error("NumbersGame player's bit vector length must be equal to product of dimensions number and dimension size\n");
68                }
69
70                List<BigInteger> candidateVector = getIntegerVector(bitCandidate.genome);
71                List<BigInteger> testVector = getIntegerVector(bitTest.genome);
72
73                return compareDimensionsVectors(candidateVector, testVector);
74        }
75
76        /**
77         * Returns objective fitness normalized to [0, 1] interval;
78         */
79        public float calculateObjectiveFitness(EvolutionState state, Individual ind) {
80                if (!(ind instanceof BitVectorIndividual)) {
81                        state.output.error("Competitor individuals should be represented by bit vectors\n");
82                }
83                BitVectorIndividual bitIndividual = (BitVectorIndividual) ind;
84
85                BigDecimal dimensionMaxValue = new BigDecimal(2).pow(dimensionSize)
86                        .subtract(BigDecimal.ONE);
87                BigDecimal sumMaxValue = dimensionMaxValue.multiply(new BigDecimal(numDimensions));
88
89                List<BigInteger> dimensionVector = getIntegerVector(bitIndividual.genome);
90                BigDecimal sum = BigDecimal.ZERO;
91                for (BigInteger dimension : dimensionVector) {
92                        sum = sum.add(new BigDecimal(dimension));
93                }
94
95                return sum.divide(sumMaxValue, 10, RoundingMode.DOWN).floatValue();
96        }
97
98        private List<BigInteger> getIntegerVector(boolean[] genome) {
99                List<BigInteger> result = new ArrayList<BigInteger>();
100                BigInteger bigTwo = new BigDecimal(2).toBigInteger();
101
102                for (int dim = 0; dim < numDimensions; dim++) {
103                        BigInteger dimValue = BigInteger.ZERO;
104                        for (int i = 0; i < dimensionSize; i++) {
105                                dimValue = dimValue.multiply(bigTwo);
106                                if (genome[(dim * dimensionSize) + i]) {
107                                        dimValue = dimValue.add(BigInteger.ONE);
108                                }
109                        }
110                        result.add(dimValue);
111                }
112
113                return result;
114        }
115
116        protected abstract Pair<? extends InteractionResult> compareDimensionsVectors(
117                        List<BigInteger> candidateVector, List<BigInteger> testVector);
118}
Note: See TracBrowser for help on using the repository browser.