C#による 非線形計画

C#によるサンプルソースコード : 使用関数名:e04uc

Keyword: 非線形計画

概要

本サンプルは非線形計画を行うC#によるサンプルプログラムです。 本サンプルは以下に示される非線形関数を最小化する解を求めて出力します。

非線形計画のデータ 

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

入力データ

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

このデータをダウンロード
e04uc Example Program Data
  4   1   2                              :Values of N, NCLIN and NCNLN
  1.0   1.0   1.0   1.0                                 :End of matrix A
  1.0   1.0   1.0   1.0  -1.0E+25  -1.0E+25  25.0       :End of BL
  5.0   5.0   5.0   5.0  20.0      40.0       1.0E+25   :End of BU
  1.0   5.0   5.0   1.0                                 :End of X 

  • 1行目はタイトル行で読み飛ばされます。
  • 2行目に変数の数(n)、線形制約の数(nclin)と非線形制約の数(ncnln)を指定しています。
  • 3行目に線形制約行列Aの要素を指定しています。
  • 4行目に変数の下限と制約の下限(bl)を指定しています。
  • 5行目に変数の上限と制約の上限(bu)を指定しています。
  • 6行目にxの初期値を指定しています。

出力結果

(本関数の詳細はe04uc のマニュアルページを参照)
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

