Skip to content

Commit 8264ff1

Browse files
Added feature to optimize generated code by adding a bonus for the least number of instructions executed.
1 parent 9eca78d commit 8264ff1

File tree

5 files changed

+48
-157
lines changed

5 files changed

+48
-157
lines changed

Diff for: AIProgrammer.GA/GA.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace AIProgrammer.GeneticAlgorithm
4545
public class GA
4646
{
4747
public GAParams GAParams { get; set; }
48+
public bool Stop = false;
4849

4950
/// <summary>
5051
/// Default constructor sets mutation rate to 5%, crossover to 80%, population to 100,
@@ -114,7 +115,7 @@ public void Go(bool resume = false)
114115
RankPopulation();
115116
}
116117

117-
while (GAParams.CurrentGeneration < GAParams.Generations)
118+
while (GAParams.CurrentGeneration < GAParams.Generations && !Stop)
118119
{
119120
CreateNextGeneration();
120121
double fitness = RankPopulation();

Diff for: AIProgrammer.Interpreter/Interpreter.cs

+17-5
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ public class Interpreter
6666
/// </summary>
6767
private bool m_ExitLoop;
6868

69+
/// <summary>
70+
/// Count of number of instructions executed.
71+
/// </summary>
72+
public int m_Ticks;
73+
6974
/// <summary>
7075
/// Constructor
7176
/// </summary>
@@ -74,6 +79,9 @@ public class Interpreter
7479
/// <param name="output"></param>
7580
public Interpreter(string programCode, Func<byte> input, Action<byte> output)
7681
{
82+
// Initialize tick counter (number of instructions executed).
83+
this.m_Ticks = 0;
84+
7785
// Save the program code
7886
this.m_Source = programCode.ToCharArray();
7987

@@ -127,7 +135,7 @@ public Interpreter(string programCode, Func<byte> input, Action<byte> output)
127135
/// <summary>
128136
/// Run the program
129137
/// </summary>
130-
public void Run(int maxInstructions = 0)
138+
public void Run(int maxInstructions)
131139
{
132140
if (maxInstructions > 0)
133141
{
@@ -145,8 +153,6 @@ public void Run(int maxInstructions = 0)
145153
/// <param name="maxInstructions">Max number of instructions to execute</param>
146154
private void RunLimited(int maxInstructions)
147155
{
148-
int instructionCount = 0;
149-
150156
// Iterate through the whole program source
151157
while (this.m_InstructionPointer < this.m_Source.Length)
152158
{
@@ -165,10 +171,13 @@ private void RunLimited(int maxInstructions)
165171
this.m_InstructionPointer++;
166172

167173
// Have we exceeded the max instruction count?
168-
if (maxInstructions > 0 && instructionCount++ > maxInstructions)
174+
if (maxInstructions > 0 && m_Ticks >= maxInstructions)
169175
{
170-
throw new StackOverflowException();
176+
break;
171177
}
178+
179+
// Increment number of instructions executed.
180+
m_Ticks++;
172181
}
173182
}
174183

@@ -193,6 +202,9 @@ private void RunUnlimited()
193202

194203
// Next instruction
195204
this.m_InstructionPointer++;
205+
206+
// Increment number of instructions executed.
207+
m_Ticks++;
196208
}
197209
}
198210
}

Diff for: AIProgrammer/AIProgrammer.csproj

-5
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@
3232
<WarningLevel>4</WarningLevel>
3333
</PropertyGroup>
3434
<ItemGroup>
35-
<Reference Include="NeuronDotNet.Core, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
36-
<SpecificVersion>False</SpecificVersion>
37-
<HintPath>lib\NeuronDotNet.Core.dll</HintPath>
38-
</Reference>
3935
<Reference Include="System" />
4036
<Reference Include="System.Core" />
4137
<Reference Include="System.Xml.Linq" />
@@ -45,7 +41,6 @@
4541
<Reference Include="System.Xml" />
4642
</ItemGroup>
4743
<ItemGroup>
48-
<Compile Include="Cleaner.cs" />
4944
<Compile Include="Program.cs" />
5045
<Compile Include="Properties\AssemblyInfo.cs" />
5146
</ItemGroup>

Diff for: AIProgrammer/Cleaner.cs

-138
This file was deleted.

Diff for: AIProgrammer/Program.cs

+29-8
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,26 @@ class Program
2121
{
2222
private static GA _ga = null; // Our genetic algorithm instance.
2323
private static double _bestFitness = 0; // Best fitness so far.
24+
private static double _bestTrueFitness = 0; // Best fitness so far, without optimization bonus.
2425
private static string _bestProgram = ""; // Best program so far.
2526
private static string _bestOutput = ""; // Best program output so far.
26-
private static int _besIiteration = 0; // Current iteration (generation) count.
27+
private static int _bestIteration = 0; // Current iteration (generation) count.
28+
private static int _bestTotalInstructions = 0; // Number of instructions executed by the best program.
2729
private static bool _bestNoErrors = false; // Indicator if the program had errors or not.
2830
private static DateTime _bestLastChangeDate = DateTime.Now; // Time of last improved evolution.
2931
private static int _maxIterationCount = 2000; // Max iterations a program may run before being killed (prevents infinite loops).
30-
private static string _targetString = "hello"; // Target string to generate a program to print.
32+
private static string _targetString = "reddit"; // Target string to generate a program to print.
33+
private static int _targetFitness = _targetString.Length * 256;
3134

3235
/// <summary>
3336
/// Event handler that is called upon each generation. We use this opportunity to display some status info and save the current genetic algorithm in case of crashes etc.
3437
/// </summary>
3538
private static void OnGeneration(GA ga)
3639
{
37-
if (_besIiteration++ > 1000)
40+
if (_bestIteration++ > 1000)
3841
{
39-
_besIiteration = 0;
40-
Console.WriteLine("Best Fitness: " + _bestFitness + "/" + ga.GAParams.TargetFitness + " " + Math.Round(_bestFitness / ga.GAParams.TargetFitness * 100) + "%, Best Output: " + _bestOutput + ", Changed: " + _bestLastChangeDate.ToString() + ", Program: " + _bestProgram);
42+
_bestIteration = 0;
43+
Console.WriteLine("Best Fitness: " + _bestTrueFitness + "/" + _targetFitness + " " + Math.Round(_bestTrueFitness / _targetFitness * 100) + "%, Ticks: " + _bestTotalInstructions + ", Output: " + _bestOutput + ", Changed: " + _bestLastChangeDate.ToString() + ", Program: " + _bestProgram);
4144

4245
ga.Save("my-genetic-algorithm.dat");
4346
}
@@ -50,7 +53,9 @@ private static void OnGeneration(GA ga)
5053
/// <returns>double, indicating the score</returns>
5154
private static double fitnessFunction(double[] weights)
5255
{
56+
Interpreter bf = null;
5357
double fitness = 0;
58+
double trueFitness = 0; // fitness without secondary bonuses (ie., optimization, etc)
5459
string console = "";
5560
bool noErrors = false;
5661

@@ -60,7 +65,7 @@ private static double fitnessFunction(double[] weights)
6065
try
6166
{
6267
// Run the program.
63-
Interpreter bf = new Interpreter(program, null, (b) =>
68+
bf = new Interpreter(program, null, (b) =>
6469
{
6570
console += (char)b;
6671
});
@@ -78,18 +83,34 @@ private static double fitnessFunction(double[] weights)
7883
{
7984
if (console.Length > i)
8085
{
81-
fitness += 256 - Math.Abs(console[i] - _targetString[i]);
86+
trueFitness += 256 - Math.Abs(console[i] - _targetString[i]);
8287
}
8388
}
8489

90+
fitness += trueFitness;
91+
92+
// Did we find a perfect fitness?
93+
if (trueFitness >= _targetFitness)
94+
{
95+
// We're done! Stop the GA algorithm.
96+
// Note, you can alternatively use the _ga.GAParams.TargetFitness to set a specific fitness to achieve.
97+
// In our case, the number of ticks (instructions executed) is a variable part of the fitness, so we don't know the exact perfect fitness value once this part is added.
98+
_ga.Stop = true;
99+
}
100+
101+
// Bonus for less operations to optimize the code.
102+
fitness += ((_maxIterationCount - bf.m_Ticks) / 10);
103+
85104
// Is this a new best fitness?
86105
if (fitness > _bestFitness)
87106
{
88107
_bestFitness = fitness;
108+
_bestTrueFitness = trueFitness;
89109
_bestOutput = console;
90110
_bestNoErrors = noErrors;
91111
_bestLastChangeDate = DateTime.Now;
92112
_bestProgram = program;
113+
_bestTotalInstructions = bf.m_Ticks;
93114
}
94115

95116
return fitness;
@@ -130,7 +151,7 @@ private static double[] Setup()
130151

131152
// Start a new genetic algorithm.
132153
_ga.GAParams.Elitism = true;
133-
_ga.GAParams.TargetFitness = _targetString.Length * 256;
154+
//_ga.GAParams.TargetFitness = _targetFitness;
134155
_ga.GAParams.HistoryPath = System.IO.Directory.GetCurrentDirectory() + "\\history.txt";
135156
_ga.FitnessFunction = new GAFunction(fitnessFunction);
136157
_ga.OnGenerationFunction = new OnGeneration(OnGeneration);

0 commit comments

Comments
 (0)