www.pudn.com > 基于VC的神经网络开发程序包(源码).rar > HopfieldNetwork.cpp
#include "../include/HopfieldNetwork.h" #include "../include/Exception.h" #include "../include/File.h" #includeusing namespace std; namespace annie { real isPositive(real x) { return (real)((x<=(real)0.0)?0.0:1.0); } HopfieldNetwork::HopfieldNetwork(int size) : Network(0,size) { int i,j; _nPatterns = 0; _time = 0; _bipolar = true; //Add the neurons _neurons = new RecurrentNeuron*[size]; for (i=0; i reset((real)0.0); nrn->setActivationFunction(signum,NULL); _neurons[i] = nrn; } //create an intialize the weight matrix and connect neurons _weightMatrix = new Matrix(size,size); for (i=0; i elementAt(i,j)=(real)0.0; _neurons[i]->connect(_neurons[j],(real)0.0); } } HopfieldNetwork::HopfieldNetwork(int size, bool bias, bool bipolar) : Network(0,size) { int i,j; _nPatterns = 0; _time = 0; _bipolar = bipolar; //create an intialize the weight matrix _weightMatrix = new Matrix(size,size); for (i=0; i elementAt(i,j)=(real)0.0; //Add the neurons _neurons = new RecurrentNeuron*[size]; for (i=0; i reset((real)0.0); if (bipolar) nrn->setActivationFunction(signum,NULL); else nrn->setActivationFunction(isPositive,NULL); _neurons[i] = nrn; } //connect the neurons for (i=0; i connect(_neurons[j],_weightMatrix->elementAt(i,j)); } HopfieldNetwork::HopfieldNetwork(const char *filename) : Network(0,0) { File file; int i,j; _time = 0; try { file.open(filename); } catch (Exception &e) { string error(getClassName()); error = error + "::" + getClassName() + "() - " + e.what(); throw Exception(error); } string s; s=file.readWord(); if (s.compare(getClassName())!=0) { string error(getClassName()); error = error + "::" + getClassName() + "() - File supplied is not about this type of network."; throw Exception(error); } _nInputs = 0; while (!file.eof()) { s=file.readWord(); if (!s.compare("SIZE")) { int size = file.readInt(); _nOutputs = size; _neurons = new RecurrentNeuron*[size]; _weightMatrix = new Matrix(size,size); for (i=0; i setActivationFunction(signum,NULL); else _neurons[i]->setActivationFunction(isPositive,NULL); _neurons[i]->reset((real)0.0); } } else if (!s.compare("WEIGHT_MATRIX")) { int size = getSize(); for (i=0; i setBias(file.readDouble()); else n->removeBias(); } } else if (!s.compare("BEGIN_META_DATA")) { static const basic_string ::size_type npos = (basic_string ::size_type)-1; string end("END_META_DATA"); string metaData; s = file.readLine(); while (s.find(end,0)==npos) { metaData = metaData + s + "\n"; s = file.readLine(); } if (metaData.length()>0) metaData.erase(metaData.length()-1); setMetaData(metaData); } else cerr< \" if the neuron has bias, \"f\" otherwise"< hasBias()) s<<"t "<<_neurons[i]->getBias(); else s<<"f"; s< output = getOutput(); vector ::iterator it; VECTOR answer; for (it = output.begin(); it!=output.end(); it++) answer.push_back((real)(*it)); return answer; } void HopfieldNetwork::setInput(vector &initialState) { _time = 0; for (int i=0; i reset((real)initialState[i]); } void HopfieldNetwork::setInput(int initialState[]) { _time = 0; for (int i=0; i reset((real)initialState[i]); } void HopfieldNetwork::step() { //we need to step only one neuron because doing so will cause all others //to be stepped anyway _neurons[0]->step(); _time++; } vector HopfieldNetwork::getNextOutput() { step(); return getOutput(); } vector HopfieldNetwork::getOutput() { vector answer; for (int i=0;i<_nOutputs;i++) answer.push_back((int)_neurons[i]->getOutput()); return answer; } int HopfieldNetwork::getTime() { return _time; } void HopfieldNetwork::addPattern(int pattern[]) { int i,j; //keeping the diagonal of the matrix 0 int size = getSize(); for (i=0; i elementAt(i,j); temp *= getSize(); temp += pattern[i]*pattern[j]; temp /= getSize(); setWeight(i,j,temp); } } _nPatterns++; } int HopfieldNetwork::getPatternCount() { return _nPatterns; } int HopfieldNetwork::getSize() { return getOutputCount(); } void HopfieldNetwork::setWeight(int i, int j, real weight) { _weightMatrix->elementAt(i,j)=weight; _weightMatrix->elementAt(j,i)=weight; _neurons[i]->connect(_neurons[j],weight); _neurons[j]->connect(_neurons[i],weight); } Matrix HopfieldNetwork::getWeightMatrix() { Matrix m(*_weightMatrix); return m; } real HopfieldNetwork::getEnergy() { real energy = 0.0; for (int i=0; i elementAt(i,j); real outI = _neurons[i]->getOutput(); real outJ = _neurons[j]->getOutput(); energy += weight*outI*outJ; } return -1*energy; } real HopfieldNetwork::getEnergy(int pattern[]) { real energy = 0.0; for (int i=0; i elementAt(i,j); energy += weight*pattern[i]*pattern[j]; } return -1*energy; } void HopfieldNetwork::setBias(int i, real bias) { if (i>=getSize()) { string error(getClassName()); error=error+"::setBias() - Invalid neuron number specified"; throw Exception(error); } _neurons[i]->setBias(bias); } real HopfieldNetwork::getBias(int i) { if (i>=getSize()) { string error(getClassName()); error=error+"::getBias() - Invalid neuron number specified"; throw Exception(error); } return _neurons[i]->getBias(); } bool HopfieldNetwork::propagate(int pattern[], int timeout) { vector p; for (int i=0; i<_nOutputs; i++) p.push_back(pattern[i]); return propagate(p,timeout); } bool HopfieldNetwork::propagate(vector &pattern, int timeout) { setInput(pattern); vector last; vector curr; last = pattern; int time = 0; while (time < timeout) { curr = getNextOutput(); if (_equal(curr,last)) return true; last = curr; } return false; } bool HopfieldNetwork::_equal(vector &p1, vector &p2) { if (p1.size() != p2.size()) return false; vector ::iterator ip1,ip2; for (ip1 = p1.begin(), ip2 = p2.begin(); ip1 != p1.end(); ip1++, ip2++) if ((*ip1)!=(*ip2)) return false; return true; } }; //namespace annie