この出力例をダウンロード
e04uc Example Program Results


 Calls to E04UEF
 ---------------

      List
      Print level = 10

 *** E04UCF

 Parameters
 ----------

 Linear constraints.....         1       Variables..............         4
 Nonlinear constraints..         2

 Infinite bound size....  1.00E+20       COLD start.............
 Infinite step size.....  1.00E+20       EPS (machine precision)  1.11E-16
 Step limit.............  2.00E+00       Hessian................        NO

 Linear feasibility.....  1.05E-08       Crash tolerance........  1.00E-02
 Nonlinear feasibility..  1.05E-08       Optimality tolerance...  3.26E-12
 Line search tolerance..  9.00E-01       Function precision.....  4.37E-15

 Derivative level.......         3       Monitoring file........        -1
 Verify level...........         0

 Major iterations limit.        50       Major print level......        10
 Minor iterations limit.        50       Minor print level......         0

 Workspace provided is     IWORK(      17),  WORK(     185).
 To solve problem we need  IWORK(      17),  WORK(     185).


 Verification of the constraint gradients.
 -----------------------------------------

 The constraint Jacobian seems to be ok.

 The largest relative error was    2.29E-07  in constraint    2



 Verification of the objective gradients.
 ----------------------------------------

 The objective gradients seem to be ok.

 Directional derivative of the objective    8.15250000E-01
 Difference approximation                   8.15249734E-01


  Maj  Mnr    Step Merit Function Norm Gz  Violtn Cond Hz
    0    4 0.0E+00   1.738281E+01 7.1E-01 1.2E+01 1.0E+00
    1    1 1.0E+00   1.703169E+01 4.6E-02 1.9E+00 1.0E+00
    2    1 1.0E+00   1.701442E+01 2.1E-02 8.8E-02 1.0E+00
    3    1 1.0E+00   1.701402E+01 3.1E-04 5.4E-04 1.0E+00
    4    1 1.0E+00   1.701402E+01 7.0E-06 9.9E-08 1.0E+00
    5    1 1.0E+00   1.701402E+01 1.1E-08 4.6E-11 1.0E+00

 Exit from NP problem after     5 major iterations,
                                9 minor iterations.


 Varbl State     Value       Lower Bound   Upper Bound    Lagr Mult   Slack

 V   1    LL    1.00000       1.00000       5.00000       1.088         .
 V   2    FR    4.74300       1.00000       5.00000           .      0.2570
 V   3    FR    3.82115       1.00000       5.00000           .       1.179
 V   4    FR    1.37941       1.00000       5.00000           .      0.3794


 L Con State     Value       Lower Bound   Upper Bound    Lagr Mult   Slack

 L   1    FR    10.9436          None       20.0000           .       9.056


 N Con State     Value       Lower Bound   Upper Bound    Lagr Mult   Slack

 N   1    UL    40.0000          None       40.0000     -0.1615     -3.5264E-11
 N   2    LL    25.0000       25.0000          None      0.5523     -2.8791E-11

 Exit E04UCF - Optimal solution found.

 Final objective value =    17.01402

 ** e04uc returned with ifail =   0

  Varbl    Istate            Value         Lagr Mult

  V    1    1                     1           1.088
  V    2    0                 4.743               0
  V    3    0               3.82115               0
  V    4    0               1.37941               0


  L Con    Istate      Value                  Lagr Mult

  L    1    0               10.9436               0


  N Con    Istate             Value           Lagr Mult

  N    1    2                    40         -0.1615
  N    2    1                    25          0.5523


  Final objective value =        17.01402

  • 15~33行目に以下に示すプログラムのオプション引数が出力されています。
    Linear constraints 線形制約の数。
    Variables 変数の数。
    Nonlinear constraints 非線形制約の数。
    Infinite bound size 無限の境界値。この値以上の上限は+∞と見なされます。またこの値を負に反転させた値以下の下限は−∞と見なされます。
    COLD start コールドスタート。変数や制約の値に基づいて初期のワーキングセットが選ばれていることを意味します。
    Infinite step size 無限解へのステップと見なされる変数の変化の大きさ。
    EPS (machine precision) マシンの精度。
    Step limit 行探索の最初のステップでの変数の変化の最大値。
    Hessian 上三角行列 R の内容を制御します。"NO"は行列HQのコレスキー因子を含むことを意味しています。
    Linear feasibility (tolerance) 実行可能解での許容可能な最大の線形制約違反。
    Crash tolerance 初期のワーキングセットに含まれる不等式制約が下限/上限のこの範囲内にあることを示しています。
    Nonlinear feasibility (tolerance) 実行可能解での許容可能な最大の非線形制約違反。
    Optimality tolerance 最後の反復で解を近似する際の正確さ。
    Line search tolerance 反復時に探索方向に進むステップがメリット関数の最小値を近似する際の正確さ。
    Function precision 問題関数の計算の正確さの度合い。
    Derivative level ユーザ提供関数で与えられる導関数のレベル。
    Monitoring file モニタリング情報の生成を制御します。"-1" はモニタリング情報が生成されないことを意味します
    Verify level 勾配の有限差分チェックのレベル。
    Major Iteration limit 大きな反復の反復数の限界値。
    Major print level 大きな反復の結果出力レベル。
    Minor Iteration limit 小さな反復の反復数の限界値。
    Minor print level 小さな反復の結果出力レベル。
    Workspace provided is 用意されているワークスペース。
    To solve problem we need 問題を解くのに必要なワークスペース。
  • 41行目には最大相対誤差が出力されています。
  • 50行目には目的関数の方向導関数が出力されています。
  • 51行目には差分近似が出力されています。
  • 54~60行目には以下が出力されています。
    Maj 大きな反復の回数。
    Mnr 実行可能解生成フェーズや最適化フェーズで必要とされる小さな反復の回数。
    Step 探索方向に進んだステップ幅。
    Merit Function ラグランジュメリット関数の値。
    Violtn 違反した制約の残差のユークリッド・ノルム。
    Norm Gz 予測される勾配のユークリッド・ノルム。
    Cond Hz 予測されるヘッセ近似行列の条件数の下限。
  • 66~71行目には以下が出力されています。
    Varbl 変数を示す "V"、インデックス。
    State 変数の状態。"LL" は下限であることを意味し、"FR" は下限も上限もワーキングセットにはないことを意味します。
    Value 最後の反復での変数の値。
    Lower Bound 変数の下限。
    Upper Bound 変数の上限。
    Lagr Mult 関連する境界のラグランジュ乗数。
    Slack スラック(変数の値と上限/下限の近いほうとの差)。
  • 74~76行目には以下が出力されています。
    L Con 線形制約を示す"L"、インデックス
    State 制約の状態。"FR" は下限も上限もワーキングセットにはないことを意味します。
    Value 最後の反復での制約の値。
    Lower Bound 線形制約の下限。
    Upper Bound 線形制約の上限。
    Lagr Mult 関連する境界のラグランジュ乗数。
    Slack スラック(制約の値と上限/下限の近いほうとの差)。
  • 79~82行目には以下が出力されています。
    N Con 非線形制約を示す "N"、インデックス。
    State 非線形制約の状態。"UL" は上限であることを意味し、"LL" は下限であることを意味します。
    Value 最後の反復の制約の値。
    Lower Bound 非線形制約の下限。
    Upper Bound 非線形制約の上限。
    Lagr Mult 関連する境界制約のラグランジュ乗数。
    Slack スラック(制約の値と上限/下限の近いほうとの差)。
  • 84行目にLPの最適解が見つかって終了したことが示されています。
  • 86行目にLPの最終的な目的関数値が出力されています。
  • 88行目にエラーを検知せずに本関数 e04uc を終了したことが示されています。
  • 90~95行目には以下が出力されています。
    Varbl 変数を示す "V"、インデックス。
    Istate 変数の状態。"0" はFeasibility toleranceの範囲内にあるが下限も上限もワーキングセットにはないことを意味します。"1" は下限がワーキングセットにあることを意味します。
    Value 最後の反復での変数の値。
    Lagr Mult 関連する境界のラグランジュ乗数。
  • 98~100行目には以下が出力されています。
    L Con 線形制約を示す "L"、インデックス。
    Istate 制約の状態。"0" はFeasibiilty toleranceの範囲内にあるが下限も上限もワーキングセットにはないことを意味します。
    Value 最後の反復での制約の値。
    Lagr Mult 関連する境界のラグランジュ乗数。
  • 103~106行目には以下が出力されています。
    N Con 非線形制約を示す "N"、インデックス。
    Istate 制約の状態。"1" は下限がワーキングセットにあることを意味し、"2" は上限がワーキングセットにあることを意味します。
    Value 最後の反復での制約の値。
    Lagr Mult 関連する境界のラグランジュ乗数。
  • 109行目に LP の最終的な目的関数値が出力されています。

