関連情報

大域的最適化

C言語によるサンプルソースコード
使用関数名:nag_glopt_bnd_mcs_solve (e05jbc)

Keyword: 大域的最適化

概要

本サンプルは大域的最適化を行うC言語によるサンプルプログラムです。 本サンプルは以下に示される2次元におけるpeaks関数の大域的最小値を求めて出力します。

大域的最適化のデータ 

※本サンプルはNAG Cライブラリに含まれる関数 nag_glopt_bnd_mcs_solve() のExampleコードです。本サンプル及び関数の詳細情報は nag_glopt_bnd_mcs_solve のマニュアルページをご参照ください。
ご相談やお問い合わせはこちらまで

入力データ

(本関数の詳細はnag_glopt_bnd_mcs_solve のマニュアルページを参照)

このデータをダウンロード
nag_glopt_bnd_mcs_solve (e05jbc) Example Program Data
  2   3                                                 : n and sdlist
  Nag_Bounds                                            : bound
  -3.0   -3.0                                           : Lower bounds bl
  3.0   3.0                                             : Upper bounds bu
  Nag_SimpleBdry                                        : initmethod
  0                                                     : plot

  • 1行目はタイトル行で読み飛ばされます。
  • 2行目に変数の数(n)と初期化リストに従って分割が行われる座標の点の数の最大値(sdlist)を指定しています。
  • 3行目には境界値を処理するための機能が使用されるか(bound)を指定しています。"Nag_Bounds"は下限と上限をそれぞれ与えることを意味します。
  • 4行目には下限(bl)を指定しています。
  • 5行目には上限(bu)を指定しています。
  • 6行目にはどの初期化の手法が使用されるか(initmethod)を指定しています。"Nag_SimpleBdry"は簡易な初期化(境界法と中点法)を意味しています。
  • 7行目には現在の検索ボックス(領域)に情報を表示させるかどうか(plot)を指定しています。"0"の場合は検索ボックス(領域)には表示されません。

出力結果

(本関数の詳細はnag_glopt_bnd_mcs_solve のマニュアルページを参照)

この出力例をダウンロード
nag_glopt_bnd_mcs_solve (e05jbc) Example Program Results

(objfun was just called for the first time)

*** Begin monitoring information ***

Total sub-boxes =   228
Total function evaluations =   196
Total function evaluations used in local search =    87
Total points used in local search =    13
Total sweeps through levels =    12
Total splits by init. list =     5
Lowest level with nonsplit boxes =     7
Number of candidate minima in the 'shopping basket' =     2
Shopping basket:
xbaskt(  1,:) = -1.34740  0.22828
xbaskt(  2,:) =  0.20452 -1.62553

*** End monitoring information ***

Final objective value =    -6.55113
Global optimum X =   0.22828 -1.62553

  • 7〜17行目に以下に示すモニタリング情報が出力されています。
    • サブボックス(下位領域)の数
    • 関数objfunの呼び出しの累積数
    • 局所検索での関数objfunの呼び出しの累積数
    • 局所検索の開始点として使用される座標点の数
    • 分割のレベルを通じたスイープ(sweep)の累積数
    • 初期化リストによる分割の累積数
    • 分割していないボックス(領域)を含む、最も低い分割のレベル
    • ショッピングバスケット(最小値の候補の格納場所)の最小値の候補の座標点の数
    • 最小値の候補が格納されているショッピングバスケットの内容
  • 21行目に最終的な関数値が出力されています。
  • 22行目に大域的最適解xの値が出力されています。

ソースコード

(本関数の詳細はnag_glopt_bnd_mcs_solve のマニュアルページを参照)

※本サンプルソースコードはNAG数値計算ライブラリ(Windows, Linux, MAC等に対応)の関数を呼び出します。
サンプルのコンパイル及び実行方法


このソースコードをダウンロード
/* nag_glopt_bnd_mcs_solve (e05jbc) Example Program.
 *
 * Copyright 2006 Numerical Algorithms Group.
 *
 * Mark 9, 2009.
 */
#include <nag_example_file_io.h>
#include <stdio.h>
#include <math.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nage05.h>

#ifdef __cplusplus
extern "C" {
#endif
static void NAG_CALL objfun(Integer n, const double x[], double *f,
                            Integer nstate, Nag_Comm *comm, Integer *inform);
static void NAG_CALL monit(Integer n, Integer ncall, const double xbest[],
                           const Integer icount[], Integer sdlist,
                           const double list[], const Integer numpts[],
                           const Integer initpt[], Integer nbaskt,
                           const double xbaskt[], const double boxl[],
                           const double boxu[], Integer nstate, Nag_Comm *comm,
                           Integer *inform);
static void NAG_CALL output_current_box(Integer n, const double boxl[],
                                        const double boxu[], FILE *fpout);
#ifdef __cplusplus
}
#endif

