summaryrefslogtreecommitdiffstats
path: root/ai/Net.cpp
diff options
context:
space:
mode:
authorBen Boeckel <MathStuf@gmail.com>2007-10-26 20:46:09 +0000
committerBen Boeckel <MathStuf@gmail.com>2007-10-26 20:46:09 +0000
commit4385af885daf460a18e236f08509358f764b2c8c (patch)
tree6c2838312dd7f42769280e24e8abc16b53c165cb /ai/Net.cpp
parent1f08afc80c73087bf9bde639754670548b89fc9f (diff)
Reverted repo back to rev24 because committing of rev25 messed up
git-svn-id: https://pokegen.svn.sourceforge.net/svnroot/pokegen/trunk@26 6ecfd1a5-f3ed-3746-8530-beee90d26b22
Diffstat (limited to 'ai/Net.cpp')
-rw-r--r--ai/Net.cpp290
1 files changed, 290 insertions, 0 deletions
diff --git a/ai/Net.cpp b/ai/Net.cpp
new file mode 100644
index 00000000..cd72fd6b
--- /dev/null
+++ b/ai/Net.cpp
@@ -0,0 +1,290 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: ai/Net.cpp
+// Purpose: An artificial neural network class
+// Author: Ben Boeckel
+// Modified by: Ben Boeckel
+// Created: Fri May 4 19:56:27 2007
+// Copyright: ©2007 Nerdy Productions
+// Licence:
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>.
+/////////////////////////////////////////////////////////////////////////////
+
+#include "Net.h"
+
+PokeGen::NeuralNetwork::Net::Net(const QList<unsigned>& nodes)
+{
+ for (int i = 0; i < nodes.size(); ++i)
+ AddLayer(i, nodes[i]);
+}
+
+void PokeGen::NeuralNetwork::Net::SaveData(const QString& fname) const
+{
+ Ini nnData("NeuralNet");
+ nnData.AddField("numLayers", GetNumLayers());
+ for (unsigned i = 0; i < GetNumLayers(); ++i)
+ layers[i].SaveData(nnData, i);
+ nnData.Export(fname);
+}
+
+PokeGen::NeuralNetwork::Net* PokeGen::NeuralNetwork::Net::LoadData(const QString& fname)
+{
+ Ini t;
+
+
+ Net* temp = new Net;
+ QFile fin(fname);
+ fin.open(QIODevice::ReadOnly | QIODevice::Text);
+ if (fin.isOpen())
+ {
+ char next;
+ while (fin.getChar(&next))
+ {
+ if (next == '-')
+ {
+ bool ok;
+ unsigned i = QString(fin.readLine()).toUInt(&ok);
+ if (ok)
+ {
+ temp->AddLayer(temp->GetNumLayers(), i);
+ for (unsigned j = 0; (j < i) && fin.getChar(&next); ++j)
+ {
+ if (next == '+')
+ {
+ if (!temp->layers[temp->GetNumLayers() - 1].AddNode(fin.readLine()))
+ {
+ delete temp;
+ return NULL;
+ }
+ }
+ else
+ {
+ delete temp;
+ return NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ delete temp;
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ delete temp;
+ return NULL;
+ }
+ return temp;
+}
+
+void PokeGen::NeuralNetwork::Net::AddLayer(const unsigned place, const unsigned numNodes)
+{
+ AddLayer(place, Layer(numNodes));
+}
+
+void PokeGen::NeuralNetwork::Net::AddLayer(const unsigned place, const Layer& layer)
+{
+ if (place <= GetNumLayers())
+ {
+ layers.insert(place, layer);
+ if (place)
+ {
+ layers[place - 1].SetChild(&layers[place]);
+ layers[place].SetParent(&layers[place - 1]);
+ }
+ if ((place + 1) < GetNumLayers())
+ {
+ layers[place].SetChild(&layers[place + 1]);
+ layers[place + 1].SetParent(&layers[place]);
+ }
+ }
+}
+
+bool PokeGen::NeuralNetwork::Net::DeleteLayer(const unsigned place)
+{
+ if (place < GetNumLayers())
+ {
+ if (place)
+ layers[place - 1].SetChild(layers[place].child);
+ if ((place + 1) < GetNumLayers())
+ layers[place + 1].SetParent(layers[place].parent);
+ layers.removeAt(place);
+ return true;
+ }
+ return false;
+}
+
+void PokeGen::NeuralNetwork::Net::FeedForward()
+{
+ for (QList<Layer>::Iterator i = layers.begin(); i != layers.end(); ++i)
+ i->CalculateValues();
+}
+
+void PokeGen::NeuralNetwork::Net::BackPropagate()
+{
+ if (GetNumLayers())
+ {
+ QMutableListIterator<Layer> i(layers);
+ for (i.toBack(); i.hasPrevious();)
+ i.previous().CalculateErrors();
+ if (1 < GetNumLayers())
+ {
+ for (i.toBack(), i.previous(); i.hasPrevious();)
+ i.previous().AdjustWeights();
+ }
+ }
+}
+
+double PokeGen::NeuralNetwork::Net::CalculateError()
+{
+ if (GetNumLayers())
+ {
+ double error = 0;
+ for (unsigned i = 0; i < layers[GetNumLayers() - 1].GetNumNodes(); ++i)
+ error += pow(layers[GetNumLayers() - 1].GetOutput(i) - layers[GetNumLayers() - 1].GetDesired(i), 2);
+ return (error / layers[GetNumLayers() - 1].GetNumNodes());
+ }
+ return 0;
+}
+
+unsigned PokeGen::NeuralNetwork::Net::GetChoice() const
+{
+ if (GetNumLayers())
+ {
+ double max = -DBL_MAX;
+ unsigned choice = 0;
+ for (unsigned i = 0; i < layers[GetNumLayers() - 1].GetNumNodes(); ++i)
+ {
+ if (max < GetOutput(i))
+ {
+ max = GetOutput(i);
+ choice = i;
+ }
+ }
+ return choice;
+ }
+ return UINT_MAX;
+}
+
+unsigned PokeGen::NeuralNetwork::Net::GetNumLayers() const
+{
+ return layers.size();
+}
+
+unsigned PokeGen::NeuralNetwork::Net::GetNumNodes(const unsigned layer) const
+{
+ if (layer < GetNumLayers())
+ return layers[layer].GetNumNodes();
+ return 0;
+}
+
+bool PokeGen::NeuralNetwork::Net::SetInput(const unsigned n, const double i)
+{
+ if (GetNumLayers())
+ return layers[0].SetInput(n, i);
+ return false;
+}
+
+bool PokeGen::NeuralNetwork::Net::SetDesired(const unsigned n, const double o)
+{
+ if (GetNumLayers())
+ return layers[GetNumLayers() - 1].SetDesired(n, o);
+ return false;
+}
+
+bool PokeGen::NeuralNetwork::Net::SetMomentum(const unsigned layer, const unsigned n, const double m)
+{
+ if (layer < GetNumLayers())
+ return layers[layer].SetMomentum(n, m);
+ return false;
+}
+
+bool PokeGen::NeuralNetwork::Net::SetMomentumFactor(const unsigned layer, const unsigned n, const double m)
+{
+ if (layer < GetNumLayers())
+ return layers[layer].SetMomentumFactor(n, m);
+ return false;
+}
+
+bool PokeGen::NeuralNetwork::Net::SetLearnRate(const unsigned layer, const unsigned n, const double l)
+{
+ if (layer < GetNumLayers())
+ return layers[layer].SetLearnRate(n, l);
+ return false;
+}
+
+bool PokeGen::NeuralNetwork::Net::SetFunction(const unsigned layer, const unsigned n, const unsigned f)
+{
+ if (layer < GetNumLayers())
+ return layers[layer].SetFunction(n, f);
+ return false;
+}
+
+double PokeGen::NeuralNetwork::Net::GetOutput(const unsigned n) const
+{
+ if (GetNumLayers())
+ return layers[GetNumLayers() - 1].GetOutput(n);
+ return 0;
+}
+
+double PokeGen::NeuralNetwork::Net::GetError(const unsigned layer, const unsigned n) const
+{
+ if (layer < GetNumLayers())
+ return layers[layer].GetError(n);
+ return 0;
+}
+
+double PokeGen::NeuralNetwork::Net::GetMomentum(const unsigned layer, const unsigned n) const
+{
+ if (layer < GetNumLayers())
+ return layers[layer].GetMomentum(n);
+ return 0;
+}
+
+double PokeGen::NeuralNetwork::Net::GetMomentumFactor(const unsigned layer, const unsigned n) const
+{
+ if (layer < GetNumLayers())
+ return layers[layer].GetMomentumFactor(n);
+ return 0;
+}
+
+double PokeGen::NeuralNetwork::Net::GetLearnRate(const unsigned layer, const unsigned n) const
+{
+ if (layer < GetNumLayers())
+ return layers[layer].GetLearnRate(n);
+ return 0;
+}
+
+unsigned PokeGen::NeuralNetwork::Net::GetFunction(const unsigned layer, const unsigned n) const
+{
+ if (layer < GetNumLayers())
+ return layers[layer].GetFunction(n);
+ return 0;
+}
+
+double PokeGen::NeuralNetwork::Net::GetWeight(const unsigned layer, const unsigned n, const unsigned i) const
+{
+ if (layer < GetNumLayers())
+ return layers[layer].GetWeight(n, i);
+ return 0;
+}
+
+double PokeGen::NeuralNetwork::Net::GetBias(const unsigned layer, const unsigned n) const
+{
+ if (layer < GetNumLayers())
+ return layers[layer].GetBias(n);
+ return 0;
+}