Skip to content

Commit 2898abf

Browse files
Performance enhancements and improved BottlesOfBeerFitness.
1 parent 634e19a commit 2898abf

File tree

4 files changed

+24
-18
lines changed

4 files changed

+24
-18
lines changed

AIProgrammer.Fitness/Base/FitnessBase.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,7 @@ public double GetFitness(double[] weights)
7171
// Append any functions to the program.
7272
if (_appendFunctions != null)
7373
{
74-
StringBuilder s = new StringBuilder(Program);
75-
s.Append("!");
76-
s.Append(_appendFunctions);
77-
Program = s.ToString();
74+
Program += "!" + _appendFunctions;
7875
}
7976

8077
// Get the fitness.

AIProgrammer.Fitness/Concrete/BottlesOfBeerFitness.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,14 @@ public class BottlesOfBeerFitness : FitnessBase
2020
{
2121
private static byte[][] _trainingExamples = { new byte[] { 5, 4, 3, 2, 1, 0 },
2222
new byte[] { 3, 2, 1, 0 },
23-
new byte[] { 2, 1, 0 }/*,
24-
new byte[] { 6, 5, 4, 3, 2, 1, 0 }*/ };
25-
private static string _targetString = "b";
23+
new byte[] { 2, 1, 0 } };
24+
private static string _targetString = "bottles of beer";
2625

2726
/// <summary>
28-
/// Previously generated BrainPlus functions for outputting the terms: bottles,of,beer,on,the,wall. This includes a 7th generated function that calls the other generated functions to output "bottles of beer". Generated using StrictStringFitness with StringFunction.
27+
/// Previously generated BrainPlus functions for outputting the terms: bottles,of,beer,bottles of beer. Generated using StrictStringFitness with StringFunction.
2928
/// To use, set _appendCode = BottlesOfBeerFitness.BottlesOfBeerFunctions in main program.
3029
/// </summary>
31-
public static string BottlesOfBeerFunctions = "&6++.+++++++++++++[.+++[++..--------.-------.++++++++++++++.-%&[]7[[-.---------.[][.+>[t[-]-[,]+>,>++<]<]],>[]><]],-<]++,><%&6++.+++..7++.[6+[+<>[>>-]>><>-.+.><><-]<.<].+]..+-<+]+.[...,%&+8[+[+]7-.-.>[22+[[-..[[<-...][,.,<<>,>,,.,,]+<<++,]+>+,+]>+%&6+t+++i++[++-+[+++++[+++++++.-----[-[--[--[--.[-+----+.-[[[>%&7++++++[+.------[--------[--------.+++++++-+++++..[+>+>[++[<%&1+++++++++++++>a---<+++.>.---------.<.c[>>>[<,,>+<[-],+<>.<,%&d2.[e2.f]--->2[>-]<[>]v-......<+[+<>+>]].,+,>[<++,>><,]-.>,+%";
30+
public static string BottlesOfBeerFunctions = "&6++.+++++++++++++[.+++[++..--------.-------.++++++++++++++.-%&[]7[[-.---------.%&6++.+++..7++.%&1+++++++++++++>a---<+++.>.---------.<.c%";
3231

3332
public BottlesOfBeerFitness(GA ga, int maxIterationCount, string appendFunctions = null)
3433
: base(ga, maxIterationCount, appendFunctions)
@@ -145,7 +144,7 @@ protected override void RunProgramMethod(string program)
145144
Console.Write(">: ");
146145
byte startingValue = Byte.Parse(Console.ReadLine());
147146
int index = 0;
148-
bool odd = true;
147+
int index2 = 0;
149148

150149
_console.Clear();
151150

@@ -171,7 +170,7 @@ protected override void RunProgramMethod(string program)
171170
(b) =>
172171
{
173172
// The program correctly solves the problem, however the output is in byte format. For example: 5b => 598 (where 98 = 'b'). We need to format the output for humans to read by leaving the numeric values as byte and the text values as char.
174-
if (odd)
173+
if (index2++ % (_targetString.Length + 1) == 0)
175174
{
176175
// Append numeric byte value.
177176
_console.Append(b);
@@ -181,8 +180,6 @@ protected override void RunProgramMethod(string program)
181180
// Append text.
182181
_console.Append((char)b);
183182
}
184-
185-
odd = !odd;
186183
});
187184

188185
bf.Run(_maxIterationCount);