ソースコード

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

※本サンプルソースコードは .NET環境用の科学技術・統計計算ライブラリである「nAG Library for .NET」の関数を呼び出します。
サンプルのコンパイル及び実行方法

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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

このソースコードをダウンロード
//      e04uc Example Program Text
//      C# version, nAG Copyright 2008
using System;
using NagLibrary;
using System.IO;
namespace NagDotNetExamples
{
  public class E04UCE
  {
    static bool defaultdata = true;
    static string datafile = "";
    // as a command line argument. It defaults to the named file specified below otherwise.
    //
    static void Main(String[] args)
    {
      if (args.Length == 1)
      {
        defaultdata = false;
        datafile = args[0];
      }
      StartExample();
    }
    public static void StartExample()
    {
      E04.E04UC_CONFUN confunE04UC = new E04.E04UC_CONFUN(confun);
      E04.E04UC_OBJFUN objfunE04UC = new E04.E04UC_OBJFUN(objfun);
      try
      {
        DataReader sr = null;
        if(defaultdata)
        {
          sr = new DataReader("exampledata/e04uce.d");
        }
        else
        {
          sr = new DataReader(datafile);
        }
        double objf = 0.0;
        int i,  ifail,  iter,  j,  n,  nclin,  ncnln;
        Console.WriteLine("e04uc Example Program Results");
        //      Skip heading in data file
        sr.Reset();
        sr.Reset();
        n = int.Parse(sr.Next());
        nclin = int.Parse(sr.Next());
        ncnln = int.Parse(sr.Next());
        double[,] a = new double[nclin, n];
        double[] bl = new double[n + nclin + ncnln];
        double[] bu = new double[n + nclin + ncnln];
        double[] c = new double[ncnln];
        double[,] cjac = new double[ncnln, n];
        double[] clamda = new double[n + nclin + ncnln];
        double[] objgrd = new double[n];
        double[,] r = new double[n, n];
        double[] x = new double[n];
        double[] work = new double[nclin];
        int[] istate = new int[n + nclin + ncnln];
        //
        //         Read a, bl, bu and x from data file
        //
        if (nclin > 0)
        {
          sr.Reset();
          for (i = 1; i <= nclin; i++)
          {
            for (j = 1; j <= n; j++)
            {
              a[i - 1, j - 1] = double.Parse(sr.Next());
            }
          }
        }
        sr.Reset();
        for (i = 1; i <= n + nclin + ncnln; i++)
        {
          bl[i - 1] = double.Parse(sr.Next());
        }
        sr.Reset();
        for (i = 1; i <= n + nclin + ncnln; i++)
        {
          bu[i - 1] = double.Parse(sr.Next());
        }
        sr.Reset();
        for (i = 1; i <= n; i++)
        {
          x[i - 1] = double.Parse(sr.Next());
        }
        //
        //         Initialise E04.E04UC and check for error exits
        //
        E04.e04ucOptions options = new E04.e04ucOptions();
        options.Set("List");
        options.Set("Print level = 10");
        //
        //            Solve the problem
        //
        //
        E04.e04uc(n, nclin, ncnln, a, bl, bu, confunE04UC, objfunE04UC, out iter, istate, c,
        cjac,
        clamda, out objf, objgrd, r, x, options, out ifail);
        //
        //            Check for error exits
        //
        Console.WriteLine("");
        if (ifail >= (9))
        {
          Console.WriteLine("   ** An input parameter is invalid");
        }
        else if (ifail == 7)
        {
          Console.WriteLine("  User supplied derivatives are incorrect");
        }
        else if (ifail == -399)
        {
          Console.WriteLine(" ** e04uc returned with ifail = {0, 3}", ifail);
        }
        else if (ifail < 0)
        {
          Console.WriteLine("  MODE < 0 on exit from OBJFUN or CONFUN.\n\n Problem abandoned.");
        }
        else
        {
          Console.WriteLine(" ** e04uc returned with ifail = {0, 3}", ifail);
          Console.WriteLine("");
          Console.WriteLine("  Varbl    Istate            Value         Lagr Mult");
          Console.WriteLine("");
          for (i = 1; i <= n; i++)
          {
            Console.WriteLine("  V  {0,3}  {1,3}        {2,14:g6}    {3,12:g4}", i, istate[i - 1],
 x[i - 1], clamda[i - 1]);
          }
          if (nclin > 0)
          {
            //
            // This performs the matrix vector multiplication A*X
            // (linear constraint values) and puts the result in
            // the first nclin locations of work.
            //
            F06.f06pa("N", nclin, n, 1.00e0, a, x, 1, 0.00e0, work, 1, out ifail);
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("  L Con    Istate      Value                  Lagr Mult");
            Console.WriteLine("");
            for (i = n + 1; i <= n + nclin; i++)
            {
              j = i - n;
              Console.WriteLine("  L  {0,3}  {1,3}        {2,14:g6}    {3,12:g4}", j, istate[i - 1],
 work[j - 1], clamda[i - 1]);
            }
          }
          if (ncnln > 0)
          {
            Console.WriteLine("");
            Console.WriteLine("");
            Console.WriteLine("  N Con    Istate             Value           Lagr Mult");
            Console.WriteLine("");
            for (i = n + nclin + 1; i <= n + nclin + ncnln; i++)
            {
              j = i - n - nclin;
              Console.WriteLine("  N  {0,3}  {1,3}        {2,14:g6}    {3,12:g4}", j, istate[i - 1], 
c[j - 1], clamda[i - 1]);
            }
          }
          Console.WriteLine("");
          Console.WriteLine("");
          Console.WriteLine("  Final objective value = {0,15:g7}", objf);
        }
        //
      }
      catch (Exception e)
      {
        Console.WriteLine(e.Message);
        Console.WriteLine( "Exception Raised");
      }
    }
    //
    public static void objfun(ref int mode, int n, double[] x, ref double objf,
    double[] objgrd, int nstate)
    {
      //      Routine to evaluate objective function and its 1st derivatives.
      double one = 1.00e0;
      double two = 2.00e0;
      if ((mode == 0) || (mode == 2))
      {
        objf = x[0] * x[3] * (x[0] + x[1] + x[2]) + x[2];
      }
      //
      if ((mode == 1) || (mode == 2))
      {
        objgrd[0] = x[3] * (two * x[0] + x[1] + x[2]);
        objgrd[1] = x[0] * x[3];
        objgrd[2] = x[0] * x[3] + one;
        objgrd[3] = x[0] * (x[0] + x[1] + x[2]);
      }
      //
    }
    //
    public static void confun(ref int mode, int ncnln, int n, int[] needc, double[] x,
    double[] c, double[,] cjac, int nstate)
    {
      //      Routine to evaluate the nonlinear constraints and their 1st
      //      derivatives.
      double zero = 0.00e0;
      double two = 2.00e0;
      int i,  j;
      if (nstate == 1)
      {
        //         First call to confun.  Set all Jacobian elements to zero.
        //         Note that this will only work when 'Derivative Level = 3'
        //         (the default; see Section 11.2).
        for (j = 1; j <= n; j++)
        {
          for (i = 1; i <= ncnln; i++)
          {
            cjac[i - 1, j - 1] = zero;
          }
        }
      }
      //
      if (needc[0] > 0)
      {
        if ((mode == 0) || (mode == 2))
        {
          c[0] = (x[0]) * (x[0]) + (x[1]) * (x[1]) + (x[2]) * (x[2]) + (x[3]) * (x[3]);
        }
        if ((mode == 1) || (mode == 2))
        {
          cjac[0, 0] = two * x[0];
          cjac[0, 1] = two * x[1];
          cjac[0, 2] = two * x[2];
          cjac[0, 3] = two * x[3];
        }
      }
      //
      if (needc[1] > 0)
      {
        if ((mode == 0) || (mode == 2))
        {
          c[1] = x[0] * x[1] * x[2] * x[3];
        }
        if ((mode == 1) || (mode == 2))
        {
          cjac[1, 0] = x[1] * x[2] * x[3];
          cjac[1, 1] = x[0] * x[2] * x[3];
          cjac[1, 2] = x[0] * x[1] * x[3];
          cjac[1, 3] = x[0] * x[1] * x[2];
        }
      }
      //
    }
  }
}


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