int main(int argc, char *argv[])
{
  FILE              *fpin, *fpout;
  /* Scalars */
  double            obj;
  Integer           exit_status, i, n, plot, sdlist;
  Nag_BoundType     boundenum;
  Nag_MCSInitMethod initmethodenum;
  /* Arrays */
  char              bound[16], initmethod[18];
  double            *bl = 0, *bu = 0, *list = 0, *x = 0;
  Integer           *initpt = 0, *numpts = 0;
  Integer           iuser[1];
  /*Nag Types*/
  Nag_E05State      state;
  NagError          fail;
  Nag_Comm          comm;

  comm.iuser = iuser;

  exit_status = 0;
  INIT_FAIL(fail);

  /* Check for command-line IO options */
  fpin = nag_example_file_io(argc, argv, "-data", NULL);
  fpout = nag_example_file_io(argc, argv, "-results", NULL);
  fprintf(fpout, "nag_glopt_bnd_mcs_solve (e05jbc) Example Program Results\n");

  comm.p = (Pointer) fpout;

  /* Skip heading in data file */
  fscanf(fpin, "%*[^\n] ");
  /* Read n and sdlist from data file */
  fscanf(fpin, "%d%d%*[^\n] ", &n, &sdlist);
  if (n > 0 && sdlist > 0)
    {
      /* Allocate memory */
      if (!(bl = NAG_ALLOC(n, double)) ||
          !(bu = NAG_ALLOC(n, double)) ||
          !(list = NAG_ALLOC(n*sdlist, double)) ||
          !(x = NAG_ALLOC(n, double)) ||
          !(initpt = NAG_ALLOC(n, Integer)) ||
          !(numpts = NAG_ALLOC(n, Integer)))
        {
          fprintf(fpout, "Allocation failure\n");
          exit_status = -1;
          goto END;
        }

      /* Read in bound (and bl and bu if necessary) */
      fscanf(fpin, "%s%*[^\n] ", bound);

      /*
       * nag_enum_name_to_value (x04nac).
       * Converts NAG enum member name to value
       */
      boundenum = (Nag_BoundType) nag_enum_name_to_value(bound);

      if (boundenum == Nag_Bounds)
      /* Read in the whole of each bound */
        {
          for (i = 0; i < n; ++i)
            fscanf(fpin, "%lf", &bl[i]);
          fscanf(fpin, "%*[^\n] ");

          for (i = 0; i < n; ++i)
            fscanf(fpin, "%lf", &bu[i]);
          fscanf(fpin, "%*[^\n] ");
        }
      else if (boundenum == Nag_BoundsEqual)
      /* Bounds are uniform: read in only the first entry of each */
        {
          fscanf(fpin, "%lf%*[^\n] ", &bl[0]);
          fscanf(fpin, "%lf%*[^\n] ", &bu[0]);
        }

      /* Read in initmethod */
      fscanf(fpin, "%s%*[^\n] ", initmethod);

      /*
       * nag_enum_name_to_value (x04nac).
       * Converts NAG enum member name to value
       */
      initmethodenum = (Nag_MCSInitMethod) nag_enum_name_to_value(initmethod);

      /* Read in plot. Its value determines whether monit displays
         information on the current search box */
      fscanf(fpin, "%d%*[^\n] ", &plot);

      /* Communicate plot through to monit */
      iuser[0] = plot;

      /* Call nag_glopt_bnd_mcs_init (e05jac) to initialize
       * nag_glopt_bnd_mcs_solve (e05jbc). */
      nag_glopt_bnd_mcs_init(n, &state, &fail);

      if (fail.code != NE_NOERROR)
        {
          fprintf(fpout, "Initialization of nag_glopt_bnd_mcs_init (e05jac) "
                  "failed.\n%s\n", fail.message);
          exit_status = 1;
          goto END;
        }

      /* Solve the problem. */
      /* nag_glopt_bnd_mcs_solve (e05jbc).
       * Global optimization by multilevel coordinate search, simple bounds.
       */
      nag_glopt_bnd_mcs_solve(n, objfun, boundenum, initmethodenum, bl, bu,
                              sdlist, list, numpts, initpt, monit, x, &obj,
                              &state, &comm, &fail);

      if (fail.code == NE_NOERROR)
        {
          fprintf(fpout, "Final objective value = %11.5f\n", obj);
          fprintf(fpout, "Global optimum X = ");

          for (i = 0; i < n; ++i)
            fprintf(fpout, "%9.5f", x[i]);
          fprintf(fpout, "\n");
        }
      else
        {
          fprintf(fpout,
                  "Error message from nag_glopt_bnd_mcs_solve (e05jbc).\n%s\n",
                  fail.message);
          exit_status = 1;
        }
    }
 END:
  if (fpin != stdin) fclose(fpin);
  if (fpout != stdout) fclose(fpout);
  if (bl) NAG_FREE(bl);
  if (bu) NAG_FREE(bu);
  if (list) NAG_FREE(list);
  if (x) NAG_FREE(x);
  if (initpt) NAG_FREE(initpt);
  if (numpts) NAG_FREE(numpts);

  return exit_status;
}

