-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCreatureGA
129 lines (115 loc) · 4.22 KB
/
CreatureGA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
[System.Serializable]
public struct CreatureGA
{
public List<ForestFire> listOfForestFires;
public List<int> treesToRemove;
public int creatureId;
public ForestFire startingForestFire;
public float fitnessEvaluationNumber;
public void ResetAll(int id)
{
listOfForestFires = new List<ForestFire>();
this.creatureId = id;
this.treesToRemove = new List<int>(MitigationGA.listOfGenes[id]);
this.fitnessEvaluationNumber = 0;
this.startingForestFire = DeepCopy(MitigationGA.forestFire);
startingForestFire.creatureId = this.creatureId;
foreach (int treeId in treesToRemove)
{
Tree treeBeingChecked = startingForestFire.listOfTrees[treeId];
treeBeingChecked.dead = true;
startingForestFire.listOfTrees[treeId] = treeBeingChecked;
}
for (int i = 0; i < MitigationGA.forestFiresPerCreature; i++)
{
ForestFire ff = DeepCopy(startingForestFire);
ff.id = i;
ff.RandomizeWind();
ff.StartBurn();
this.listOfForestFires.Add(ff);
}
}
public void Run()
{
for (int i = 0; i < MitigationGA.forestFiresPerCreature; i++)
{
ForestFire forestFireRunning = this.listOfForestFires[i];
forestFireRunning.RunSimulation();
}
}
public void Render(Material nonBurningTree, Material burningTree, Material deadTree, int id)
{
int distanceBetween = (int)Mathf.Round(MitigationGA.forestFireSize * 1.5f);
int rendersPerLine = (int)Mathf.Floor(Mathf.Sqrt(MitigationGA.forestFiresPerCreature));
for (int y = 0; y < rendersPerLine; y++)
{
for (int x = 0; x < rendersPerLine; x++)
{
Vector2 displacement = new Vector2(x * distanceBetween, y * distanceBetween);
displacement += new Vector2(id * distanceBetween * rendersPerLine, 0);
Renderer.RenderAllTrees(this.listOfForestFires[(y * rendersPerLine) + x], nonBurningTree, burningTree, deadTree, displacement);
}
}
}
public void EvaluateFitness()
{
fitnessEvaluationNumber = 0;
for (int i = 0; i < this.listOfForestFires.Count; i++)
{
//FITNESS FUNCTION
fitnessEvaluationNumber += MitigationGA.numberOfTreesPerForest - (this.listOfForestFires[i].listOfAliveTreesIds.Count);
//fitnessEvaluationNumber += this.treesToRemove.Count;
}
}
public List<int> CreateGenesFromParent(List<int> parent)
{
List<int> x = new List<int>(this.treesToRemove);
List<int> y = new List<int>(parent);
List<int> z = new List<int>();
int geneLength = (Functions.randomInt(1, 2) == 1 ? x.Count : y.Count);
for (int i = 0; i < MitigationGA.mutationRepetition; i++)
{
geneLength += (Functions.randomInt(1, MitigationGA.mutationRate) == 1 ? (Functions.randomInt(1, 2) == 1 ? -1 : 1) : 0);
}
geneLength = Mathf.Clamp(geneLength, 1, MitigationGA.numberOfTreesPerForest - 1);
for (int i = 0; i < geneLength; i++)
{
int geneToAdd;
if (x.Count != 0 && y.Count != 0)
{
if (Functions.randomInt(1, 2) == 1)
{
geneToAdd = x[Functions.randomInt(0, x.Count - 1)];
}
else
{
geneToAdd = y[Functions.randomInt(0, y.Count - 1)];
}
x.Remove(geneToAdd);
y.Remove(geneToAdd);
z.Add(geneToAdd);
}
else
{
break;
}
}
return z;
}
public static T DeepCopy<T>(T item)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, item);
stream.Seek(0, SeekOrigin.Begin);
T result = (T)formatter.Deserialize(stream);
stream.Close();
return result;
}
}