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]; } } // } } }