static void NAG_CALL objfun(Integer n, const double x[], double *f,
                            Integer nstate, Nag_Comm *comm, Integer *inform)
{
  /* Routine to evaluate objective function */

  FILE *fpout = (FILE *) comm->p;
  *inform = 0;

  if (*inform >= 0)
  /* Here we're prepared to evaluate objfun at the current x */
    {
      if (nstate == 1)
      /* This is the first call to objfun */
        {
          fprintf(fpout, "\n(objfun was just called for the first time)\n");
        }

      *f = (
        3.0*pow((1.0-x[0]), 2)*exp(-pow(x[0], 2)-pow((x[1]+1), 2))
        - (10.0*(x[0]/5.0-pow(x[0], 3)-pow(x[1], 5))*
           exp(-pow(x[0], 2)-pow(x[1], 2)))
        - 1.0/3.0*exp(-pow((x[0]+1.0), 2)-pow(x[1], 2))
        );
    }
}

static void NAG_CALL monit(Integer n, Integer ncall, const double xbest[],
                           const Integer icount[], Integer sdlist,
                           const double list[], const Integer numpts[],
                           const Integer initpt[], Integer nbaskt,
                           const double xbaskt[], const double boxl[],
                           const double boxu[], Integer nstate, Nag_Comm *comm,
                           Integer *inform)
{
  /* Scalars */
  Integer i, j;
  Integer plot;

#define XBASKT(I, J) xbaskt[(I-1)*nbaskt + (J-1)]

  FILE    *fpout = (FILE *) comm->p;
  *inform = 0;

  if (*inform >= 0)
  /* We are going to allow the iterations to continue */
    {
      /* Extract plot from the communication structure */
      plot = comm->iuser[0];

      if (nstate == 0 || nstate == 1)
      /* When nstate == 1, monit is called for the first time.
       * When nstate == 0, monit is called for the first AND last time.
       * Display a welcome message */
        {
          fprintf(fpout, "\n*** Begin monitoring information ***\n\n");

          if (plot != 0 && n == 2)
            fprintf(fpout, "<Begin displaying search boxes>\n\n");
        }

      if (plot != 0 && n == 2)
        {
          /* Display the coordinates of the edges of the current search box */
          output_current_box(n, boxl, boxu, fpout);
        }

      if (nstate <= 0)
      /* monit is called for the last time */
        {
          if (plot != 0 && n == 2)
            fprintf(fpout, "<End displaying search boxes>\n\n");
          fprintf(fpout, "Total sub-boxes = %5d\n", icount[0]);
          fprintf(fpout, "Total function evaluations = %5d\n", ncall);
          fprintf(fpout,
                  "Total function evaluations used in local search = %5d\n",
                  icount[1]);
          fprintf(fpout, "Total points used in local search = %5d\n",
                  icount[2]);
          fprintf(fpout, "Total sweeps through levels = %5d\n", icount[3]);
          fprintf(fpout, "Total splits by init. list = %5d\n", icount[4]);
          fprintf(fpout, "Lowest level with nonsplit boxes = %5d\n",
                  icount[5]);
          fprintf(fpout, "Number of candidate minima in the 'shopping basket'"
                  " = %5d\n", nbaskt);
          fprintf(fpout, "Shopping basket:\n");

          for (i = 1; i <= n; ++i)
            {
              fprintf(fpout, "xbaskt(%3d,:) =", i);
              for (j = 1; j <= nbaskt; ++j)
                fprintf(fpout, "%9.5f", XBASKT(i, j));
              fprintf(fpout, "\n");
            }

          fprintf(fpout, "\n");
          fprintf(fpout, "*** End monitoring information ***\n");
          fprintf(fpout, "\n");
        }
    }
}

static void NAG_CALL output_current_box(Integer n, const double boxl[],
                                        const double boxu[], FILE *fpout)
{
  fprintf(fpout, "%20.15f %20.15f\n", boxl[0], boxl[1]);
  fprintf(fpout, "%20.15f %20.15f\n\n", boxl[0], boxu[1]);
  fprintf(fpout, "%20.15f %20.15f\n", boxl[0], boxl[1]);
  fprintf(fpout, "%20.15f %20.15f\n\n", boxu[0], boxl[1]);
  fprintf(fpout, "%20.15f %20.15f\n", boxl[0], boxu[1]);
  fprintf(fpout, "%20.15f %20.15f\n\n", boxu[0], boxu[1]);
  fprintf(fpout, "%20.15f %20.15f\n", boxu[0], boxl[1]);
  fprintf(fpout, "%20.15f %20.15f\n\n", boxu[0], boxu[1]);
}



Results matter. Trust NAG.

Privacy Policy | Trademarks