public static void CreateNetwork(string filename, params int[] layers)
{
Debug.Assert(layers.Length >= 2);
Debug.Assert(layers.Min() > 0);
const string inputNodeFormat = @" <Node type=""in"" id=""{0}"" />";
const string outputNodeFormat = @" <Node type=""out"" id=""{0}"" />";
const string hiddenNodeFormat = @" <Node type=""hid"" id=""{0}"" />";
int nextId = 1;
StringBuilder nodes = new StringBuilder();
int[][] layerIds = new int[layers.Length][];
for (int i = 0; i < layers.Length; i++)
layerIds[i] = new int[layers[i]];
// Add the input neurons
for (int i = 0; i < layers[0]; i++)
{
int id = nextId++;
nodes.AppendLine(string.Format(inputNodeFormat, id));
layerIds[0][i] = id;
}
// Add the output neurons (have to do this now because of conventions in SharpNEAT)
for (int i = 0; i < layers.Last(); i++)
{
int id = nextId++;
nodes.AppendLine(string.Format(outputNodeFormat, id));
layerIds[layers.Length - 1][i] = id;
}
// Add the hidden neurons
for (int i = 1; i < layers.Length - 1; i++)
for (int j = 0; j < layers[i]; j++)
{
int id = nextId++;
nodes.AppendLine(string.Format(hiddenNodeFormat, id));
layerIds[i][j] = id;
}
const string connectionFormat = @" <Con id=""{0}"" src=""{1}"" tgt=""{2}"" wght=""{3}"" />";
StringBuilder connections = new StringBuilder();
// Add the bias connections to all non-input nodes
int lastInput = nextId;
for (int i = layers[0] + 1; i < lastInput; i++)
connections.AppendLine(string.Format(connectionFormat, nextId++, 0, i, _random.NextDouble() * 10.0 - 5.0));
// Add the connections
// Note that you need to randomize these connections externally
for (int i = 1; i < layers.Length; i++)
for (int j = 0; j < layers[i]; j++)
for (int k = 0; k < layers[i - 1]; k++)
connections.AppendLine(string.Format(connectionFormat, nextId++, layerIds[i - 1][k], layerIds[i][j], _random.NextDouble() * 10.0 - 5.0));
using (TextWriter writer = new StreamWriter(filename))
writer.WriteLine(string.Format(NETWORK_FORMAT, nodes.ToString(), connections.ToString(), nextId++));
}