Beispiel #1
0
//-1: no solution 1: no bound 0: has a solution -V
int Simplex() {
  if(!initSimplex())
    return -1;
  if(!Process(c))
    return 1;
  for(int i=1; i<=nCnt; i++)
    X[N[i]]=0.0;
  for(int i=1; i<=bCnt; i++)
    X[B[i]]=b[i];
  return 0;
}
Beispiel #2
0
void multiDS(int n, double *x, double cc, double ce, double lmin,
             double lstart, int maxiter)
{
   int i, imin, replaced, iter = 0;
   double **xs, **xr, **xe, **xc, *fs, *fr, *fe, *fc, fsmin, frmin,
      femin, fcmin, ssize;
   FILE *fp;
   void initSimplex(int, double *, double **, double);
   void printSimplex(int, int, double **, double *);
   void findBest(int, double **, double *, int *, double *);
   void copySimplex(int, double **, double **, double *, double *);
   double simplexSize(int, double **);
   void vecAdd(int, double *, double *, double *, double);
   double dmin(int, double *);
   void mpi_assign(int);
   void mpi_distribute(int, double *);

   /* Initial size of simplex */
   ssize = lstart;

   /* Check validity of input parameters */
   if(cc <= 0.0 || cc >= 1.0) {
      printf("multiDS: contraction coefficient must be in (0,1)\n");
      exit(0);
   }

   if(ce <= 1.0) {
      printf("multiDS: expandion coefficient must be > 1\n");
      exit(0);
   }

   if(ssize < lmin) {
      printf("multiDS: starting simplex size is < minimum\n");
      printf("         give lstart > lmin\n");
      exit(0);
   }

   printf("Parameters for search:\n");
   printf("   Contraction factor     = %e\n", cc);
   printf("   Expansion   factor     = %e\n", ce);
   printf("   Starting simplex size  = %e\n", ssize);
   printf("   Minimum  simplex size  = %e\n", lmin);
   printf("   Maximum number of iter = %d\n", maxiter);

   /* Allocate memory */
   xs = (double **) calloc((n + 1), sizeof(double *));
   xr = (double **) calloc((n + 1), sizeof(double *));
   xe = (double **) calloc((n + 1), sizeof(double *));
   xc = (double **) calloc((n + 1), sizeof(double *));
   fs = (double *) calloc(n + 1, sizeof(double));
   fr = (double *) calloc(n + 1, sizeof(double));
   fe = (double *) calloc(n + 1, sizeof(double));
   fc = (double *) calloc(n + 1, sizeof(double));
   for(i = 0; i < n + 1; i++) {
      xs[i] = (double *) calloc(n, sizeof(double));
      xr[i] = (double *) calloc(n, sizeof(double));
      xe[i] = (double *) calloc(n, sizeof(double));
      xc[i] = (double *) calloc(n, sizeof(double));
   }


   /* Initialize the simplex */
   initSimplex(n, x, xs, ssize);

   /* Assign evaluations to different proc */
   mpi_assign(n);

   /* Calculate initial function values */
   /* Zeroth vertex is starting vertex, cost = 1. No need to calculate again
    * since it is already done in multiDS_driver.c */
   fs[0] = cost0;

   for(i = 1; i < n + 1; i++) {
      if(proc[i] == myproc)
         fs[i] = objFun(n, xs[i]);
   }

   /* Distribute cost functions */
   mpi_distribute(n, fs);

   printf("Initial simplex and function values:\n");
   printSimplex(0, n, xs, fs);

   /* Find best vertex and put in first position */
   findBest(n, xs, fs, &imin, &fsmin);

   if(myproc == 0)
      fp = fopen("cost.dat", "w");

   /* Main iteration loop */
   while(ssize > lmin && iter < maxiter) {
      printf("Iteration = %d\n\n", iter + 1);

      replaced = 0;
      while(!replaced && ssize > lmin) { /* inner repeat loop */

         /* rotation step */
         printf("   Rotation:\n");
         for(i = 1; i <= n; i++) {
            vecAdd(n, xs[0], xs[i], xr[i], 1.0);
            if(proc[i] == myproc)
               fr[i] = objFun(n, xr[i]);
         }
         mpi_distribute(n, fr);
         printSimplex(1, n, xr, fr);

         frmin = dmin(n, fr);
         replaced = (frmin < fs[0]) ? 1 : 0;
         if(replaced) {
            /* expansion step */
            printf("   Expansion:\n");
            for(i = 1; i <= n; i++) {
               vecAdd(n, xs[0], xs[i], xe[i], ce);
               if(proc[i] == myproc)
                  fe[i] = objFun(n, xe[i]);
            }
            mpi_distribute(n, fe);
            printSimplex(1, n, xe, fe);

            femin = dmin(n, fe);
            if(femin < frmin)
               copySimplex(n, xe, xs, fe, fs); //accept expansion
            else
               copySimplex(n, xr, xs, fr, fs); //accept rotation
         }
         else {
            /* contraction step */
            printf("   Contraction step:\n");
            for(i = 1; i <= n; i++) {
               vecAdd(n, xs[0], xs[i], xc[i], -cc);
               if(proc[i] == myproc)
                  fc[i] = objFun(n, xc[i]);
            }
            mpi_distribute(n, fc);
            printSimplex(1, n, xc, fc);

            fcmin = dmin(n, fc);
            replaced = (fcmin < fs[0]) ? 1 : 0;
            copySimplex(n, xc, xs, fc, fs); //accept contraction
         }

         /* Length of smallest edge in simplex */
         ssize = simplexSize(n, xs);

      }                         /* End of inner repeat loop */

      ++iter;

      /* Find best vertex and put in first position */
      findBest(n, xs, fs, &imin, &fsmin);

      printf("\n");
      printf("Minimum length of simplex = %12.4e\n", ssize);
      printf("Minimum function value    = %12.4e\n", fs[0]);
      printf("-------------------------------------------------\n");
      if(myproc == 0) {
         fprintf(fp, "%5d %20.10e %20.10e %5d\n", iter, fs[0], ssize, imin);
         fflush(fp);
      }
   }                            /* End of main iteration loop */
   if(myproc == 0)
      fclose(fp);

   /* Copy best vertex for output */
   for(i = 0; i < n; i++)
      x[i] = xs[0][i];

   /* Best vertex found */
   printf("Best vertex:\n");
   for(i = 0; i < n; i++)
      printf("%e ", x[i]);
   printf("\n");


   /* Free memory */
   for(i = 0; i < n + 1; i++) {
      free(xs[i]);
      free(xr[i]);
      free(xe[i]);
      free(xc[i]);
   }
   free(xs);
   free(xr);
   free(xe);
   free(xc);
   free(fs);
   free(fr);
   free(fe);
   free(fc);
}