⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 network.cpp

📁 也是遗传算法的源代码
💻 CPP
字号:
/***************************************************************************                          network.cpp  -  description                             -------------------    copyright            : (C) 2001, 2002 by Matt Grover    email                : mgrover@amygdala.org ***************************************************************************//*************************************************************************** *                                                                         * *   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 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/// Uncomment for debugging messages//#define DEBUG_NETWORKusing namespace std;#include "types.h"#include <math.h>#include <stdio.h>#include <iostream>#include <string>#include <iterator>#include <algorithm>#include <vector>#include <list>#if GCC_VERSION >= 30000    #include <ext/hash_map>#else    #include <hash_map>#endif#include "neuron.h"#include "basicneuron.h"#include "layer.h"#include "network.h"#include "simplespikeinput.h"#include "functionlookup.h"#include "utilities.h"#ifdef DEBUG_NETWORK#include <sys/time.h>#endifclass SimpleSpikeInput;Network::Network(){    // initialize the lookup tables    SetDefaults();    pspLRes = 100;  // unit = microseconds => 0.1 ms    pspLSize = 1000;    functionRef = new FunctionLookup();    spikeInput = new SimpleSpikeInput(this);    // default input object    netSize = 0;    eventRequestCount = 0;    isLayered = false;    runCount++;    trainingMode = true;    maxSpikeDelay = 0;    maxSpikeDelaySyn = 0;    currSpikeDelayOffset = 0;    maxOffset = 0;    spikeDelaysOn = false;    spikeBatchCount = 0;}void Network::SetDefaults(){    nextNeuronId = 1;    nextLayerId = 1;    streamingInput = false;}Network::~Network(){    // We don't know if the keys are contiguous    // in net, so use an iterator to delete    // Neurons instead of subscripting    hash_map<AmIdInt, Neuron*>::iterator netItr;    netItr = net.begin();    while (netItr != net.end()) {        delete netItr->second;        netItr->second = 0;        netItr++;    }    net.clear();    runCount--;    delete functionRef;    delete spikeInput;    for(layer_iterator layer = layers.begin(); layer != layers.end(); layer++){        delete layer->second;    }}// Initialize staticsAmTimeInt Network::simTime = 0;unsigned int Network::runCount = 0;AmTimeInt Network::simStepSize = 100;  // Default must match Neuron::simStepSize default!void Network::ResetSimTime(){    // FIXME: Some checks need to be developed to make    // sure that it is safe to reset simTime right now.    // For example, simTime should not be reset if    // any Networks are in the run loop.  This should    // maybe be done as part of a more general reset routine    // that clears out old data, etc.  A flag would have to be    // set to indicate to other instances that they need to reset, also.    simTime = 0;}void Network::SetTimeStepSize(AmTimeInt stepSize){    // FIXME: Need a static flag to keep this from running after    // neurons have been added to a net.    simStepSize = stepSize;    Neuron::simStepSize = stepSize;}Neuron* Network::AddNeuron(LayerType lType, AmIdInt nId){    if (nId >= nextNeuronId) {        nextNeuronId = nId + 1;    }    //cout << "Adding neuron " << nId << endl;    BasicNeuron* nrn = new BasicNeuron(nId);    net[nId] = nrn;    nrn->SetTableDimensions(pspLSize, pspLRes);    nrn->SetLookupTables(functionRef);    nrn->SetLayerType(lType);    nrn->SetParentNet(this);    nrn->TrainingOn(trainingMode);    return nrn;}Neuron* Network::AddNeuron(LayerType lType, Neuron* nrn){    AmIdInt nId = 0;    nId = nrn->GetID();    if (nId >= nextNeuronId) {        nextNeuronId = nId + 1;    }    //cout << "Adding neuron " << nId << endl;    net[nId] = nrn;    nrn->SetTableDimensions(pspLSize, pspLRes);    nrn->SetLookupTables(functionRef);    nrn->SetLayerType(lType);    nrn->SetParentNet(this);    nrn->TrainingOn(trainingMode);    return nrn;}bool Network::ConnectNeurons(Neuron* preSynapticNeuron,                                Neuron* postSynapticNeuron,                                float weight,                                AmTimeInt delay=0){// FIXME: Sign enforcement is not working. There is confusion//  as to when a neuron should be designated as inhibitory.//  This code should maybe run in the neuron instead, and//  a static function can set the enforceSign flag.// NOTE: EnforceSign() has been made a static member of Neuron,//  but this section of code has still not been tested. Remove//  the fixme once this is confirmed to work correctly.    if ( Neuron::EnforceSign() ) {        // Make sure weight has correct sign        if ( preSynapticNeuron->Inhibitory() ) {            if (weight > 0.0) {                cerr << "Inhibitory neuron " << preSynapticNeuron->GetID() <<                    " has a positive weight!\n";                return false;            }        }        else if (weight < 0.0) {            cerr << "Excitatory neuron " << preSynapticNeuron->GetID() <<                " has a negative weight!\n";            return false;        }    }    try {        Synapse* syn = new Synapse(postSynapticNeuron, weight, delay);        preSynapticNeuron->AddSynapse(syn);        if (delay > maxSpikeDelay) {            maxSpikeDelay = delay;            maxSpikeDelaySyn = syn;        }    }    catch(string& e) {        cerr << e << endl;        return false;    }    catch(...) {        cerr << "An error occured while connecting the neurons.\n";        return false;    }    return true;}bool Network::ConnectNeurons(AmIdInt preSynapticNeuron,                                AmIdInt postSynapticNeuron,                                float weight,                                AmTimeInt delay=0){    return ConnectNeurons(net[preSynapticNeuron], net[postSynapticNeuron], weight, delay);}void Network::AddLayer(Layer* newLayer){    unsigned int lId = newLayer->LayerId();    if (!lId) {        lId = nextLayerId;        newLayer->SetLayerId(lId);    }    if (lId >= nextLayerId) {        nextLayerId = lId + 1;    }    // we don't want duplicate Layer IDs    for(layer_iterator layer = layers.begin(); layer != layers.end(); layer++){        Layer *l = layer->second;        if(l->LayerId() == lId) throw string("Layer ID: " + Utilities::itostr(lId) + " already in use");    }    layers[newLayer->LayerId()] = newLayer;    newLayer->SetLayerParent(this);    isLayered = true;}void Network::ScheduleNEvent(NEvent eventType,                            AmTimeInt eventTime,                            Neuron* reqNrn){    SpikeRequest newSpike;    if (eventType > RMSPIKE) {        // initialize a new event request        newSpike.requestTime = simTime;        newSpike.requestor = reqNrn;        newSpike.spikeTime = eventTime;        newSpike.requestOrder = eventRequestCount++;        // insert into the queue        if (eventType == SPIKE || eventType == RESPIKE) {            eventQ.push(newSpike);        }        else if (eventType == INPUTSPIKE) {            inputQ.push(newSpike);        }    }}void Network::ScheduleNEvent(NEvent eventType,                            AmTimeInt eventTime,                            AmIdInt reqNrnId){    Neuron* nrn = net.find(reqNrnId)->second;    if (nrn) {        ScheduleNEvent(eventType, eventTime, nrn);    }    else {        string errMsg = "Neuron ID could not be found.";        throw errMsg;    }}void Network::Run(AmTimeInt maxRunTime){    // This is the main loop    // If streaming input is being used, keep on going until simTime >= maxRunTime.    // Otherwise, run until the event queue is empty or    // until simTime >= maxRunTime -- whichever happens first.    bool stopRun = false;    const unsigned int stopTime = maxRunTime + simTime;    AmTimeInt nextInputTime = 0;  	#ifdef DEBUG_NETWORK  	timeval time1;  	timeval time2;    int totalTime;    #endif    if (simTime == 0)        simTime = simStepSize;    // Initialize the delayed spike queue if it has not been done.    if (!delayedSpikeQ.size()) {        InitializeDelayedSpikeQ();    }    if (eventQ.empty() && inputQ.empty()) {        if(!streamingInput) {            stopRun = true;        }        else {            stopRun = false;        }    }    else {        if (!inputQ.empty()) {            nextInputTime = inputQ.top().spikeTime;        }        else {            nextInputTime = 0;        }        stopRun = false;    }    while (!stopRun) {        while (!eventQ.empty()) {            const SpikeRequest& topSpike = eventQ.top();            if (topSpike.spikeTime != simTime)                break;            #ifdef DEBUG_NETWORK            cout << "\nSending spike from Neuron: " << topSpike.requestor->GetID() << endl;            gettimeofday(&time1, NULL);            #endif            topSpike.requestor->SendSpike(simTime);            eventQ.pop();            #ifdef DEBUG_NETWORK            gettimeofday(&time2, NULL);            totalTime = time2.tv_usec - time1.tv_usec;            cout << "\nTotal time for sending spike: " << totalTime << "us" << endl;            #endif  	        }        if (streamingInput) {            spikeInput->ReadInputBuffer();            if (!inputQ.empty()) {                nextInputTime = inputQ.top().spikeTime;            }            else {                nextInputTime = 0;            }        }        while (nextInputTime <= simTime) {            if (nextInputTime == 0)                break;            inputQ.top().requestor->SendSpike(simTime);            inputQ.pop();            if (!inputQ.empty()) {                nextInputTime = inputQ.top().spikeTime;            }            else {                nextInputTime = 0;            }        }        // send the delayed spikes        // this must be called after Neuron::SendSpike()        // has been called for the last time during this        // time step        if (spikeDelaysOn) {            SendDelayedSpikes();        }        // increment simTime        if (runCount > 1) {            // A call to IncrementSimTime() is made if more than one            // instance of Network is running in a process.  This is done            // to keep all of the Networks synchronized and to handle any            // threading issues that may arise due to simTime being static.            IncrementSimTime();        }        else {            simTime += simStepSize;        }        if (simTime >= stopTime) {            stopRun = true;        }        else if (!streamingInput) {            if (eventQ.empty() && inputQ.empty() && !spikeBatchCount) {                stopRun = true;            }        }    }}void Network::SetSpikeInput(SpikeInput* sIn){    delete spikeInput;    spikeInput = sIn;}void Network::IncrementSimTime(){    simTime += simStepSize;}void Network::SetTrainingMode(bool tMode){    if (tMode == trainingMode) {        return;    }    trainingMode = tMode;    hash_map<AmIdInt, Neuron*>::iterator itr;    itr = net.begin();    while (itr != net.end()) {        itr->second->TrainingOn(tMode);        itr++;    }}void Network::ScheduleSpikeDelay(vector<Synapse*>& axon){    unsigned int maxOffset = delayedSpikeQ.size() - 1;    for (vector<Synapse*>::iterator it=axon.begin(); it!=axon.end(); ++it) {        AmTimeInt offset = (*it)->GetOffset();        offset += currSpikeDelayOffset;        // If the offset goes past the end of the queue, then        // start back at the beginning        if (offset > maxOffset) {            offset -= (maxOffset + 1);        }        delayedSpikeQ[offset].push_back((*it));    }    spikeBatchCount += axon.size();}void Network::SendDelayedSpikes(){    vector<Synapse*>& spikeBatch = delayedSpikeQ[currSpikeDelayOffset];    if (!spikeBatch.size()) {        IncrementDelayOffset();        return;    }    // sort the elements in the current offset batch    // according to neuronId and get a pointer to    // the first element    vector<Synapse*>::iterator beginItr = spikeBatch.begin();    vector<Synapse*>::iterator endItr = spikeBatch.end();    static CompareSynapse comp;    sort(beginItr, endItr, comp);    //Synapse* firstSyn = spikeBatch[0];    SynapseItr firstSyn = spikeBatch.begin();    unsigned int numSyn = 0;    // parse the spikeBatch vector and send one group of spikes    // to each neuron in the vector.    for (unsigned int i=0; i<spikeBatch.size(); ++i) {        if (spikeBatch[i]->GetPostNeuron() != (*firstSyn)->GetPostNeuron()) {            (*firstSyn)->GetPostNeuron()->InputSpike(firstSyn, simTime, numSyn);            //firstSyn = spikeBatch[i];            firstSyn += numSyn;            numSyn = 1;        }        else {            ++numSyn;        }    }    // send the last batch of delayed spikes    (*firstSyn)->GetPostNeuron()->InputSpike(firstSyn, simTime, numSyn);    // clean up    spikeBatchCount -= spikeBatch.size();    spikeBatch.clear();    IncrementDelayOffset();}void Network::InitializeDelayedSpikeQ(){    if (maxSpikeDelay) {        spikeDelaysOn = true;        Neuron::EnableSpikeBatching();    }    maxOffset = maxSpikeDelay/simStepSize;    delayedSpikeQ.reserve(maxOffset+1);    delayedSpikeQ.resize(maxOffset+1);    for (unsigned int i=0; i<delayedSpikeQ.size(); ++i) {        // TODO: Assuming 100 delayed spikes per offset for now.        // A more intelligent algorithm to determine proper        // sizing should be developed later on.        delayedSpikeQ[i].reserve(100);    }}inline void Network::IncrementDelayOffset(){    if (currSpikeDelayOffset >= maxOffset) {        currSpikeDelayOffset = 0;    }    else {        ++currSpikeDelayOffset;    }}Layer * Network::GetLayer(AmIdInt layerId){    return layers[layerId];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -