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

📄 amoeba.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
字号:
/* * From Numerical Recipes in C (1st edition), Chapter 10, * page 307, Downhill Simplex Method in Multimensions * for minimization. * * The Numerical Recipes copyright forbids this code from * being distributed. */#include <click/config.h>#include "amoeba.hh"#include <math.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>CLICK_DECLSAmoeba::Amoeba(int dimensions){  _dimensions = dimensions;}Amoeba::~Amoeba(){}#define TINY 1.0e-10#define NMAX 5000#define GET_PSUM \  for (j=1;j<=ndim;j++) {\  for (sum=0.0,i=1;i<=mpts;i++) sum += p[i][j];\  psum[j]=sum;}#define SWAP(a,b) {swap=(a);(a)=(b);(b)=swap;}voidAmoeba::amoeba1(double **p, double y[], double ftol, int *nfunk){  int ndim = dimensions();  int i,ihi,ilo,inhi,j,mpts=ndim+1;  double rtol,sum,swap,ysave,ytry,*psum;  psum=vector(1,ndim);  *nfunk=0;  GET_PSUM;  for (;;) {    ilo=1;    ihi = y[1]>y[2] ? (inhi=2,1) : (inhi=1,2);    for (i=1;i<=mpts;i++) {      if (y[i] <= y[ilo])        ilo=i;      if (y[i] > y[ihi]) {        inhi=ihi;        ihi=i;      } else if (y[i] > y[inhi] && i != ihi)        inhi=i;    }    rtol=2.0*fabs(y[ihi]-y[ilo])/(fabs(y[ihi])+fabs(y[ilo])+TINY);    if (rtol < ftol) {      SWAP(y[1],y[ilo]);      for (i=1;i<=ndim;i++){        SWAP(p[1][i],p[ilo][i]);      }      break;    }    if (*nfunk >= NMAX)      nrerror("NMAX exceeded");    *nfunk += 2;    ytry=amotry(p,y,psum,ihi,-1.0);    if (ytry <= y[ilo])      ytry=amotry(p,y,psum,ihi,2.0);    else if (ytry >= y[inhi]) {      ysave=y[ihi];      ytry=amotry(p,y,psum,ihi,0.5);      if (ytry >= ysave) {        for (i=1;i<=mpts;i++) {          if (i != ilo) {            for (j=1;j<=ndim;j++)              p[i][j]=psum[j]=0.5*(p[i][j]+p[ilo][j]);            y[i]=fn(psum + 1);          }        }        *nfunk += ndim;        GET_PSUM;      }    } else {      --(*nfunk);    }  }  free_vector(psum,1,ndim);}doubleAmoeba::amotry(double **p, double y[], double psum[],               int ihi, double fac){  int ndim = dimensions();  int j;  double fac1,fac2,ytry,*ptry;  ptry=vector(1,ndim);  fac1=(1.0-fac)/ndim;  fac2=fac1-fac;  for (j=1;j<=ndim;j++)    ptry[j]=psum[j]*fac1-p[ihi][j]*fac2;  ytry = fn(ptry + 1);  if (ytry < y[ihi]) {    y[ihi]=ytry;    for (j=1;j<=ndim;j++) {      psum[j] += ptry[j]-p[ihi][j];      p[ihi][j]=ptry[j];    }  }  free_vector(ptry,1,ndim);  return ytry;}voidAmoeba::nrerror(const char *error_text){  fprintf(stderr, "Oops %s\n", error_text);  exit(1);}double *Amoeba::vector(int nl, int nh){  double *v;  v = (double *) malloc((nh-nl+1)*sizeof(double));  return v - nl;}voidAmoeba::free_vector(double *v, int nl, int){  free((char *) (v + nl));}voidAmoeba::minimize(double res[]){  double ftmp[150];  double *p[10];  /* vertices of starting simplex */  double y[10];   /* funk() on each p[] */  double ftol;    /* tolerance of funk output */  int nfunk = 0;  /* number of times funk called */  int i;  assert(dimensions() < 9);  p[0] = 0;  for(i = 1; i <= dimensions()+1; i++)    p[i] = ftmp + i*(dimensions()+1);  for(i = 1; i <= dimensions()+1; i++){    int j;    for(j = 1; j <= dimensions(); j++){      p[i][j] = 0.0;    }  }  /* start simplex points at 0,0,0 1,0,0 0,1,0 0,0,1 */  for(i = 2; i <= dimensions()+1; i++){    p[i][i-1] = 1 + i*0.01;  }  /* evaluate at each simplex point */  for(i = 1; i <= dimensions()+1; i++)    y[i] = fn(p[i] + 1);  ftol = 0.00001;  amoeba1(p, y, ftol, &nfunk);  for(i = 1; i <= dimensions(); i++)    res[i-1] = p[1][i];}class AmoebaTest : public Amoeba {public:  AmoebaTest();  virtual double fn(double a[]);  void doit();};AmoebaTest::AmoebaTest() : Amoeba(2){}struct xxx {  double x;  double y;  double d;};static struct xxx da[] = {  { 1000, 1000, 1 },  { 1001, 1001, 1 },  { 1000.5, 1001, .5 }};doubleAmoebaTest::fn(double a[]){  double x = a[0];  double y = a[1];  double d = 0;  int i;  printf("xfunc(%f,%f) ", x, y);  for(i = 0; i < (int)(sizeof(da) / sizeof(da[0])); i++){    double dx = x - da[i].x;    double dy = y - da[i].y;    double dd = da[i].d - sqrt(dx*dx + dy*dy);    dd = dd * dd;    d += dd;    printf("%f ", dd);  }  printf("= %f\n", d);  return(d);}voidAmoebaTest::doit(){  double pt[2];  minimize(pt);  printf("%f %f\n", pt[0], pt[1]);  if(pt[0] > 999.999 && pt[0] < 1000.001 &&     pt[1] > 1000.999 && pt[1] < 1001.001){    printf("AmoebaTest ok\n");  } else {    printf("AmoebaTest failed\n");  }}#if 0main(){  AmoebaTest at;  at.doit();}#endifCLICK_ENDDECLSELEMENT_PROVIDES(Amoeba)ELEMENT_REQUIRES(userlevel)

⌨️ 快捷键说明

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