AIProgrammer.GA/GA.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class GA : IGeneticAlgorithm
4747
{
4848
public GAParams GAParams { get; set; }
4949
public bool Stop { get; set; }
50+
private DateTime _lastEpoch = DateTime.Now;
5051

5152
/// <summary>
5253
/// Default constructor sets mutation rate to 5%, crossover to 80%, population to 100,
@@ -128,13 +129,15 @@ public void Go(bool resume = false)
128129

129130
if (GAParams.CurrentGeneration % 100 == 0)
130131
{
131-
Console.WriteLine("Generation " + GAParams.CurrentGeneration + ", Best Fitness: " + fitness);
132+
Console.WriteLine("Generation " + GAParams.CurrentGeneration + ", Time: " + Math.Round((DateTime.Now - _lastEpoch).TotalSeconds, 2) + "s, Best Fitness: " + fitness);
132133

133134
if (GAParams.HistoryPath != "")
134135
{
135136
// Record history timeline.
136137
File.AppendAllText(GAParams.HistoryPath, DateTime.Now.ToString() + "," + fitness + "," + GAParams.TargetFitness + "," + GAParams.CurrentGeneration + "\r\n");
137138
}
139+
140+
_lastEpoch = DateTime.Now;
138141
}
139142

140143
if (GAParams.TargetFitness > 0 && fitness >= GAParams.TargetFitness)

AIProgrammer.Interpreter/Interpreter.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class FunctionCallObj
3636
public int DataPointer { get; set; }
3737
public Stack<int> CallStack { get; set; }
3838
public bool ExitLoop { get; set; }
39+
public int ExitLoopInstructionPointer { get; set; }
3940
public int Ticks { get; set; }
4041
};
4142

@@ -93,7 +94,7 @@ public class FunctionCallObj
9394
/// <summary>
9495
/// The list of functions and their starting instruction index.
9596
/// </summary>
96-
private readonly Dictionary<char, int> m_Functions = new Dictionary<char, int>(26);
97+
private readonly Dictionary<char, int> m_Functions = new Dictionary<char, int>();
9798

9899
/// <summary>
99100
/// Identifier for next function. Will serve as the instruction to call this function.
@@ -110,6 +111,11 @@ public class FunctionCallObj
110111
/// </summary>
111112
private Stack<int> m_CurrentCallStack;
112113

114+
/// <summary>
115+
/// Number of cells available to functions for memory. When a function is executed, an array of cells are allocated in upper-memory addresses (eg., 1000-1999, 2000-2999, etc.) for usage.
116+
/// </summary>
117+
private const int _memoryAvailableForFunctions = 255;
118+
113119
/// <summary>
114120
/// Number of instructions executed.
115121
/// </summary>
@@ -228,6 +234,8 @@ public Interpreter(string programCode, Func<byte> input, Action<byte> output)
228234
this.m_CurrentCallStack = temp.CallStack;
229235
// Restore exit loop status.
230236
this.m_ExitLoop = temp.ExitLoop;
237+
// Restore exit loop instruction pointer.
238+
this.m_ExitLoopInstructionPointer = temp.ExitLoopInstructionPointer;
231239
// Restore ticks.
232240
this.m_Ticks = temp.Ticks;
233241
// Restore the instruction pointer.
@@ -244,21 +252,22 @@ public Interpreter(string programCode, Func<byte> input, Action<byte> output)
244252
this.m_InstructionSet.Add(instruction, () =>
245253
{
246254
// Store the current instruction pointer and data pointer before we move to the function.
247-
var functionCallObj = new FunctionCallObj { InstructionPointer = this.m_InstructionPointer, DataPointer = this.m_DataPointer, CallStack = this.m_CurrentCallStack, ExitLoop = this.m_ExitLoop, Ticks = this.m_Ticks };
255+
var functionCallObj = new FunctionCallObj { InstructionPointer = this.m_InstructionPointer, DataPointer = this.m_DataPointer, CallStack = this.m_CurrentCallStack, ExitLoop = this.m_ExitLoop, ExitLoopInstructionPointer = this.m_ExitLoopInstructionPointer, Ticks = this.m_Ticks };
248256
this.m_FunctionCallStack.Push(functionCallObj);
249257

250258
// Give the function a fresh call stack.
251259
this.m_CurrentCallStack = new Stack<int>();
252260
this.m_ExitLoop = false;
261+
this.m_ExitLoopInstructionPointer = 0;
253262

254263
// Get current memory value to use as input for the function.
255264
var inputValue = this.m_Memory[this.m_DataPointer];
256265

257266
// Set the data pointer to the functions starting memory address.
258-
this.m_DataPointer = 1000 * (instruction - 96); // each function gets a space of 1000 memory slots.
267+
this.m_DataPointer = _memoryAvailableForFunctions * (instruction - 96); // each function gets a space of 1000 memory slots.
259268

260269
// Clear function memory.
261-
Array.Clear(this.m_Memory, this.m_DataPointer, 1000);
270+
Array.Clear(this.m_Memory, this.m_DataPointer, _memoryAvailableForFunctions);
262271

263272
// Copy the input value to the function's starting memory address.
264273
this.m_Memory[this.m_DataPointer] = inputValue;

0 commit comments

Comments
 (0)