├── img
├── example1.gif
├── example2.gif
├── fitnessEq.gif
├── maxVelEq.gif
└── posVelAccEq.gif
├── .gitignore
├── example1
├── sun.pde
├── example1.pde
├── satelliteSystem.pde
├── satellite.pde
└── brain.pde
├── example2
├── sun.pde
├── example2.pde
├── satellite.pde
├── satelliteSystem.pde
└── brain.pde
├── LICENSE
└── README.md
/img/example1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c-planelles/self-propelled-satellites/HEAD/img/example1.gif
--------------------------------------------------------------------------------
/img/example2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c-planelles/self-propelled-satellites/HEAD/img/example2.gif
--------------------------------------------------------------------------------
/img/fitnessEq.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c-planelles/self-propelled-satellites/HEAD/img/fitnessEq.gif
--------------------------------------------------------------------------------
/img/maxVelEq.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c-planelles/self-propelled-satellites/HEAD/img/maxVelEq.gif
--------------------------------------------------------------------------------
/img/posVelAccEq.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c-planelles/self-propelled-satellites/HEAD/img/posVelAccEq.gif
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | applet
3 | application.linux32
4 | application.linux64
5 | application.windows32
6 | application.windows64
7 | application.macosx
8 |
--------------------------------------------------------------------------------
/example1/sun.pde:
--------------------------------------------------------------------------------
1 |
2 | class Sun {
3 | PVector position;
4 | float mass;
5 |
6 | Sun(){
7 | position = new PVector((width-6)/2.0, (0.63*height)/2.0);
8 | mass = 1000.0;
9 | }
10 |
11 | void run() {
12 | update();
13 | display();
14 | }
15 |
16 | float getMass(){
17 | return mass;
18 | }
19 |
20 | void update() {
21 | }
22 |
23 | void display() {
24 | stroke(0);
25 | fill(#ffff00);
26 | ellipse(position.x, position.y, 20, 20);
27 | }
28 |
29 | PVector getPosition(){
30 | return position;
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/example2/sun.pde:
--------------------------------------------------------------------------------
1 |
2 | class Sun {
3 | PVector position;
4 | float mass;
5 |
6 | Sun(float posx, float posy){
7 | position = new PVector(posx,posy);
8 | mass = 1000.0;
9 | }
10 |
11 | void run() {
12 | update();
13 | display();
14 | }
15 |
16 | float getMass(){
17 | return mass;
18 | }
19 |
20 | void update() {
21 | }
22 |
23 | void display() {
24 | stroke(0);
25 | fill(#ffff00);
26 | ellipse(position.x, position.y, 20, 20);
27 | }
28 |
29 | PVector getPosition(){
30 | return position;
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Carlos Planelles Alemany
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/example1/example1.pde:
--------------------------------------------------------------------------------
1 | SatelliteSystem satelliteSys;
2 |
3 | int numSatellites = 100;
4 |
5 | void setup() {
6 | size(1200, 800);
7 | frameRate(2000);
8 | satelliteSys = new SatelliteSystem(numSatellites);
9 | }
10 |
11 | void draw() {
12 | background(150);
13 | //carsys.addParticle();
14 | satelliteSys.run();
15 | noFill();
16 | stroke(0);
17 | rect(3, 3, width-6, 0.63*height);
18 | drawTopBoard();
19 | drawGraph();
20 | text("Steps left: "+satelliteSys.getStepsLeft(), 10, 20);
21 | text("live satellites: "+satelliteSys.numSatLife(), 10, 40);
22 | text("generation : "+satelliteSys.generation(), 10, 60);
23 | }
24 |
25 | // d
26 | void drawTopBoard(){
27 | //draw TOP 10
28 | textSize(16);
29 | stroke(0);
30 | fill(0);
31 | text("1st "+nf(satelliteSys.getSatellite(0).getFitness(),0,1), 10, 534);
32 | text("2nd "+nf(satelliteSys.getSatellite(1).getFitness(),0,1), 10, 554);
33 | text("3rd "+nf(satelliteSys.getSatellite(2).getFitness(),0,1), 10, 574);
34 | for(int i=4; i<=10; i++)
35 | text(i+"th "+nf(satelliteSys.getSatellite(i).getFitness(),0,1), 10, 514+(20*i));
36 | }
37 |
38 | int[] x = new int[3501];
39 | float[] y = new float[3501];
40 | int iterator = 0;
41 | int[] xGen = {};
42 | float[] yGen = {};
43 | int generation = -1;
44 |
45 | void drawGraph(){
46 |
47 | iterator++;
48 | noFill();
49 | stroke(0);
50 | rect(width*0.15, 0.64*height , (1.0-0.15)*width-3, (1-0.64)*height-3);
51 |
52 | x[iterator] = iterator;// = append(x, iterator);
53 | y[iterator] = -satelliteSys.getSatellite(0).getFitness();
54 |
55 |
56 | if(iterator > 1) {
57 | for(int i = 1; i < iterator; i++) {
58 | line(0.75*x[i-1]/iterator*width+width/5, y[i-1]+height/1.1, 0.75*x[i]/iterator*width+width/5, y[i]+height/1.1);
59 | }
60 | }
61 |
62 | stroke(255);
63 | if(generation > 1) {
64 | for(int i = 1; i < generation; i++) {
65 | line(10.0*xGen[i-1]+width/5, yGen[i-1]+height/1.1, 10.0*xGen[i]+width/5, yGen[i]+height/1.1);
66 | }
67 | }
68 |
69 | //println(y[iterator-1]);
70 | if(generation < satelliteSys.generation()){
71 | generation = satelliteSys.generation();
72 | println(iterator);
73 | xGen = append(xGen, generation);
74 | yGen = append(yGen, y[iterator-1]);
75 |
76 | iterator = -1;
77 | }
78 | }
--------------------------------------------------------------------------------
/example2/example2.pde:
--------------------------------------------------------------------------------
1 | SatelliteSystem satelliteSys;
2 |
3 | int numSatellites = 100;
4 | int numSuns = 3;
5 |
6 | void setup() {
7 | size(1200, 800);
8 | frameRate(2000);
9 | satelliteSys = new SatelliteSystem(numSatellites, numSuns);
10 | }
11 |
12 | void draw() {
13 | background(150);
14 | //carsys.addParticle();
15 | satelliteSys.run();
16 | noFill();
17 | stroke(0);
18 | rect(3, 3, width-6, 0.63*height);
19 | drawTopBoard();
20 | drawGraph();
21 | text("Steps left: "+satelliteSys.getStepsLeft(), 10, 20);
22 | text("live satellites: "+satelliteSys.numSatLife(), 10, 40);
23 | text("generation : "+satelliteSys.generation(), 10, 60);
24 | }
25 |
26 | // d
27 | void drawTopBoard(){
28 | //draw TOP 10
29 | textSize(16);
30 | stroke(0);
31 | fill(0);
32 | text("1st "+nf(satelliteSys.getSatellite(0).getFitness(),0,1), 10, 534);
33 | text("2nd "+nf(satelliteSys.getSatellite(1).getFitness(),0,1), 10, 554);
34 | text("3rd "+nf(satelliteSys.getSatellite(2).getFitness(),0,1), 10, 574);
35 | for(int i=4; i<=10; i++)
36 | text(i+"th "+nf(satelliteSys.getSatellite(i).getFitness(),0,1), 10, 514+(20*i));
37 | }
38 |
39 | int[] x = new int[3501];
40 | float[] y = new float[3501];
41 | int iterator = 0;
42 | int[] xGen = {};
43 | float[] yGen = {};
44 | int generation = -1;
45 |
46 | void drawGraph(){
47 |
48 | iterator++;
49 | noFill();
50 | stroke(0);
51 | rect(width*0.15, 0.64*height , (1.0-0.15)*width-3, (1-0.64)*height-3);
52 |
53 | x[iterator] = iterator;// = append(x, iterator);
54 | y[iterator] = -satelliteSys.getSatellite(0).getFitness();
55 |
56 |
57 | if(iterator > 1) {
58 | for(int i = 1; i < iterator; i++) {
59 | line(0.75*x[i-1]/iterator*width+width/5, y[i-1]+height/1.1, 0.75*x[i]/iterator*width+width/5, y[i]+height/1.1);
60 | }
61 | }
62 |
63 | stroke(255);
64 | if(generation > 1) {
65 | for(int i = 1; i < generation; i++) {
66 | line(10.0*xGen[i-1]+width/5, yGen[i-1]+height/1.1, 10.0*xGen[i]+width/5, yGen[i]+height/1.1);
67 | }
68 | }
69 |
70 | //println(y[iterator-1]);
71 | if(generation < satelliteSys.generation()){
72 | generation = satelliteSys.generation();
73 |
74 | xGen = append(xGen, generation);
75 | yGen = append(yGen, y[iterator-1]);
76 |
77 | iterator = -1;
78 | }
79 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # self-propelled satellites
2 | The system is formed by self-propelled satellites influenced by the Sun whose objective is not to leave the domain maintaining the maximum possible speed.
3 |
4 | All satellites start at the same point with zero velocity, interacting with the Sun according to Newton's law of universal gravitation. Each satellite can auto propel.
5 |
6 | ## Example 1
7 |
8 | ### Equations
9 |
10 | #### Calculation of position, speed, and acceleration.
11 |
12 | Acceleration is calculated by Newton's law of universal gravitation plus the satellite impulse, the velocity is computed from the acceleration and the position from the velocity.
13 |
14 |
15 |
16 |
17 |
18 | #### Inpulse
19 |
20 | The pulse is calculated by the "brain" of the satellite consisting of a neural network consisting of two hidden layers of 5 and 3 neurons, the input data are the satellite speed, the position of the satellite and the position of the Sun, as output the impulse.
21 |
22 | #### Genetic algorithm
23 |
24 | The genetic algorithm changes weight and bias of neural networks by mutation, reproduction and crossing of the neurons, between the top 5 of the satellites. This way, the maximum fitness value is obtained progressively.
25 |
26 | Note: The first 5 satellites are not affected by the genetic algorithm. The algorithm randomly chooses two satellites for reproduction and another for crossing, among the first five (they can not be the same).
27 |
28 |
29 | #### Fitness
30 |
31 | Fitness must calculate the accumulated velocity (in module) of the satellite "i" in the generation "g", adding all the previous steps "j". Then a constant (0.025) is multiplied at that speed. If the module of the instantaneous velocity is greater than a maximum value established (20), it is penalized by subtracting 10.
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | *[YouTube video](https://www.youtube.com/watch?v=gBNJntyCFuE&feature=youtu.be)*
42 |
43 |
44 |
45 |
46 |
47 |
48 | ## Example 2
49 |
50 | It is like example 1 but the satellites interact with three stars.
51 |
52 | *[YouTube video](https://www.youtube.com/watch?v=eWLeQlX0vnI&feature=youtu.be)*
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/example1/satelliteSystem.pde:
--------------------------------------------------------------------------------
1 |
2 | // A class to describe a group of Particles
3 | // An ArrayList is used to manage the list of Particles
4 |
5 | import java.util.Arrays;
6 |
7 | class SatelliteSystem {
8 | ArrayList selfCarSystem;
9 | Sun sun;
10 | int generation;
11 | int numSats;
12 | int numSatsLife;
13 | int stepsLeft;
14 |
15 | SatelliteSystem(int n) {
16 | sun = new Sun();
17 | generation = 0;
18 | numSats = n;
19 | numSatsLife = n;
20 | stepsLeft = 3500;
21 | selfCarSystem = new ArrayList();
22 | for (int i=0; i sortCars(ArrayList old){
62 | ArrayList sorted = new ArrayList();
63 | for (int i = old.size()-1; i>=0; i--)
64 | {
65 | float max_score=-1000000000.0;
66 | int index = -1;
67 | for (int j = old.size()-1; j>=0; j--)
68 | {
69 | if (old.get(j).getFitness()>max_score)
70 | {
71 | max_score = old.get(j).getFitness();
72 | index = j;
73 | }
74 | }
75 | sorted.add(old.get(index));
76 | old.remove(index);
77 | }
78 | return sorted;
79 | }
80 |
81 | // GA == genetic algorithm
82 | //void GA(){
83 | // for(int i = 5; i 5){
109 | //voose between top 5
110 | int sat1 = int(random(0, 5));
111 | int sat2 = int(random(0, 5));
112 | // not reapeat sat
113 | while(sat1 == sat2){
114 | sat2 = int(random(0, 5));
115 | }
116 | selfCarSystem.get(i).geneticAlgotithm(selfCarSystem.get(sat1), selfCarSystem.get(sat2));
117 | }
118 | }
119 | stepsLeft = 3500;
120 | numSatsLife = numSats;
121 | generation++;
122 | }
123 |
124 | }
--------------------------------------------------------------------------------
/example1/satellite.pde:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Satellite {
4 | PVector position;
5 | PVector velocity;
6 | PVector acceleration;
7 | boolean lifetag;
8 | float fitness;
9 | int numDeads;
10 | float mass;
11 | float acumulateVel; // to deff new parameter to fitness
12 |
13 | Brain brain;
14 |
15 | //domain limits
16 | float topLimit = 3.0;
17 | float downLimit = 0.63*height;
18 | float leftLimit = 3.0;
19 | float rightLimit = width-6;
20 | float timetag;
21 |
22 | Satellite() {
23 | acceleration = new PVector(0.0, 0.0);
24 | velocity = new PVector(0.0, 0.0);
25 | //position = new PVector(random(leftLimit, rightLimit), random(topLimit, downLimit));
26 | position = new PVector(width/6.0, 0.63*height/2.0);
27 | lifetag = true;
28 | fitness = 0;
29 | timetag = 0;
30 | numDeads = 0;
31 | acumulateVel = 0;
32 | mass = 0.1;
33 | brain = new Brain();
34 | }
35 |
36 | void run(float sunMass, PVector sunPosition) {
37 | if(isLife()){
38 | update(sunMass, sunPosition);
39 | display();
40 | }
41 | }
42 |
43 | // Method to update position
44 | void update(float sunMass, PVector sunPosition) {
45 | timetag ++;
46 | acceleration = gravityForce(sunMass, sunPosition).add(brain.getInpulse(position, velocity, sunPosition)) ;
47 | velocity.add(acceleration);
48 | position.add(velocity);
49 | //lifetag = true;
50 | deadConditions();
51 | calculateFitness();
52 | }
53 |
54 | // Method to display
55 | void display() {
56 | if(isLife()){
57 | stroke(0);
58 | fill(#a73540);
59 | ellipse(position.x, position.y, 8, 8);
60 | }
61 | }
62 |
63 | // Is the car still useful?
64 | boolean isLife() {
65 | return lifetag;
66 | }
67 |
68 | void reallocate(){
69 | acceleration = new PVector(0.0, 0.0);
70 | velocity = new PVector(0.0, 0.0);
71 | //position = new PVector(random(leftLimit, rightLimit), random(topLimit, downLimit));
72 | position = new PVector(width/6.0, 0.63*height/2.0);
73 | lifetag = true;
74 | fitness = 0;
75 | numDeads ++;
76 | timetag = 0;
77 | acumulateVel = 0;
78 | }
79 |
80 | // dead conditions
81 | void deadConditions(){
82 | if(position.x>rightLimit || position.xdownLimit || position.y20) vel = -10;
90 | acumulateVel += vel;
91 | //0.005
92 | fitness = 0.0*(timetag) - 0.0*numDeads + 0.0*vel + 0.025*acumulateVel;
93 | }
94 |
95 | float getFitness(){
96 | return fitness;
97 | }
98 |
99 | float getDeads(){
100 | return numDeads;
101 | }
102 |
103 | PVector gravityForce(float sunMass, PVector sunPosition){
104 | float dist = position.dist(sunPosition);
105 | PVector force = PVector.sub(position,sunPosition).normalize().mult(-mass*sunMass/(dist*dist));
106 | return force;
107 | }
108 |
109 | void geneticAlgotithm(Satellite sat1, Satellite sat2){
110 |
111 | if(0.3 < random(0, 1.0))
112 | brain.mutation();
113 | if(0.3 < random(0, 1.0))
114 | brain.crossOver(sat1); // choose bebetween 4 first numbers (5 not include)
115 | if(0.3 < random(0, 1.0))
116 | brain.reproduction(sat1, sat2); // choose bebetween 4 first numbers
117 |
118 | }
119 |
120 | float getWeight(int layer, int i, int j){
121 | return brain.getWeight(layer, i, j);
122 | }
123 |
124 | float getBias(int layer, int i){
125 | return brain.getBias(layer, i);
126 | }
127 |
128 | }
--------------------------------------------------------------------------------
/example2/satellite.pde:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Satellite {
4 | PVector position;
5 | PVector velocity;
6 | PVector acceleration;
7 | boolean lifetag;
8 | float fitness;
9 | int numDeads;
10 | float mass;
11 | float acumulateVel; // to deff new parameter to fitness
12 |
13 | Brain brain;
14 |
15 | //domain limits
16 | float topLimit = 3.0;
17 | float downLimit = 0.63*height;
18 | float leftLimit = 3.0;
19 | float rightLimit = width-6;
20 | float timetag;
21 |
22 | Satellite(int numSuns) {
23 | acceleration = new PVector(0.0, 0.0);
24 | velocity = new PVector(0.0, 0.0);
25 | //position = new PVector(random(leftLimit, rightLimit), random(topLimit, downLimit));
26 | position = new PVector(width/6.0, 0.63*height/2.0);
27 | lifetag = true;
28 | fitness = 0;
29 | timetag = 0;
30 | numDeads = 0;
31 | acumulateVel = 0;
32 | mass = 0.1;
33 | brain = new Brain(numSuns);
34 | }
35 |
36 | void run(float[] sunMass, ArrayList sunPosition) {
37 | if(isLife()){
38 | update(sunMass, sunPosition);
39 | display();
40 | }
41 | }
42 |
43 | // Method to update position
44 | void update(float[] sunsMass, ArrayList sunsPosition) {
45 | timetag ++;
46 | acceleration = brain.getInpulse(position, velocity, sunsPosition);
47 | for (int j = 0; j < sunsPosition.size(); j++) {
48 | float sunMass = sunsMass[j];
49 | PVector sunPosition = sunsPosition.get(j);
50 | acceleration.add(gravityForce(sunMass, sunPosition)) ;
51 | }
52 | velocity.add(acceleration);
53 | position.add(velocity);
54 | //lifetag = true;
55 | deadConditions();
56 | calculateFitness();
57 | }
58 |
59 | // Method to display
60 | void display() {
61 | if(isLife()){
62 | stroke(0);
63 | fill(#a73540);
64 | ellipse(position.x, position.y, 8, 8);
65 | }
66 | }
67 |
68 | // Is the car still useful?
69 | boolean isLife() {
70 | return lifetag;
71 | }
72 |
73 | void reallocate(){
74 | acceleration = new PVector(0.0, 0.0);
75 | velocity = new PVector(0.0, 0.0);
76 | //position = new PVector(random(leftLimit, rightLimit), random(topLimit, downLimit));
77 | position = new PVector(width/6.0, 0.63*height/2.0);
78 | lifetag = true;
79 | fitness = 0;
80 | numDeads ++;
81 | timetag = 0;
82 | acumulateVel = 0;
83 | }
84 |
85 | // dead conditions
86 | void deadConditions(){
87 | if(position.x>rightLimit || position.xdownLimit || position.y20) vel = -10;
95 | acumulateVel += vel;
96 | //0.005
97 | fitness = 0.0*(timetag) - 0.0*numDeads + 0.0*vel + 0.025*acumulateVel;
98 | }
99 |
100 | float getFitness(){
101 | return fitness;
102 | }
103 |
104 | float getDeads(){
105 | return numDeads;
106 | }
107 |
108 | PVector gravityForce(float sunMass, PVector sunPosition){
109 | float dist = position.dist(sunPosition);
110 | PVector force = PVector.sub(position,sunPosition).normalize().mult(-mass*sunMass/(dist*dist));
111 | return force;
112 | }
113 |
114 | void geneticAlgotithm(Satellite sat1, Satellite sat2){
115 | if(0.3 < random(0, 1.0))
116 | brain.crossOver(sat1); // choose bebetween 4 first numbers (5 not include)
117 | else if(0.3 < random(0, 1.0))
118 | brain.copyBrain(sat1); // choose bebetween 4 first numbers (5 not include)
119 | else
120 | brain.reproduction(sat1, sat2); // choose bebetween 4 first numbers
121 |
122 | //if(0.3 < random(0, 1.0))
123 | brain.mutation();
124 |
125 | }
126 |
127 | float getWeight(int layer, int i, int j){
128 | return brain.getWeight(layer, i, j);
129 | }
130 |
131 | float getBias(int layer, int i){
132 | return brain.getBias(layer, i);
133 | }
134 |
135 | }
--------------------------------------------------------------------------------
/example2/satelliteSystem.pde:
--------------------------------------------------------------------------------
1 |
2 | // A class to describe a group of Particles
3 | // An ArrayList is used to manage the list of Particles
4 |
5 | import java.util.Arrays;
6 |
7 | class SatelliteSystem {
8 | ArrayList selfCarSystem;
9 | ArrayList suns;
10 | int generation;
11 | int numSats;
12 | int numSatsLife;
13 | int stepsLeft;
14 | int numSuns;
15 |
16 | SatelliteSystem(int numberSatellites, int numberSuns) {
17 | suns = new ArrayList();
18 | for (int i = 0; i < numberSuns; i++){
19 | suns.add(new Sun((width-6.0)/2.0, (0.63*height)/2.0*(0.4*i+0.6)));
20 | }
21 |
22 | generation = 0;
23 | numSats = numberSatellites;
24 | numSatsLife = numberSatellites;
25 | stepsLeft = 3500;
26 | numSuns = numberSuns;
27 |
28 | selfCarSystem = new ArrayList();
29 | for (int i=0; i sunPositions = new ArrayList();
47 | float[] sunMass = {};
48 | for (int j = 0; j < suns.size(); j++) {
49 | Sun sun = suns.get(j);
50 | sunMass = append(sunMass, sun.getMass());
51 | sunPositions.add(sun.getPosition());
52 | }
53 | sat.run(sunMass, sunPositions);
54 | if (sat.isLife()) {
55 | numSatsLife +=1;
56 | //selfCar.remove(i);
57 | //sat.reallocate();
58 | }
59 |
60 | }
61 |
62 | //sort cars comparing fitness
63 | //old = selfCarSystem;
64 | selfCarSystem = sortCars(selfCarSystem);
65 |
66 | // suns
67 | for (int i = 0; i < suns.size(); i++) {
68 | Sun sun = suns.get(i);
69 | sun.run();
70 | }
71 |
72 | stepsLeft --;
73 |
74 | }
75 |
76 | void addParticle() {
77 | selfCarSystem.add(new Satellite(numSuns));
78 | }
79 |
80 | //sort method
81 | ArrayList sortCars(ArrayList old){
82 | ArrayList sorted = new ArrayList();
83 | for (int i = old.size()-1; i>=0; i--)
84 | {
85 | float max_score=-1000000000.0;
86 | int index = -1;
87 | for (int j = old.size()-1; j>=0; j--)
88 | {
89 | if (old.get(j).getFitness()>max_score)
90 | {
91 | max_score = old.get(j).getFitness();
92 | index = j;
93 | }
94 | }
95 | sorted.add(old.get(index));
96 | old.remove(index);
97 | }
98 | return sorted;
99 | }
100 |
101 | // GA == genetic algorithm
102 | //void GA(){
103 | // for(int i = 5; i 5){
129 | //voose between top 5
130 | int sat1 = int(random(0, 5));
131 | int sat2 = int(random(0, 5));
132 |
133 | // not reapeat sat
134 | while(sat1 == sat2){
135 | sat2 = int(random(0, 5));
136 | }
137 |
138 | selfCarSystem.get(i).geneticAlgotithm(selfCarSystem.get(sat1), selfCarSystem.get(sat2));
139 | }
140 | }
141 | stepsLeft = 3500;
142 | numSatsLife = numSats;
143 | generation++;
144 | }
145 |
146 | }
--------------------------------------------------------------------------------
/example1/brain.pde:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Brain {
4 |
5 | int numOutputs;
6 | float [] outPuts;
7 | int numInputs;
8 | float [] inputs;
9 | int numHiddenNeurons1;
10 | int numHiddenNeurons2;
11 | float[][] weight1;
12 | float[][] weight2;
13 | float[][] weight3;
14 | float[] bias1;
15 | float[] bias2;
16 |
17 | float[] hiddenNeurons1;
18 | float[] hiddenNeurons2;
19 |
20 |
21 | float maxInpulse;
22 | float mutation;
23 |
24 | Brain(){
25 | // NOTE: two out puts
26 | numOutputs = 2;
27 | outPuts = new float[numOutputs];
28 | // satellite pos, satellite vell, sun pos
29 | numInputs = 2+2+2;
30 | inputs = new float[numInputs];
31 | numHiddenNeurons1 = 5;
32 | numHiddenNeurons2 = 3;
33 | weight1 = new float[numInputs][numHiddenNeurons1];
34 | weight2 = new float[numHiddenNeurons1][numHiddenNeurons2];
35 | weight3 = new float[numHiddenNeurons2][numOutputs];
36 | bias1 = new float[numHiddenNeurons1];
37 | bias2 = new float[numHiddenNeurons2];
38 | initWeights();
39 | hiddenNeurons1 = new float[numHiddenNeurons1];
40 | hiddenNeurons2 = new float[numHiddenNeurons2];
41 |
42 | mutation = 0.05;
43 | maxInpulse = 0.001;
44 | }
45 |
46 | void initWeights(){
47 | //weight1
48 | for(int i = 0; imaxInpulse)
120 | outPuts[i] = maxInpulse;
121 | else if (outPuts[i]<-maxInpulse)
122 | outPuts[i] = -maxInpulse;
123 | }
124 |
125 | // transfor out put to PVector
126 | PVector inpulse = new PVector(0.0, 0.0);
127 |
128 | inpulse.x = outPuts[0];
129 | inpulse.y = outPuts[1];
130 |
131 | return inpulse;
132 | }
133 |
134 | // GA operations
135 | void mutation (){
136 | //weight1
137 | for(int i = 0; i sunsPos){
81 |
82 | // get inputs and normaliz
83 | inputs[0] = satPos.x/width;
84 | inputs[1] = satPos.y/(0.63*height);
85 | inputs[2] = satVel.x/maxInpulse;
86 | inputs[3] = satVel.y/maxInpulse;
87 | for(int i=4; i<(4+sunsPos.size()); i++){
88 | PVector sunPos = sunsPos.get(i-4);
89 | inputs[i] = sunPos.x/width;
90 | inputs[i] = sunPos.y/(0.63*height);
91 | }
92 |
93 | // calculate hidden neurons
94 | // layer 1
95 | for(int i = 0; imaxInpulse)
123 | outPuts[i] = maxInpulse;
124 | else if (outPuts[i]<-maxInpulse)
125 | outPuts[i] = -maxInpulse;
126 | }
127 |
128 | // transfor out put to PVector
129 | PVector inpulse = new PVector(0.0, 0.0);
130 |
131 | inpulse.x = outPuts[0];
132 | inpulse.y = outPuts[1];
133 |
134 | return inpulse;
135 | }
136 |
137 | // GA operations
138 | void mutation (){
139 | //weight1
140 | for(int i = 0; i