シンプレックス法による関数の最小化

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

ホーム > 製品 > nAG数値計算ライブラリ > サンプルソースコード集 > シンプレックス法による関数の最小化 (C言語/C++)

Keyword: シンプレックス法, 関数の最小化

概要

本サンプルはシンプレックス法による関数の最小化を行うC言語によるサンプルプログラムです。 本サンプルはNelder-Meadシンプレックス法により以下に示される関数の最小値を求めて出力します。本サンプルではx1とx2の初期値を(−1.0,1.0)として計算しています。

シンプレックス法による関数の最小化のデータ 

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

出力結果

(本関数の詳細はnag_opt_simplex_easy のマニュアルページを参照)
1
2
3
4
5

この出力例をダウンロード
nag_opt_simplex_easy (e04cbc) Example Program Results
(User-supplied callback funct, first invocation.)
(User-supplied callback monit, first invocation.)
The final function value is       0.0000
at the point       0.5000      -0.9999

  • 2行目に最小の関数値が出力されています。
  • 3行目に最小の関数値に対応するxの値が出力されています。

ソースコード

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

このソースコードをダウンロード
/* nag_opt_simplex_easy (e04cbc) Example Program.
 *
 * CLL6I261D/CLL6I261DL Version.
 *
 * Copyright 2017 Numerical Algorithms Group.
 *
 * Mark 26.1, 2017.
 */

#include <nag.h>
#include <math.h>
#include <stdio.h>
#include <nag_stdlib.h>
#include <nage04.h>
#include <nagx02.h>

#ifdef __cplusplus
extern "C"
{
#endif
  static void nAG_CALL funct(const Integer n, const double *xc, double *fc,
                             Nag_Comm *comm);
  static void nAG_CALL monit(const double fmin, const double fmax,
                             const double sim[], const Integer n,
                             const Integer ncall, const double serror,
                             const double vratio, Nag_Comm *comm);
#ifdef __cplusplus
}
#endif

int main(void)
{
  /* Scalars */
  double f, tolf, tolx;
  Integer exit_status, i, monitoring, maxcal = 100, n = 2;
  NagError fail;

  /* Arrays */
  static double ruser[2] = { -1.0, -1.0 };
  double *x = 0;

  Nag_Comm comm;

  exit_status = 0;

  INIT_FAIL(fail);

  printf("nag_opt_simplex_easy (e04cbc) Example Program Results\n");

  /* For communication with user-supplied functions: */
  comm.user = ruser;

  /* Allocate memory */
  if (!(x = nAG_ALLOC(n, double)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }

  /* Set monitoring to a nonzero value to obtain monitoring information */
  monitoring = 0;
  comm.p = (Pointer) &monitoring;

  /* Starting values */
  x[0] = -1.0;
  x[1] = 1.0;
  tolf = sqrt(nag_machine_precision);
  tolx = sqrt(tolf);

  nag_opt_simplex_easy(n, x, &f, tolf, tolx, funct, monit, maxcal, &comm,
                       &fail);

  if (fail.code != NE_NOERROR) {
    printf("Error from nag_opt_simplex_easy (e04cbc).\n%s\n", fail.message);
    exit_status = 1;
    goto END;
  }

  printf("The final function value is %12.4f\n", f);
  printf("at the point");
  for (i = 1; i <= n; ++i) {
    printf(" %12.4f", x[i - 1]);
  }
  printf("\n");

END:
  nAG_FREE(x);

  return exit_status;
}

static void nAG_CALL funct(const Integer n, const double *xc, double *fc,
                           Nag_Comm *comm)
{
  if (comm->user[0] == -1.0) {
    printf("(User-supplied callback funct, first invocation.)\n");
    comm->user[0] = 0.0;
  }
  *fc = exp(xc[0]) * (4.0 * xc[0] * (xc[0] + xc[1]) +
                      2.0 * xc[1] * (xc[1] + 1.0) + 1.0);
}

static void nAG_CALL monit(const double fmin, const double fmax,
                           const double sim[], const Integer n,
                           const Integer ncall, const double serror,
                           const double vratio, Nag_Comm *comm)
{
#define SIM(I, J) sim[(J-1)*(n+1) + (I-1)]

  Integer i, j;
  Integer monitoring = *(Integer *) comm->p;

  if (comm->user[1] == -1.0) {
    printf("(User-supplied callback monit, first invocation.)\n");
    comm->user[1] = 0.0;
  }
  if (monitoring != 0) {
    printf("\nThere have been %5ld function calls\n", ncall);
    printf("The smallest function value is %10.4f\n", fmin);
    printf("\nThe simplex is\n");
    for (i = 1; i <= n + 1; ++i) {
      for (j = 1; j <= n; ++j) {
        printf(" %13.4e", SIM(i, j));
      }
      printf("\n");
    }
    printf("\nThe standard deviation in function values at the"
           " vertices of the simplex is %10.4f\n", serror);
    printf("The linearized volume ratio of the current simplex"
           " to the starting one is %10.4f\n", vratio);
  }
}


関連情報
© 日本ニューメリカルアルゴリズムズグループ株式会社 2025
Privacy Policy  /  Trademarks