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

📄 neuron.cc

📁 遗传算法和神经网络结合
💻 CC
字号:
/*  YAKS, Optann, a Khepera simulator including a separate GA and ANN   (Genetic Algoritm, Artificial Neural Net).  Copyright (C) 2000  Johan Carlsson (johanc@ida.his.se)    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 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, write to the Free Software  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#include "neuron.h"/** * Get a random number in the range [0..\a i] * @param i The upper limit, [0..\a i] * @return The random number generated */int nrand(int i){  return (int)fabs((rand()*(double)i)/(RAND_MAX+1));}/** * Get a unique identifier for the neuron * @return A unique identifier. */long int getUniqId(){  static long int uniqeID=0;  return ++uniqeID;}/** * Get the unique identifier for the neuron * @return The identifier. */long int Neuron::getId(){  return id;}/** * Get the identifier of the neuron to which link \a index points at. * @see getNextLinkId * @return The identifier or -1 if \a index is out of range. */long int Neuron::getLinkToId(int index){  if(index < nrOfLinks && index >= 0){    linkCount = index;    return getNextLinkId();  }  else{    return(-1);  }}/** * Get the identifier of the neuron to which the next link points at. * @attention You must call getLinkToId before calling getNextLinkId. * @see getLinkId * @return The identifier or -1 if there are no more links. */long int Neuron::getNextLinkId(){  if(linkCount < nrOfLinks && linkCount >= 0){  return links[linkCount++]->fromId;  }  else{    return(-1);  }}/** * Get the number of links the neuron has. * @return The number of links. */int Neuron::getNrOfLinks(){  return nrOfLinks;}/** * Duplicate the neuron. * @warning I dont know if this method really does work... * @return An exact copy of the neuron. */class Neuron* Neuron::duplicate(){  Neuron *copy;  copy = new Neuron(layerPriority,nType,actType);  for(int i=0; i < nrOfLinks;i++){    copy->createLink(links[i]->fromNode,links[i]->weight,links[i]->typ);  }  return copy;}/** * Constructor for neuron, creates a new neuron with an unique identifier. * @param iLayerPriority The activatio priority of the new neuron. * @param NODE_T The neuron type (for example INPUT,INTERN,OUTPUT,BIAS,SCN). * @param iFuncT The activation function for the neuron. */Neuron::Neuron(int iLayerPriority,NODE_T inType, ACTIVATION_T iFuncT){  activationValue = new double();  *activationValue = 0.5;  nrOfLinks = 0;  layerPriority = iLayerPriority;  actType = iFuncT;  nType = inType;  linkCount = 0;  id=getUniqId();  scnUsed = 0;}/** * Constructor for neuron, creates a new neuron with a specified identifier. * @attention Only use this constructor if you know what you are doing. * @param iLayerPriority The activatio priority of the new neuron. * @param NODE_T The neuron type (for example INPUT,INTERN,OUTPUT,BIAS,SCN). * @param iFuncT The activation function for the neuron. * @param iId The unique identifier for the neuron. */Neuron::Neuron(int iLayerPriority,NODE_T inType, ACTIVATION_T iFuncT,long int iId){  activationValue = new double();  *activationValue = 1.0;  nrOfLinks = 0;  layerPriority = iLayerPriority;  actType = iFuncT;  nType = inType;  linkCount = 0;  id=iId;  scnUsed = 0;}/** * Get the type of neuron. * @return The type. */NODE_T Neuron::getNodeType(){  return nType;}/** * Get the activation function for the neuron. * @return The activation function. */ACTIVATION_T Neuron::getActFunc(){  return actType;}/** * Get the weight of a link. * @attention This function will call exit(-1) if index is out of range. * @param index The internal index of the link. * @return The weight. * @see setLinkWeight * @see getLinkWeightPointer */int8_t Neuron::getLinkWeight(int index){  if(index < nrOfLinks && index >= 0)    return links[index]->weight;  fprintf(stderr,"WARNING Neuron::getLinkWeight got a index which was out of range\n");  exit(-1);}/** * Get a pointer to the weight of a link. * @attention This function will call exit(-1) if index is out of range. * @param index The internal index of the link. * @return The weight pointer. * @see getLinkWeight * @see setLinkWeight */int8_t *Neuron::getLinkWeightPointer(int index){  if(index < nrOfLinks && index >= 0)    return &links[index]->weight;  fprintf(stderr,"WARNING Neuron::getLinkWeightPointer got a index which was out of range\n Index %d",index);  exit(-1);}/** * Set the weight for a link. * @attention This function will call exit(-1) if index is out of range. * @param index The internal index of the link. * @param iweight The new weight for the link. * @see getLinkWeight * @see getLinkWeightPointer */void Neuron::setLinkWeight(int index, int8_t iweight){  if(index < nrOfLinks && index >= 0)    links[index]->weight=iweight;  else{    fprintf(stderr,"WARNING Neuron::setLinkWeight got a index which was out of range\n");    exit(-1);  }}/** * Deconstructor, deallocates all memory and links for the neuron. */Neuron::~Neuron(){  if(nrOfLinks>0){    for(int i=0;i < nrOfLinks; i++){      free(links[i]);    }    free(links);  }  delete(activationValue);}/** * Creates a link from the current neuron to \a toNeuron. * @param toNeuron The neuron from which the link starts. * @param iWeight Initial weight of the link. * @param iType The link type, for now there are just NORMAL. * @see Neuron::createSCNLink */void Neuron::createLink(class Neuron *toNeuron,int8_t iWeight,LINK_TO_T iType){  int nI;  if(iType==SCN_L){    fprintf(stderr,"Neuron::createLink use Neuron::createSCNLink to create a SCN link");    exit(-1);  }  if(nrOfLinks==0){    links = (LINK_T**) malloc(sizeof(LINK_T*));    links[0] = (LINK_T*)malloc(sizeof(LINK_T));    nI=0;  }  else{    links = (LINK_T**) realloc(links,sizeof(LINK_T*)*(nrOfLinks+1));    links[nrOfLinks] =(LINK_T*) malloc(sizeof(LINK_T));    nI=nrOfLinks;  }  links[nI]->weight = iWeight;  links[nI]->value=toNeuron->activationPointer();  links[nI]->fromNode=toNeuron;  links[nI]->fromId=toNeuron->getId();  links[nI]->typ=iType;  links[nI]->toNode=this;  links[nI]->SCN=NULL;  links[nI]->SCNid=-1;  links[nI]->toId=id;  links[nI]->slowness=0;  nrOfLinks++;}/** * Creates a SCN link from the current neuron to \a toNeuron with the weight from \a SCNNeuron activation value. * @param toNeuron The neuron from which the link starts. *燖param SCNNeuron The neuron to get the weight from. * @see Neuron::createLink */void Neuron::createSCNLink(class Neuron *toNeuron,class Neuron *SCNNeuron){  int nI;  if(nrOfLinks==0){    links = (LINK_T**) malloc(sizeof(LINK_T*));    links[0] = (LINK_T*)malloc(sizeof(LINK_T));    nI=0;  }  else{    links = (LINK_T**) realloc(links,sizeof(LINK_T*)*(nrOfLinks+1));    links[nrOfLinks] =(LINK_T*) malloc(sizeof(LINK_T));    nI=nrOfLinks;  }  links[nI]->weight = 0;  links[nI]->value=toNeuron->activationPointer();  links[nI]->fromNode=toNeuron;  links[nI]->fromId=toNeuron->getId();  links[nI]->typ=SCN_L;  links[nI]->SCN=SCNNeuron;  links[nI]->SCNid=SCNNeuron->getId();  links[nI]->toNode=this;  links[nI]->toId=id;  links[nI]->slowness=0;  SCNNeuron->setSCNUsed();  nrOfLinks++;}/** * Toggle the stat of scnUsed (used to make sure that a SCN neuron is used only ones) */void Neuron::setSCNUsed(){  scnUsed = 1;}/** * Get the identifier of the SCN neuron for the SCN link \a index. * @return The identifier or -1 if \a index is out of range or the link is not an SCN link. */long int Neuron::getLinkSCNid(int index){  if(index >=0 && index < nrOfLinks)    return links[index]->SCNid;  else    return(-1);}/** * Remove a link to the neuron. It is safe to call this function with an incorrect index. * @param index The internal index of the link. * @see removeLinksTo() */void Neuron::removeLink(int index){  if(index >= 0 && index < nrOfLinks){    if((index+1)!=nrOfLinks){      free(links[index]);      for(int i=index; i < --nrOfLinks; i++){	links[i] = links[i+1];      }      links = (LINK_T**) realloc(links,sizeof(LINK_T*)*nrOfLinks);    }    else{      free(links[index]);      links = (LINK_T**) realloc(links,sizeof(LINK_T*)*--nrOfLinks);    }  }}/** * Remove all links to \a toNeuron. * @param toNeuron The neuron to lose all connections to. * @see removeLinksTo(long int) */void Neuron::removeLinksTo(class Neuron *toNeuron){  for(int i=0; i < nrOfLinks; i++){    if(links[i]->fromNode==toNeuron){      removeLink(i);    }  }}/** * Remove all links to \a toNeuron. * @param toNeuron The neuron to lose all connections to. * @see removeLinksTo(class Neuron) */void Neuron::removeLinksTo(long int toNeuron){  for(int i=0; i < nrOfLinks; i++){    if(links[i]->fromId==toNeuron){      removeLink(i);    }  }}/** * Get the current activation of the neuron. * @return The activation. */double Neuron::getActivationValue(){  return *activationValue;}/** * Set the current activation of the neuron. * @param iValue The new activation. */void Neuron::setActivationValue(double iValue){  *activationValue = iValue;}/** * Get a pointer to the activation. * @return The pointer. */double* Neuron::activationPointer(){  return activationValue; }/** * Get the activation priority of the neuron, * @return The activation priority. */int Neuron::getPriority(){  return layerPriority;}/** * Mutate all links to the neuron. Each bit in the links flips with a probability of \a bitMutateProbability. *@param  bitMutateProbability The probability that a bit in a link will mutate. */void Neuron::mutateWeights(int bitMutateProbability){  uint8_t q;  int cdna;  for(int i=0; i < nrOfLinks; i++){    if(links[i]->typ!=SCN_L){      cdna = 0;      for(q = 128; q; q >>= 1)	if(bitMutateProbability > nrand(100))	  cdna |= q;      links[i]->weight ^= cdna;    }  }}/** * Wrapper to mutateWeights() which only will be called if the neuron has the layer priority of \a pri. *@param  bitMutateProbability The probability that a bit in a link will mutate. * @param pri The selection criteria. */void Neuron::mutateWeightsWithPri(int bitMutateProbability, int pri){  if(pri==layerPriority){    mutateWeights(bitMutateProbability);  }}/** * Rebuilds all activation pointers in links to the neuron indicated by \a toNeuron. *@param toNeuron The neuron to fix all links to. */void Neuron::correctAllLinksFrom(class Neuron *toNeuron){  for(int i=0; i < nrOfLinks; i++){    if(links[i]->fromNode==toNeuron)      links[i]->value=toNeuron->activationPointer();  }}/** * Check if SCN capability has been used. * @return 0 if it has been used - 1 otherwise. * */int Neuron::SCNNotUsed() const{  return !scnUsed;}/** * Sigmoid activation function. * @param in Input to sigmoid function. * @return  \f$ f(in)=(1.0 / (1.0 + e^-in)) \f$ */double Neuron::sigmoid(double in){  double act;#ifdef ANN_DEBUG  printf("%f \n",in);#endif   act =(1.0 / (1.0 + exp(0.0 - in)));#ifdef ANN_DEBUG  printf("%f \n",act);#endif   return act;}/** * Sigmoid activation function. * @param in Input to sigmoid function. * @return \f$ f(in)=(1.0 / (1.0 + e^-in)) \f$ */double Neuron::logistic(double in){  return (1.0 / (1.0 + exp(0.0 - in)));}/** * Step activation function. * @param in Input to step function. * @return \f$ f(in) = (1.0, in >= 0.0)/(0.0, in < 0.0) \f$ */double Neuron::step(double in){  double out;  if(in < 0)    out=0.0;  else    out=1.0;  return out;}/** * Linear activation function. * @param in Input to linear function. * @return \f$ f(in)=in \f$ */double Neuron::linear(double in){  return in;}/** * Activate the neuron. Sums all links values and calls the activation function. */void Neuron::activate(){  int i;  double sum=0;  if(nrOfLinks>0){    for(i=0; i < nrOfLinks; i++){      if(links[i]->typ==NORMAL){#ifdef ANN_DEBUG      cout << "link weight " << (double)links[i]->weight/12.8 <<  " activation value " <<\	(double)*((double*)links[i]->value) << endl;#endif	/* Weights between -10 < w < 10 */	sum += (double)*((double*)links[i]->value)*(links[i]->weight/12.8);      }      else if(links[i]->typ==SCN_L){	sum += (double)*((double*)links[i]->value)*(links[i]->SCN->getActivationValue());      }      else{ //NULLAD      }    }    if(actType==LOGISTIC){      *activationValue = logistic(sum);    }    else if(actType==SIGMOID){      *activationValue = sigmoid(sum);    }    else if(actType==TANH){      *activationValue = tanh(sum);    }    else if(actType == STEP){      *activationValue = step(sum);    }    else if(actType == LINEAR){      *activationValue = linear(sum);    }    else if(actType == NONE){      /* Do nothing */    }    else{      *activationValue = 1.0;      fprintf(stderr,"Whooooaaaaa i smell an error in Neuron::activate this neuron does not have an activationfunction\n");      exit(-1);    }  }}/** * Get the link type for the link with the internal index \a index. * @param index The internal index. * @return The link type. */LINK_TO_T Neuron::getLinkType(int index) const{  return links[index]->typ;}

⌨️ 快捷键说明

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