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

📄 gaparameter.c

📁 关于遗传算法代码。比较全。希望能给大家带来帮助。
💻 C
📖 第 1 页 / 共 2 页
字号:
// $Header: /usr/people/mbwall/src/galib/ga/RCS/GAParameter.C,v 1.4 1998/11/08 22:53:07 mbwall Exp $
/* ----------------------------------------------------------------------------
  parameters.C
  mbwall 28jul94
  Copyright (c) 1995 Massachusetts Institute of Technology
                     all rights reserved

 DESCRIPTION:
  Definition of the parameter object and a container list for it.  I did this
as a separate list implementation because I don't want all of the overhead of
a fullblown list.  The parameter list is a special purpose, stripped down list
implementation.
---------------------------------------------------------------------------- */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <ga/gaconfig.h>
#include <ga/gaerror.h>
#include <ga/GAParameter.h>

#define PRM_CHUNKSIZE 10
#define BUFSIZE       1024	// size of buffer for reading pairs
#define MAX_PAIRS     5000	// max number of name-value pairs in stream
#define NAMESIZE      128	// max length of name in name-value pair

extern char _gaerrbuf1[];
extern char _gaerrbuf2[];
static int IsNumeric(const char*);

GAParameter::GAParameter(const char* fn, const char* sn, 
			 Type tp, const void* v){
  if(fn){
    fname = new char[strlen(fn)+1];
    strcpy(fname, fn);
  }
  else fname = (char*)0;

  if(sn){
    sname = new char[strlen(sn)+1];
    strcpy(sname, sn);
  }
  else sname = (char*)0;

  t = tp;
  memset(&val, 0, sizeof(Value));
  setvalue(v);
}

GAParameter::GAParameter(const GAParameter& orig){
  fname=sname = (char*)0; 
  memset(&val, 0, sizeof(Value));
  copy(orig);
}

void
GAParameter::copy(const GAParameter& orig){
  if(&orig == this) return;

  delete [] fname;
  delete [] sname;
  if(orig.fname){
    fname = new char[strlen(orig.fname)+1];
    strcpy(fname, orig.fname);
  }
  else fname = (char *)0;
  if(orig.sname){
    sname = new char[strlen(orig.sname)+1];
    strcpy(sname, orig.sname);
  }
  else sname = (char *)0;

  t = orig.t;
  setvalue(orig.value());	// do this directly...
}    

GAParameter::~GAParameter(){
  delete [] fname;
  delete [] sname;
  if(t == STRING) delete [] val.sval;
}


void
GAParameter::setvalue(const void* v){
  switch(t){
  case BOOLEAN:
  case INT:
    val.ival = *((int*)v);
    break;
  case CHAR:
    val.cval = *((char*)v);
    break;
  case STRING:
    if(v != val.sval) {
      char* ptr=0;
      if(strlen((char*)v) > 0){
	ptr = new char[strlen((char*)v)+1];
	strcpy(ptr, (char*)v);
      }
      delete [] val.sval;
      val.sval = ptr;
    }
    break;
  case FLOAT:
    val.fval = *((float*)v);
    break;
  case DOUBLE:
    val.dval = *((double*)v);
    break;
  case POINTER:
  default:
    val.pval = v;
    break;
  }
}






// The default parameter list is empty.  Allocate space for the pointers, but
// don't allocate any parameters at this point.
GAParameterList::GAParameterList(){
  N = n = cur = 0;
  p = (GAParameter**)0;
}

GAParameterList::GAParameterList(const GAParameterList& list){
  N = list.N;
  n = list.n;
  cur = list.cur;
  p = new GAParameter * [N];
  for(unsigned int i=0; i<n; i++)
    p[i] = new GAParameter(*(list.p[i]));
}

// This is a rather stupid operator= implementation.  Instead of doing a copy
// we just nuke everything the reallocate new stuff.  If this were called a lot
// then we could end up with some fragmentation this way (rather than just 
// doing copies on already-allocated memory).
GAParameterList&
GAParameterList::operator=(const GAParameterList& list){
  if(&list == this) return *this;

  unsigned int i;
  for(i=0; i<n; i++)
    delete p[i];
  delete [] p;

  N = list.N;
  n = list.n;
  cur = list.cur;
  p = new GAParameter * [N];
  for(i=0; i<n; i++)
    p[i] = new GAParameter(*(list.p[i]));

  return *this;
}

GAParameterList::~GAParameterList(){
  for(unsigned int i=0; i<n; i++)
    delete p[i];
  delete [] p;
}


