View Javadoc
1   package org.woehlke.simulation.evolution.model;
2   
3   import java.util.List;
4   import java.util.Random;
5   import java.util.ArrayList;
6   
7   /**
8    * The CellCore contains the DNA which has influence on orientation at moving.
9    *
10   * Simulated Evolution.
11   * Artificial Life Simulation of Bacteria Motion depending on DNA.
12   *
13   * © 2006 - 2008 Thomas Woehlke.
14   * http://thomas-woehlke.de/p/simulated-evolution/
15   * @author Thomas Woehlke
16   * Date: 04.02.2006
17   * Time: 19:55:23
18   */
19  public class CellCore {
20  
21      /**
22       * The DNA Values of the Genome.
23       */
24      private List<Integer> dna;
25  
26      private final static int MIN_VALUE = 0;
27      private final static int MAX_VALUE = 16;
28      private final static int MAX_INITIAL_VALUE = 8;
29  
30      /**
31       * Random Generator is set from outside by Constructor.
32       */
33      private Random random;
34  
35      public CellCore(Random random) {
36          dna = new ArrayList<Integer>();
37          this.random = random;
38          for (int i = 0; i < Orientation.values().length; i++) {
39              int gen = random.nextInt() % MAX_INITIAL_VALUE;
40              dna.add(gen);
41          }
42      }
43  
44      private CellCore(Random random, List<Integer> rna) {
45          this.random = random;
46          dna = new ArrayList<Integer>();
47          dna.addAll(rna);
48      }
49  
50      /**
51       * Mitosis is the Cell Core Division where the DNA changes for Evolution.
52       * After Mitosis this Cell Core is one of the two Children.
53       *
54       * @see Cell#performReproductionByCellDivision()
55       *
56       * @return the other Child CellCore.
57       */
58      public CellCore performMitosis() {
59          List<Integer> rna = new ArrayList<Integer>();
60          for (Integer dnaBase:dna) {
61              rna.add(dnaBase);
62          }
63          CellCore child = new CellCore(random, rna);
64          int baseIndex = random.nextInt() % Orientation.values().length;
65          if (baseIndex < MIN_VALUE) {
66              baseIndex *= -1;
67          }
68          Orientation base[] = Orientation.values();
69          this.decrease(base[baseIndex]);
70          child.increase(base[baseIndex]);
71          return child;
72      }
73  
74      private void increase(Orientation base) {
75          int value = dna.get(base.ordinal());
76          if (value == MAX_VALUE) {
77              for (int i = 0; i < dna.size(); i++) {
78                  Integer val = dna.get(i);
79                  val--;
80                  dna.set(i, val);
81              }
82          }
83          Integer val = dna.get(base.ordinal());
84          val++;
85          dna.set(base.ordinal(), val);
86      }
87  
88      private void decrease(Orientation base) {
89          int value = dna.get(base.ordinal());
90          if (value == -MAX_VALUE) {
91              for (int i = 0; i < dna.size(); i++) {
92                  Integer val = dna.get(i);
93                  val++;
94                  dna.set(i, val);
95              }
96              dna.set(base.ordinal(), 0);
97          } else {
98              dna.set(base.ordinal(), value-1);
99          }
100     }
101 
102     /**
103      * @return gives a new Orientation based on the Combinition of Random and DNA.
104      */
105     public Orientation getRandomOrientation() {
106         Orientation orientation = Orientation.FORWARD;
107         int dnaLength = Orientation.values().length;
108         double sumDna = 0.0;
109         for (int i = 0; i < dnaLength; i++) {
110             double val = dna.get(i).longValue() ^ 2;
111             if (val < MIN_VALUE) {
112                 val *= -1;
113             }
114             sumDna += val;
115         }
116         double sum = 0.0;
117         double[] rna = new double[dnaLength];
118         for (int i = 0; i < dnaLength; i++) {
119             double val = dna.get(i).longValue() ^ 2;
120             if (val < MIN_VALUE) {
121                 val *= -1;
122             }
123             sum += val / sumDna;
124             rna[i] = sum;
125         }
126         if (sumDna != 0) {
127             double val = new Double(random.nextInt(MAX_VALUE) ^ 2);
128             if (val < MIN_VALUE) {
129                 val *= -1;
130             }
131             double sumRandom = val / new Double(MAX_VALUE ^ 2);
132             if (sumRandom < MIN_VALUE) {
133                 sumRandom *= -1;
134             }
135             int newInt = 0;
136             for (int i = 0; i < dnaLength; i++) {
137                 if (sumRandom > rna[i]) {
138                     newInt = i;
139                 }
140             }
141             orientation = Orientation.values()[newInt];
142         }
143         return orientation;
144     }
145 }