// Set the specified parameter (if we have it).  If we don't recognize the name
// (ie it has not been added to the list) then we return the error code.
int
GAParameterList::set(const char* name, const void* v){
  int found = 0;
  for(unsigned int i=0; i<n && !found; i++){
    if(strcmp(name, p[i]->fullname()) == 0 || 
       strcmp(name, p[i]->shrtname()) == 0){
      p[i]->value(v);
      found = 1;
    }
  }
  return found ? 0 : -1;
}


// Must do a special case for double/float.  Any floats that get passed to this
// routine will be cast to doubles, but then we need to force them back to a
// float if FLOAT is the type that is expected.  Kind of sucks, eh?
//   We could check the parameter type against the type here, but we don't. 
// (could do it for all of the 'set' members).  Maybe in a later release.
int
GAParameterList::set(const char* name, double v) {
  int found = 0;
  for(unsigned int i=0; i<n; i++){
    if(strcmp(name, p[i]->fullname()) == 0 ||
       strcmp(name, p[i]->shrtname()) == 0){
      if(p[i]->type() == GAParameter::FLOAT){
	float fval = (float)v;
	p[i]->value((void*)&fval);
      }
      else if(p[i]->type() == GAParameter::DOUBLE)
	p[i]->value((void*)&v);
      else
	GAErr(GA_LOC, "GAParameterList", "set", gaErrBadTypeIndicator);
      found = 1;
    }
  }
  return found ? 0 : -1;
}

// This allocates space for strings, so be sure to free it!
int
GAParameterList::get(const char* name, void* value) const {
  int status = 1;
  for(unsigned int i=0; i<n; i++){
    if(strcmp(name, p[i]->fullname()) == 0 ||
       strcmp(name, p[i]->shrtname()) == 0){
      switch(p[i]->type()){
      case GAParameter::BOOLEAN:
      case GAParameter::INT:
	*((int*)value) = *((int*)p[i]->value());
	break;
      case GAParameter::CHAR:
	*((char*)value) = *((char*)p[i]->value());
	break;
      case GAParameter::STRING:
	break;
      case GAParameter::FLOAT:
	*((float*)value) = *((float*)p[i]->value());
	break;
      case GAParameter::DOUBLE:
	*((double*)value) = *((double*)p[i]->value());
	break;
      case GAParameter::POINTER:
      default:
	break;
      }
      status = 0;
    }
  }
  return status;
}


// Add the item to the list if it does not already exist.  Return 0 if the add
// was OK, -1 if there was a problem.
int
GAParameterList::add(const char* fn, const char* sn,
		     GAParameter::Type t, const void* v) { 
  int status = -1;
  if(n == N){
    N += PRM_CHUNKSIZE;
    GAParameter **tmp = p;
    p = new GAParameter* [N];
    memcpy(p, tmp, n * sizeof(GAParameter*));
    delete [] tmp;
  }
  int found = 0;
  for(unsigned int i=0; i<n && !found; i++){
    if(strcmp(fn, p[i]->fullname()) == 0 &&
       strcmp(sn, p[i]->shrtname()) == 0)
      found = 1;
  }
  if(!found){
    cur = n;
    p[n++] = new GAParameter(fn, sn, t, v);
  }
  return status;
}


// When you remove a parameter from the list, the iterator is left pointing
// at the same location.  If the item was the last in the list, then the 
// iterator moves to the new last item in the list.
//   Return 0 if everything was OK, -1 if error.
int
GAParameterList::remove(){
  int status = -1;
  if(cur > n) return status;
  delete p[cur];
  memmove(&(p[cur]), &(p[cur+1]), (n-cur-1)*sizeof(GAParameter*));
  n--;
  if(cur > n) cur = n;
  status = 0;
  return status;
}

GAParameter* 
GAParameterList::operator()(const char* name){
  for(unsigned int i=0; i<n; i++)
    if(strcmp(name, p[i]->fullname())==0 || strcmp(name, p[i]->shrtname())==0)
      return p[i];
  return (GAParameter*)0;
}


#ifndef NO_STREAMS
// Dump the parameters to the specified stream.  Just name-value pairs with a
// tab delimiter and newline separating pairs.
//   If there is an error, return 1, otherwise return 0.
int
GAParameterList::write(ostream& os) const {
  for(unsigned int i=0; i<n; i++){
    int ival;
    float fval;
    double dval;
    char cval;
    char* sval;

    os << p[i]->fullname() << "\t";

    switch(p[i]->type()){
    case GAParameter::BOOLEAN:
      ival = *((int*)(p[i]->value()));
      if(ival) os << "true\n";
      else os << "false\n";
      break;
    case GAParameter::INT:
      ival = *((int*)(p[i]->value()));
      os << ival << "\n";
      break;

⌨️ 快捷键说明

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