情報学部 | 菅沼ホーム | 目次 | 索引 |
/**************************************/ /* シンプレックス法による最小値の計算 */ /* coded by Y.Suganuma */ /**************************************/ #include <stdio.h> double snx1(double *); double snx2(double *); double snx3(double *); int simplex(int, int, double, double, double, double, double *, double *, double (*)(double *)); int main() { double eps, r1, r2, *x, y, k; int fun, i1, max, n, sw = 0; // データの入力 scanf("%*s %d %*s %d %*s %d %*s %lf", &fun, &n, &max, &k); scanf("%*s %lf %*s %lf %*s %lf", &eps, &r1, &r2); x = new double [n]; scanf("%*s"); for (i1 = 0; i1 < n; i1++) scanf("%lf", &x[i1]); // 実行 switch (fun) { case 1: sw = simplex(max, n, k, eps, r1, r2, &y, x, snx1); break; case 2: sw = simplex(max, n, k, eps, r1, r2, &y, x, snx2); break; case 3: sw = simplex(max, n, k, eps, r1, r2, &y, x, snx3); break; } // 結果の出力 if (sw < 0) printf(" 収束しませんでした!"); else { printf(" 結果="); for (i1 = 0; i1 < n; i1++) printf("%f ", x[i1]); printf(" 最小値=%f 回数=%d\n", y, sw); } delete [] x; return 0; } /******************************************/ /* シンプレックス法 */ /* max : 最大繰り返し回数 */ /* n : 次元 */ /* k : 初期値設定係数 */ /* r1 : 縮小比率 */ /* r2 : 拡大比率 */ /* y : 最小値 */ /* x : x(初期値と答え) */ /* snx : 関数値を計算する関数名 */ /* return : >=0 : 正常終了(収束回数) */ /* =-1 : 収束せず */ /******************************************/ #include <math.h> int simplex(int max, int n, double k, double eps, double r1, double r2, double *y, double *x, double (*snx)(double *)) { double **xx, *yy, *xg, *xr, *xn, yr, yn, e; int i1, i2, fh = -1, fg = -1, fl = -1, count = 0, sw = -1; // 初期値の設定 yy = new double [n+1]; xg = new double [n]; xr = new double [n]; xn = new double [n]; xx = new double * [n+1]; for (i1 = 0; i1 < n+1; i1++) xx[i1] = new double [n]; for (i1 = 0; i1 < n+1; i1++) { for (i2 = 0; i2 < n; i2++) xx[i1][i2] = x[i2]; if (i1 > 0) xx[i1][i1-1] += k; yy[i1] = snx(xx[i1]); } // 最大値,最小値の計算 for (i1 = 0; i1 < n+1; i1++) { if (fh < 0 || yy[i1] > yy[fh]) fh = i1; if (fl < 0 || yy[i1] < yy[fl]) fl = i1; } for (i1 = 0; i1 < n+1; i1++) { if (i1 != fh && (fg < 0 || yy[i1] > yy[fg])) fg = i1; } // 最小値の計算 while (count < max && sw < 0) { count++; // 重心の計算 for (i1 = 0; i1 < n; i1++) xg[i1] = 0.0; for (i1 = 0; i1 < n+1; i1++) { if (i1 != fh) { for (i2 = 0; i2 < n; i2++) xg[i2] += xx[i1][i2]; } } for (i1 = 0; i1 < n; i1++) xg[i1] /= n; // 最大点の置き換え for (i1 = 0; i1 < n; i1++) xr[i1] = 2.0 * xg[i1] - xx[fh][i1]; yr = snx(xr); if (yr >= yy[fh]) { // 縮小 for (i1 = 0; i1 < n; i1++) xr[i1] = (1.0 - r1) * xx[fh][i1] + r1 * xr[i1]; yr = snx(xr); } else if (yr < (yy[fl]+(r2-1.0)*yy[fh])/r2) { // 拡大 for (i1 = 0; i1 < n; i1++) xn[i1] = r2 * xr[i1] - (r2 - 1.0) * xx[fh][i1]; yn = snx(xn); if (yn <= yr) { for (i1 = 0; i1 < n; i1++) xr[i1] = xn[i1]; yr = yn; } } for (i1 = 0; i1 < n; i1++) xx[fh][i1] = xr[i1]; yy[fh] = yr; // シンプレックス全体の縮小 if (yy[fh] >= yy[fg]) { for (i1 = 0; i1 < n+1; i1++) { if (i1 != fl) { for (i2 = 0; i2 < n; i2++) xx[i1][i2] = 0.5 * (xx[i1][i2] + xx[fl][i2]); yy[i1] = snx(xx[i1]); } } } // 最大値,最小値の計算 fh = -1; fg = -1; fl = -1; for (i1 = 0; i1 < n+1; i1++) { if (fh < 0 || yy[i1] > yy[fh]) fh = i1; if (fl < 0 || yy[i1] < yy[fl]) fl = i1; } for (i1 = 0; i1 < n+1; i1++) { if (i1 != fh && (fg < 0 || yy[i1] > yy[fg])) fg = i1; } // 収束判定 e = 0.0; for (i1 = 0; i1 < n+1; i1++) { if (i1 != fl) { yr = yy[i1] - yy[fl]; e += yr * yr; } } if (e < eps) sw = 0; } if (sw == 0) { sw = count; *y = yy[fl]; for (i1 = 0; i1 < n; i1++) x[i1] = xx[fl][i1]; } delete [] yy; delete [] xg; delete [] xr; delete [] xn; for (i1 = 0; i1 < n+1; i1++) delete [] xx[i1]; delete [] xx; return sw; } /*******************/ /* 関数値の計算 */ /* y = f(x) */ /* return : y */ /*******************/ // 関数1 double snx1(double *x) { double x1, y1, y; x1 = x[0] - 1.0; y1 = x[1] - 2.0; y = x1 * x1 + y1 * y1; return y; } // 関数2 double snx2(double *x) { double x1, y1, y; x1 = x[1] - x[0] * x[0]; y1 = 1.0 - x[0]; y = 100.0 * x1 * x1 + y1 * y1; return y; } // 関数3 double snx3(double *x) { double x1, y1, z1, y; x1 = 1.5 - x[0] * (1.0 - x[1]); y1 = 2.25 - x[0] * (1.0 - x[1] * x[1]); z1 = 2.625 - x[0] * (1.0 - x[1] * x[1] * x[1]); y = x1 * x1 + y1 * y1 + z1 * z1; return y; }
/**************************************/ /* シンプレックス法による最小値の計算 */ /* coded by Y.Suganuma */ /**************************************/ import java.io.*; import java.util.StringTokenizer; public class Test { public static void main(String args[]) throws IOException { double eps, r1, r2, x[], y[], k; int fun, i1, max, n, sw = 0; StringTokenizer str; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); // データの入力 str = new StringTokenizer(in.readLine(), " "); str.nextToken(); fun = Integer.parseInt(str.nextToken()); str.nextToken(); n = Integer.parseInt(str.nextToken()); str.nextToken(); max = Integer.parseInt(str.nextToken()); str.nextToken(); k = Double.parseDouble(str.nextToken()); x = new double [n]; y = new double [1]; str = new StringTokenizer(in.readLine(), " "); str.nextToken(); eps = Double.parseDouble(str.nextToken()); str.nextToken(); r1 = Double.parseDouble(str.nextToken()); str.nextToken(); r2 = Double.parseDouble(str.nextToken()); str = new StringTokenizer(in.readLine(), " "); str.nextToken(); for (i1 = 0; i1 < n; i1++) { x[i1] = Double.parseDouble(str.nextToken()); } // 実行 Kansu kn = new Kansu(fun); sw = kn.simplex(max, n, k, eps, r1, r2, y, x); // 結果の出力 if (sw < 0) System.out.print(" 収束しませんでした!"); else { System.out.print(" 結果="); for (i1 = 0; i1 < n; i1++) System.out.print(x[i1] + " "); System.out.println(" 最小値=" + y[0] + " 回数=" + sw); } } } /**********/ /* 関数値 */ /**********/ class Kansu extends Simplex { private int sw; // コンストラクタ Kansu (int s) {sw = s;} // 関数値の計算 double snx(double x[]) { double x1, y1, z1, y = 0.0; switch (sw) { case 1: x1 = x[0] - 1.0; y1 = x[1] - 2.0; y = x1 * x1 + y1 * y1; break; case 2: x1 = x[1] - x[0] * x[0]; y1 = 1.0 - x[0]; y = 100.0 * x1 * x1 + y1 * y1; break; case 3: x1 = 1.5 - x[0] * (1.0 - x[1]); y1 = 2.25 - x[0] * (1.0 - x[1] * x[1]); z1 = 2.625 - x[0] * (1.0 - x[1] * x[1] * x[1]); y = x1 * x1 + y1 * y1 + z1 * z1; break; } return y; } } abstract class Simplex { /******************************************/ /* シンプレックス法 */ /* max : 最大繰り返し回数 */ /* n : 次元 */ /* k : 初期値設定係数 */ /* r1 : 縮小比率 */ /* r2 : 拡大比率 */ /* y : 最小値 */ /* x : x(初期値と答え) */ /* return : >=0 : 正常終了(収束回数) */ /* =-1 : 収束せず */ /******************************************/ abstract double snx(double x[]); int simplex(int max, int n, double k, double eps, double r1, double r2, double y[], double x[]) { double xx[][], yy[], xg[], xr[], xn[], yr, yn, e; int i1, i2, fh = -1, fg = -1, fl = -1, count = 0, sw = -1; // 初期値の設定 yy = new double [n+1]; xg = new double [n]; xr = new double [n]; xn = new double [n]; xx = new double [n+1][n]; for (i1 = 0; i1 < n+1; i1++) { for (i2 = 0; i2 < n; i2++) xx[i1][i2] = x[i2]; if (i1 > 0) xx[i1][i1-1] += k; yy[i1] = snx(xx[i1]); } // 最大値,最小値の計算 for (i1 = 0; i1 < n+1; i1++) { if (fh < 0 || yy[i1] > yy[fh]) fh = i1; if (fl < 0 || yy[i1] < yy[fl]) fl = i1; } for (i1 = 0; i1 < n+1; i1++) { if (i1 != fh && (fg < 0 || yy[i1] > yy[fg])) fg = i1; } // 最小値の計算 while (count < max && sw < 0) { count++; // 重心の計算 for (i1 = 0; i1 < n; i1++) xg[i1] = 0.0; for (i1 = 0; i1 < n+1; i1++) { if (i1 != fh) { for (i2 = 0; i2 < n; i2++) xg[i2] += xx[i1][i2]; } } for (i1 = 0; i1 < n; i1++) xg[i1] /= n; // 最大点の置き換え for (i1 = 0; i1 < n; i1++) xr[i1] = 2.0 * xg[i1] - xx[fh][i1]; yr = snx(xr); if (yr >= yy[fh]) { // 縮小 for (i1 = 0; i1 < n; i1++) xr[i1] = (1.0 - r1) * xx[fh][i1] + r1 * xr[i1]; yr = snx(xr); } else if (yr < (yy[fl]+(r2-1.0)*yy[fh])/r2) { // 拡大 for (i1 = 0; i1 < n; i1++) xn[i1] = r2 * xr[i1] - (r2 - 1.0) * xx[fh][i1]; yn = snx(xn); if (yn <= yr) { for (i1 = 0; i1 < n; i1++) xr[i1] = xn[i1]; yr = yn; } } for (i1 = 0; i1 < n; i1++) xx[fh][i1] = xr[i1]; yy[fh] = yr; // シンプレックス全体の縮小 if (yy[fh] >= yy[fg]) { for (i1 = 0; i1 < n+1; i1++) { if (i1 != fl) { for (i2 = 0; i2 < n; i2++) xx[i1][i2] = 0.5 * (xx[i1][i2] + xx[fl][i2]); yy[i1] = snx(xx[i1]); } } } // 最大値,最小値の計算 fh = -1; fg = -1; fl = -1; for (i1 = 0; i1 < n+1; i1++) { if (fh < 0 || yy[i1] > yy[fh]) fh = i1; if (fl < 0 || yy[i1] < yy[fl]) fl = i1; } for (i1 = 0; i1 < n+1; i1++) { if (i1 != fh && (fg < 0 || yy[i1] > yy[fg])) fg = i1; } // 収束判定 e = 0.0; for (i1 = 0; i1 < n+1; i1++) { if (i1 != fl) { yr = yy[i1] - yy[fl]; e += yr * yr; } } if (e < eps) sw = 0; } if (sw == 0) { sw = count; y[0] = yy[fl]; for (i1 = 0; i1 < n; i1++) x[i1] = xx[fl][i1]; } return sw; } }
<!DOCTYPE HTML> <HTML> <HEAD> <TITLE>最適化(シンプレックス法)</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> <SCRIPT TYPE="text/javascript"> str = ""; function main() { // データの設定 let n = parseInt(document.getElementById("n").value); let max = parseInt(document.getElementById("max").value); let k = parseFloat(document.getElementById("k").value); let r1 = parseFloat(document.getElementById("r1").value); let r2 = parseFloat(document.getElementById("r2").value); let x = document.getElementById("x0").value.split(/ {1,}/) for (let i1 = 0; i1 < n; i1++) x[i1] = parseFloat(x[i1]); str = document.getElementById("func").value + ";"; let eps = 1.0e-20; let y = new Array(); // 実行 let sw = simplex(max, n, k, eps, r1, r2, y, x, snx); // 結果 let res; if (sw < 0) { res = " 収束しませんでした!"; switch (sw) { case -1: res += "(収束回数)"; break; case -2: res += "(1次元最適化の区間)"; break; case -3: res += "(黄金分割法)"; break; } document.getElementById("res").value = res; } else { let c = 100000; res = " x ="; for (let i1 = 0; i1 < n; i1++) { let s1 = Math.round(x[i1] * c) / c; res = res + " " + s1; } res += "\n"; let s2 = Math.round(y[0] * c) / c; res = res + " 最小値 = " + s2 + " 回数 = " + sw; document.getElementById("res").value = res; } } /****************/ /* 関数値の計算 */ /****************/ function snx(x) { let y = eval(str); return y; } /******************************************/ /* シンプレックス法 */ /* max : 最大繰り返し回数 */ /* n : 次元 */ /* k : 初期値設定係数 */ /* r1 : 縮小比率 */ /* r2 : 拡大比率 */ /* y : 最小値 */ /* x : x(初期値と答え) */ /* fn : 関数値を計算する関数 */ /* return : >=0 : 正常終了(収束回数) */ /* =-1 : 収束せず */ /******************************************/ function simplex(max, n, k, eps, r1, r2, y, x, fn) { let yr, yn, e, fh = -1, fg = -1, fl = -1, count = 0, sw = -1; // 初期値の設定 yy = new Array(); xg = new Array(); xr = new Array(); xn = new Array(); xx = new Array(); for (let i1 = 0; i1 < n+1; i1++) { xx[i1] = new Array(); for (let i2 = 0; i2 < n; i2++) xx[i1][i2] = x[i2]; if (i1 > 0) xx[i1][i1-1] += k; yy[i1] = fn(xx[i1]); } // 最大値,最小値の計算 for (let i1 = 0; i1 < n+1; i1++) { if (fh < 0 || yy[i1] > yy[fh]) fh = i1; if (fl < 0 || yy[i1] < yy[fl]) fl = i1; } for (let i1 = 0; i1 < n+1; i1++) { if (i1 != fh && (fg < 0 || yy[i1] > yy[fg])) fg = i1; } // 最小値の計算 while (count < max && sw < 0) { count++; // 重心の計算 for (let i1 = 0; i1 < n; i1++) xg[i1] = 0.0; for (let i1 = 0; i1 < n+1; i1++) { if (i1 != fh) { for (let i2 = 0; i2 < n; i2++) xg[i2] += xx[i1][i2]; } } for (let i1 = 0; i1 < n; i1++) xg[i1] /= n; // 最大点の置き換え for (let i1 = 0; i1 < n; i1++) xr[i1] = 2.0 * xg[i1] - xx[fh][i1]; yr = fn(xr); if (yr >= yy[fh]) { // 縮小 for (i1 = 0; i1 < n; i1++) xr[i1] = (1.0 - r1) * xx[fh][i1] + r1 * xr[i1]; yr = fn(xr); } else if (yr < (yy[fl]+(r2-1.0)*yy[fh])/r2) { // 拡大 for (let i1 = 0; i1 < n; i1++) xn[i1] = r2 * xr[i1] - (r2 - 1.0) * xx[fh][i1]; yn = fn(xn); if (yn <= yr) { for (i1 = 0; i1 < n; i1++) xr[i1] = xn[i1]; yr = yn; } } for (let i1 = 0; i1 < n; i1++) xx[fh][i1] = xr[i1]; yy[fh] = yr; // シンプレックス全体の縮小 if (yy[fh] >= yy[fg]) { for (let i1 = 0; i1 < n+1; i1++) { if (i1 != fl) { for (let i2 = 0; i2 < n; i2++) xx[i1][i2] = 0.5 * (xx[i1][i2] + xx[fl][i2]); yy[i1] = fn(xx[i1]); } } } // 最大値,最小値の計算 fh = -1; fg = -1; fl = -1; for (let i1 = 0; i1 < n+1; i1++) { if (fh < 0 || yy[i1] > yy[fh]) fh = i1; if (fl < 0 || yy[i1] < yy[fl]) fl = i1; } for (let i1 = 0; i1 < n+1; i1++) { if (i1 != fh && (fg < 0 || yy[i1] > yy[fg])) fg = i1; } // 収束判定 e = 0.0; for (let i1 = 0; i1 < n+1; i1++) { if (i1 != fl) { yr = yy[i1] - yy[fl]; e += yr * yr; } } if (e < eps) sw = 0; } if (sw == 0) { sw = count; y[0] = yy[fl]; for (let i1 = 0; i1 < n; i1++) x[i1] = xx[fl][i1]; } return sw; } </SCRIPT> </HEAD> <BODY STYLE="font-size: 130%; background-color: #eeffee;"> <H2 STYLE="text-align:center"><B>最適化(シンプレックス法)</B></H2> <DL> <DT> テキストフィールドには,例として,以下に示すような関数の最小値を求める場合に対する値が設定されています(他の問題を実行する場合は,それらを適切に修正してください). <P STYLE="text-align:center"><IMG SRC="simplex.gif"></P> <DT>目的関数の箇所には,その計算式が与えられています.ただし,プログラム内では,変数 x は,この例の x と y からなる配列として表現されています.なお,目的関数は,JavaScript の仕様に適合した形式で記述してあることに注意してください. </DL> <DIV STYLE="text-align:center"> 変数の数(n):<INPUT ID="n" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="2"> 最大繰り返し回数:<INPUT ID="max" STYLE="font-size: 100%" TYPE="text" SIZE="3" VALUE="1000"> 初期値設定係数:<INPUT ID="k" STYLE="font-size: 100%" TYPE="text" SIZE="3" VALUE="1.0"><BR> 縮小比率:<INPUT ID="r1" STYLE="font-size: 100%" TYPE="text" SIZE="3" VALUE="0.7"> 拡大比率:<INPUT ID="r2" STYLE="font-size: 100%" TYPE="text" SIZE="3" VALUE="1.5"> 初期値(n個):<INPUT ID="x0" STYLE="font-size: 100%" TYPE="text" SIZE="20" VALUE="0.0 0.0"><BR><BR> 目的関数: f(x) = <INPUT ID="func" STYLE="font-size: 100%" TYPE="text" SIZE="70" VALUE="100.0 * (x[1] - x[0] * x[0]) * (x[1] - x[0] * x[0]) + (1.0 - x[0]) * (1.0 - x[0])"><BR><BR> <BUTTON STYLE="font-size: 100%; background-color: pink" onClick="main()">実行</BUTTON><BR><BR> 結果:<TEXTAREA ID="res" STYLE="font-size: 110%" COLS="40" ROWS="2"></TEXTAREA> </DIV> </BODY> </HTML>
<?php /**************************************/ /* シンプレックス法による最小値の計算 */ /* coded by Y.Suganuma */ /**************************************/ $sw = 0; // データの入力 fscanf(STDIN, "%*s %d %*s %d %*s %d %*s %lf", $fun, $n, $max, $k); fscanf(STDIN, "%*s %lf %*s %lf %*s %lf", $eps, $r1, $r2); $x = array($n); $str = trim(fgets(STDIN)); strtok($str, " "); for ($i1 = 0; $i1 < $n; $i1++) $x[$i1] = floatval(strtok(" ")); // 実行 switch ($fun) { case 1: $sw = simplex($max, $n, $k, $eps, $r1, $r2, $y, $x, "snx1"); break; case 2: $sw = simplex($max, $n, $k, $eps, $r1, $r2, $y, $x, "snx2"); break; case 3: $sw = simplex($max, $n, $k, $eps, $r1, $r2, $y, $x, "snx3"); break; } // 結果の出力 if ($sw < 0) printf(" 収束しませんでした!"); else { printf(" 結果="); for ($i1 = 0; $i1 < $n; $i1++) printf("%f ", $x[$i1]); printf(" 最小値=%f 回数=%d\n", $y, $sw); } /******************************************/ /* シンプレックス法 */ /* max : 最大繰り返し回数 */ /* n : 次元 */ /* k : 初期値設定係数 */ /* r1 : 縮小比率 */ /* r2 : 拡大比率 */ /* y : 最小値 */ /* x : x(初期値と答え) */ /* snx : 関数値を計算する関数名 */ /* return : >=0 : 正常終了(収束回数) */ /* =-1 : 収束せず */ /******************************************/ function simplex($max, $n, $k, $eps, $r1, $r2, &$y, &$x, $snx) { // 初期値の設定 $fh = -1; $fg = -1; $fl = -1; $count = 0; $sw = -1; $yy = array($n+1); $xg = array($n); $xr = array($n); $xn = array($n); $xx = array($n+1); for ($i1 = 0; $i1 < $n+1; $i1++) $xx[$i1] = array($n); for ($i1 = 0; $i1 < $n+1; $i1++) { for ($i2 = 0; $i2 < $n; $i2++) $xx[$i1][$i2] = $x[$i2]; if ($i1 > 0) $xx[$i1][$i1-1] += $k; $yy[$i1] = $snx($xx[$i1]); } // 最大値,最小値の計算 for ($i1 = 0; $i1 < $n+1; $i1++) { if ($fh < 0 || $yy[$i1] > $yy[$fh]) $fh = $i1; if ($fl < 0 || $yy[$i1] < $yy[$fl]) $fl = $i1; } for ($i1 = 0; $i1 < $n+1; $i1++) { if ($i1 != $fh && ($fg < 0 || $yy[$i1] > $yy[$fg])) $fg = $i1; } // 最小値の計算 while ($count < $max && $sw < 0) { $count++; // 重心の計算 for ($i1 = 0; $i1 < $n; $i1++) $xg[$i1] = 0.0; for ($i1 = 0; $i1 < $n+1; $i1++) { if ($i1 != $fh) { for ($i2 = 0; $i2 < $n; $i2++) $xg[$i2] += $xx[$i1][$i2]; } } for ($i1 = 0; $i1 < $n; $i1++) $xg[$i1] /= $n; // 最大点の置き換え for ($i1 = 0; $i1 < $n; $i1++) $xr[$i1] = 2.0 * $xg[$i1] - $xx[$fh][$i1]; $yr = $snx($xr); if ($yr >= $yy[$fh]) { // 縮小 for ($i1 = 0; $i1 < $n; $i1++) $xr[$i1] = (1.0 - $r1) * $xx[$fh][$i1] + $r1 * $xr[$i1]; $yr = $snx($xr); } else if ($yr < ($yy[$fl]+($r2-1.0)*$yy[$fh])/$r2) { // 拡大 for ($i1 = 0; $i1 < $n; $i1++) $xn[$i1] = $r2 * $xr[$i1] - ($r2 - 1.0) * $xx[$fh][$i1]; $yn = $snx($xn); if ($yn <= $yr) { for ($i1 = 0; $i1 < $n; $i1++) $xr[$i1] = $xn[$i1]; $yr = $yn; } } for ($i1 = 0; $i1 < $n; $i1++) $xx[$fh][$i1] = $xr[$i1]; $yy[$fh] = $yr; // シンプレックス全体の縮小 if ($yy[$fh] >= $yy[$fg]) { for ($i1 = 0; $i1 < $n+1; $i1++) { if ($i1 != $fl) { for ($i2 = 0; $i2 < $n; $i2++) $xx[$i1][$i2] = 0.5 * ($xx[$i1][$i2] + $xx[$fl][$i2]); $yy[$i1] = $snx($xx[$i1]); } } } // 最大値,最小値の計算 $fh = -1; $fg = -1; $fl = -1; for ($i1 = 0; $i1 < $n+1; $i1++) { if ($fh < 0 || $yy[$i1] > $yy[$fh]) $fh = $i1; if ($fl < 0 || $yy[$i1] < $yy[$fl]) $fl = $i1; } for ($i1 = 0; $i1 < $n+1; $i1++) { if ($i1 != $fh && ($fg < 0 || $yy[$i1] > $yy[$fg])) $fg = $i1; } // 収束判定 $e = 0.0; for ($i1 = 0; $i1 < $n+1; $i1++) { if ($i1 != $fl) { $yr = $yy[$i1] - $yy[$fl]; $e += $yr * $yr; } } if ($e < $eps) $sw = 0; } if ($sw == 0) { $sw = $count; $y = $yy[$fl]; for ($i1 = 0; $i1 < $n; $i1++) $x[$i1] = $xx[$fl][$i1]; } return $sw; } /*******************/ /* 関数値の計算 */ /* y = f(x) */ /* return : y */ /*******************/ // 関数1 function snx1($x) { $x1 = $x[0] - 1.0; $y1 = $x[1] - 2.0; $y = $x1 * $x1 + $y1 * $y1; return $y; } // 関数2 function snx2($x) { $x1 = $x[1] - $x[0] * $x[0]; $y1 = 1.0 - $x[0]; $y = 100.0 * $x1 * $x1 + $y1 * $y1; return $y; } // 関数3 function snx3($x) { $x1 = 1.5 - $x[0] * (1.0 - $x[1]); $y1 = 2.25 - $x[0] * (1.0 - $x[1] * $x[1]); $z1 = 2.625 - $x[0] * (1.0 - $x[1] * $x[1] * $x[1]); $y = $x1 * $x1 + $y1 * $y1 + $z1 * $z1; return $y; } ?>
#*************************************/ # シンプレックス法による最小値の計算 */ # coded by Y.Suganuma */ #*************************************/ #******************/ # 関数値の計算 */ # y = f(x) */ # return : y */ #******************/ # 関数1 snx1 = Proc.new { |x| x1 = x[0] - 1.0 y1 = x[1] - 2.0 x1 * x1 + y1 * y1 } # 関数2 snx2 = Proc.new { |x| x1 = x[1] - x[0] * x[0] y1 = 1.0 - x[0] 100.0 * x1 * x1 + y1 * y1 } # 関数3 snx3 = Proc.new { |x| x1 = 1.5 - x[0] * (1.0 - x[1]) y1 = 2.25 - x[0] * (1.0 - x[1] * x[1]) z1 = 2.625 - x[0] * (1.0 - x[1] * x[1] * x[1]) x1 * x1 + y1 * y1 + z1 * z1 } #*****************************************/ # シンプレックス法 */ # max : 最大繰り返し回数 */ # n : 次元 */ # k : 初期値設定係数 */ # r1 : 縮小比率 */ # r2 : 拡大比率 */ # y : 最小値 */ # x : x(初期値と答え) */ # snx : 関数値を計算する関数名 */ # return : >=0 : 正常終了(収束回数) */ # =-1 : 収束せず */ #*****************************************/ def simplex(max, n, k, eps, r1, r2, y, x, &snx) # 初期値の設定 fh = -1 fg = -1 fl = -1 count = 0 sw = -1 yy = Array.new(n+1) xg = Array.new(n) xr = Array.new(n) xn = Array.new(n) xx = Array.new(n+1) for i1 in 0 ... n+1 xx[i1] = Array.new(n) end for i1 in 0 ... n+1 for i2 in 0 ... n xx[i1][i2] = x[i2] end if i1 > 0 xx[i1][i1-1] += k end yy[i1] = snx.call(xx[i1]) end # 最大値,最小値の計算 for i1 in 0 ... n+1 if fh < 0 || yy[i1] > yy[fh] fh = i1 end if fl < 0 || yy[i1] < yy[fl] fl = i1 end end for i1 in 0 ... n+1 if i1 != fh && (fg < 0 || yy[i1] > yy[fg]) fg = i1 end end # 最小値の計算 while count < max && sw < 0 count += 1 # 重心の計算 for i1 in 0 ... n xg[i1] = 0.0 end for i1 in 0 ... n+1 if i1 != fh for i2 in 0 ... n xg[i2] += xx[i1][i2] end end end for i1 in 0 ... n xg[i1] /= n end # 最大点の置き換え for i1 in 0 ... n xr[i1] = 2.0 * xg[i1] - xx[fh][i1] end yr = snx.call(xr) if yr >= yy[fh] # 縮小 for i1 in 0 ... n xr[i1] = (1.0 - r1) * xx[fh][i1] + r1 * xr[i1] end yr = snx.call(xr) elsif yr < (yy[fl]+(r2-1.0)*yy[fh])/r2 # 拡大 for i1 in 0 ... n xn[i1] = r2 * xr[i1] - (r2 - 1.0) * xx[fh][i1] end yn = snx.call(xn) if yn <= yr for i1 in 0 ... n xr[i1] = xn[i1] end yr = yn end end for i1 in 0 ... n xx[fh][i1] = xr[i1] end yy[fh] = yr # シンプレックス全体の縮小 if yy[fh] >= yy[fg] for i1 in 0 ... n+1 if i1 != fl for i2 in 0 ... n xx[i1][i2] = 0.5 * (xx[i1][i2] + xx[fl][i2]) end yy[i1] = snx.call(xx[i1]) end end end # 最大値,最小値の計算 fh = -1 fg = -1 fl = -1 for i1 in 0 ... n+1 if fh < 0 || yy[i1] > yy[fh] fh = i1 end if fl < 0 || yy[i1] < yy[fl] fl = i1 end end for i1 in 0 ... n+1 if i1 != fh && (fg < 0 || yy[i1] > yy[fg]) fg = i1 end end # 収束判定 e = 0.0 for i1 in 0 ... n+1 if i1 != fl yr = yy[i1] - yy[fl] e += yr * yr end end if e < eps sw = 0 end end if sw == 0 sw = count y[0] = yy[fl] for i1 in 0 ... n x[i1] = xx[fl][i1] end end return sw end # データの入力 sw = 0 str = gets() a = str.split(" ") fun = Integer(a[1]) n = Integer(a[3]) max = Integer(a[5]) k = Float(a[7]) str = gets(); a = str.split(" "); eps = Float(a[1]) r1 = Float(a[3]) r2 = Float(a[5]) x = Array.new(n) y = Array.new(1) sw = 0 str = gets(); a = str.split(" "); for i1 in 0 ... n x[i1] = Float(a[i1+1]) end # 実行 case fun when 1 sw = simplex(max, n, k, eps, r1, r2, y, x, &snx1) when 2 sw = simplex(max, n, k, eps, r1, r2, y, x, &snx2) when 3 sw = simplex(max, n, k, eps, r1, r2, y, x, &snx3) end # 結果の出力 if sw < 0 printf(" 収束しませんでした!") else printf(" 結果=") for i1 in 0 ... n printf("%f ", x[i1]) end printf(" 最小値=%f 回数=%d\n", y[0], sw) end
# -*- coding: UTF-8 -*- import numpy as np import sys from math import * ############################################ # シンプレックス法 # max : 最大繰り返し回数 # n : 次元 # k : 初期値設定係数 # r1 : 縮小比率 # r2 : 拡大比率 # y : 最小値 # x : x(初期値と答え) # snx : 関数値を計算する関数名 # return : >=0 : 正常終了(収束回数) # =-1 : 収束せず # coded by Y.Suganuma ############################################ def simplex(max, n, k, eps, r1, r2, y, x, snx) : # 初期値の設定 fh = -1 fg = -1 fl = -1 count = 0 sw = -1 yy = np.empty(n+1, np.float) xg = np.empty(n, np.float) xr = np.empty(n, np.float) xn = np.empty(n, np.float) xx = np.empty((n+1, n), np.float) for i1 in range(0, n+1) : for i2 in range(0, n) : xx[i1][i2] = x[i2] if i1 > 0 : xx[i1][i1-1] += k yy[i1] = snx(xx[i1]) # 最大値,最小値の計算 for i1 in range(0, n+1) : if fh < 0 or yy[i1] > yy[fh] : fh = i1 if fl < 0 or yy[i1] < yy[fl] : fl = i1 for i1 in range(0, n+1) : if i1 != fh and (fg < 0 or yy[i1] > yy[fg]) : fg = i1 # 最小値の計算 while count < max and sw < 0 : count += 1 # 重心の計算 for i1 in range(0, n) : xg[i1] = 0.0 for i1 in range(0, n+1) : if i1 != fh : for i2 in range(0, n) : xg[i2] += xx[i1][i2] for i1 in range(0, n) : xg[i1] /= n # 最大点の置き換え for i1 in range(0, n) : xr[i1] = 2.0 * xg[i1] - xx[fh][i1] yr = snx(xr) if yr >= yy[fh] : # 縮小 for i1 in range(0, n) : xr[i1] = (1.0 - r1) * xx[fh][i1] + r1 * xr[i1] yr = snx(xr) elif yr < (yy[fl]+(r2-1.0)*yy[fh])/r2 : # 拡大 for i1 in range(0, n) : xn[i1] = r2 * xr[i1] - (r2 - 1.0) * xx[fh][i1] yn = snx(xn) if yn <= yr : for i1 in range(0, n) : xr[i1] = xn[i1] yr = yn for i1 in range(0, n) : xx[fh][i1] = xr[i1] yy[fh] = yr # シンプレックス全体の縮小 if yy[fh] >= yy[fg] : for i1 in range(0, n+1) : if i1 != fl : for i2 in range(0, n) : xx[i1][i2] = 0.5 * (xx[i1][i2] + xx[fl][i2]) yy[i1] = snx(xx[i1]) # 最大値,最小値の計算 fh = -1 fg = -1 fl = -1 for i1 in range(0, n+1) : if fh < 0 or yy[i1] > yy[fh] : fh = i1 if fl < 0 or yy[i1] < yy[fl] : fl = i1 for i1 in range(0, n+1) : if i1 != fh and (fg < 0 or yy[i1] > yy[fg]) : fg = i1 # 収束判定 e = 0.0 for i1 in range(0, n+1) : if i1 != fl : yr = yy[i1] - yy[fl] e += yr * yr if e < eps : sw = 0 if sw == 0 : sw = count y[0] = yy[fl] for i1 in range(0, n) : x[i1] = xx[fl][i1] return sw ############################################ # シンプレックス法による最小値の計算 # coded by Y.Suganuma ############################################ ############### # 関数値の計算 ############### # 関数1 def snx1(x) : x1 = x[0] - 1.0 y1 = x[1] - 2.0 y = x1 * x1 + y1 * y1 return y # 関数2 def snx2(x) : x1 = x[1] - x[0] * x[0] y1 = 1.0 - x[0] y = 100.0 * x1 * x1 + y1 * y1 return y # 関数3 def snx3(x) : x1 = 1.5 - x[0] * (1.0 - x[1]) y1 = 2.25 - x[0] * (1.0 - x[1] * x[1]) z1 = 2.625 - x[0] * (1.0 - x[1] * x[1] * x[1]) y = x1 * x1 + y1 * y1 + z1 * z1 return y # データの入力 sw = 0 line = sys.stdin.readline() s = line.split() fun = int(s[1]) n = int(s[3]) max = int(s[5]) k = float(s[7]) line = sys.stdin.readline() s = line.split() eps = float(s[1]) r1 = float(s[3]) r2 = float(s[5]) x = np.empty(n, np.float) y = np.empty(1, np.float) line = sys.stdin.readline() s = line.split() for i1 in range(0, n) : x[i1] = float(s[i1+1]) # 実行 if fun == 1 : sw = simplex(max, n, k, eps, r1, r2, y, x, snx1) elif fun == 2 : sw = simplex(max, n, k, eps, r1, r2, y, x, snx2) else : sw = simplex(max, n, k, eps, r1, r2, y, x, snx3) # 結果の出力 if sw < 0 : print(" 収束しませんでした!") else : print(" 結果=", end="") for i1 in range(0, n) : print(str(x[i1]) + " ", end="") print(" 最小値=" + str(y[0]) + " 回数=" + str(sw))
/**************************************/ /* シンプレックス法による最小値の計算 */ /* coded by Y.Suganuma */ /**************************************/ using System; class Program { static void Main() { Test1 ts = new Test1(); } } class Test1 { public Test1() { // データの入力 // 1 行目 string[] str = Console.ReadLine().Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries); int fun = int.Parse(str[1]); int n = int.Parse(str[3]); int max = int.Parse(str[5]); double k = double.Parse(str[7]); // 2 行目 str = Console.ReadLine().Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries); double eps = double.Parse(str[1]); double r1 = double.Parse(str[3]); double r2 = double.Parse(str[5]); // 3 行目 double[] x = new double [n]; double y = 0.0; str = Console.ReadLine().Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries); for (int i1 = 0; i1 < n; i1++) x[i1] = double.Parse(str[i1+1]); // 実行 int sw; if (fun == 1) sw = simplex(max, n, k, eps, r1, r2, ref y, x, snx1); else if (fun == 2) sw = simplex(max, n, k, eps, r1, r2, ref y, x, snx2); else sw = simplex(max, n, k, eps, r1, r2, ref y, x, snx3); // 結果の出力 if (sw < 0) Console.WriteLine(" 収束しませんでした!"); else { Console.Write(" 結果="); for (int i1 = 0; i1 < n; i1++) Console.Write(x[i1] + " "); Console.WriteLine(" 最小値=" + y + " 回数=" + sw); } } // 関数1の値の計算 double snx1(double[] x) { double x1 = x[0] - 1.0; double y1 = x[1] - 2.0; double y = x1 * x1 + y1 * y1; return y; } // 関数2の値の計算 double snx2(double[] x) { double x1 = x[1] - x[0] * x[0]; double y1 = 1.0 - x[0]; double y = 100.0 * x1 * x1 + y1 * y1; return y; } // 関数3の値の計算 double snx3(double[] x) { double x1 = 1.5 - x[0] * (1.0 - x[1]); double y1 = 2.25 - x[0] * (1.0 - x[1] * x[1]); double z1 = 2.625 - x[0] * (1.0 - x[1] * x[1] * x[1]); double y = x1 * x1 + y1 * y1 + z1 * z1; return y; } /******************************************/ /* シンプレックス法 */ /* max : 最大繰り返し回数 */ /* n : 次元 */ /* k : 初期値設定係数 */ /* r1 : 縮小比率 */ /* r2 : 拡大比率 */ /* y : 最小値 */ /* x : x(初期値と答え) */ /* fn : 関数値を計算する関数 */ /* return : >=0 : 正常終了(収束回数) */ /* =-1 : 収束せず */ /******************************************/ int simplex(int max, int n, double k, double eps, double r1, double r2, ref double y, double[] x, Func<double[], double> fn) { // 初期値の設定 double[] yy = new double [n+1]; double[] xg = new double [n]; double[] xr = new double [n]; double[] xn = new double [n]; double[][] xx = new double [n+1][]; for (int i1 = 0; i1 < n+1; i1++) { xx[i1] = new double [n]; for (int i2 = 0; i2 < n; i2++) xx[i1][i2] = x[i2]; if (i1 > 0) xx[i1][i1-1] += k; yy[i1] = fn(xx[i1]); } // 最大値,最小値の計算 int fh = -1, fg = -1, fl = -1; for (int i1 = 0; i1 < n+1; i1++) { if (fh < 0 || yy[i1] > yy[fh]) fh = i1; if (fl < 0 || yy[i1] < yy[fl]) fl = i1; } for (int i1 = 0; i1 < n+1; i1++) { if (i1 != fh && (fg < 0 || yy[i1] > yy[fg])) fg = i1; } // 最小値の計算 int count = 0, sw = -1; while (count < max && sw < 0) { count++; // 重心の計算 for (int i1 = 0; i1 < n; i1++) xg[i1] = 0.0; for (int i1 = 0; i1 < n+1; i1++) { if (i1 != fh) { for (int i2 = 0; i2 < n; i2++) xg[i2] += xx[i1][i2]; } } for (int i1 = 0; i1 < n; i1++) xg[i1] /= n; // 最大点の置き換え for (int i1 = 0; i1 < n; i1++) xr[i1] = 2.0 * xg[i1] - xx[fh][i1]; double yr = fn(xr); if (yr >= yy[fh]) { // 縮小 for (int i1 = 0; i1 < n; i1++) xr[i1] = (1.0 - r1) * xx[fh][i1] + r1 * xr[i1]; yr = fn(xr); } else if (yr < (yy[fl]+(r2-1.0)*yy[fh])/r2) { // 拡大 for (int i1 = 0; i1 < n; i1++) xn[i1] = r2 * xr[i1] - (r2 - 1.0) * xx[fh][i1]; double yn = fn(xn); if (yn <= yr) { for (int i1 = 0; i1 < n; i1++) xr[i1] = xn[i1]; yr = yn; } } for (int i1 = 0; i1 < n; i1++) xx[fh][i1] = xr[i1]; yy[fh] = yr; // シンプレックス全体の縮小 if (yy[fh] >= yy[fg]) { for (int i1 = 0; i1 < n+1; i1++) { if (i1 != fl) { for (int i2 = 0; i2 < n; i2++) xx[i1][i2] = 0.5 * (xx[i1][i2] + xx[fl][i2]); yy[i1] = fn(xx[i1]); } } } // 最大値,最小値の計算 fh = -1; fg = -1; fl = -1; for (int i1 = 0; i1 < n+1; i1++) { if (fh < 0 || yy[i1] > yy[fh]) fh = i1; if (fl < 0 || yy[i1] < yy[fl]) fl = i1; } for (int i1 = 0; i1 < n+1; i1++) { if (i1 != fh && (fg < 0 || yy[i1] > yy[fg])) fg = i1; } // 収束判定 double e = 0.0; for (int i1 = 0; i1 < n+1; i1++) { if (i1 != fl) { yr = yy[i1] - yy[fl]; e += yr * yr; } } if (e < eps) sw = 0; } if (sw == 0) { sw = count; y = yy[fl]; for (int i1 = 0; i1 < n; i1++) x[i1] = xx[fl][i1]; } return sw; } }
'''''''''''''''''''''''''''''''''''''' ' シンプレックス法による最小値の計算 ' ' coded by Y.Suganuma ' '''''''''''''''''''''''''''''''''''''' Imports System.Text.RegularExpressions Module Test Sub Main() ' データの入力 ' 1 行目 Dim MS As Regex = New Regex("\s+") Dim str() As String = MS.Split(Console.ReadLine().Trim()) Dim fun As Integer = Integer.Parse(str(1)) Dim n As Integer = Integer.Parse(str(3)) Dim max As Integer = Integer.Parse(str(5)) Dim k As Integer = Double.Parse(str(7)) ' 2 行目 str = MS.Split(Console.ReadLine().Trim()) Dim eps As Double = Double.Parse(str(1)) Dim r1 As Double = Double.Parse(str(3)) Dim r2 As Double = Double.Parse(str(5)) ' 3 行目 Dim x(n) As Double Dim y As Double = 0.0 str = MS.Split(Console.ReadLine().Trim()) For i1 As Integer = 0 To n-1 x(i1) = Double.Parse(str(i1+1)) Next ' 関数1の値の計算(ラムダ式) Dim snx1 = Function(x0) As Double Dim x1 As Double = x0(0) - 1.0 Dim y1 As Double = x0(1) - 2.0 Dim y0 As Double = x1 * x1 + y1 * y1 Return y0 End Function ' 関数2の値の計算(ラムダ式) Dim snx2 = Function(x0) As Double Dim x1 As Double = x0(1) - x0(0) * x0(0) Dim y1 As Double = 1.0 - x0(0) Dim y0 As Double = 100.0 * x1 * x1 + y1 * y1 Return y0 End Function ' 関数3の値の計算(ラムダ式) Dim snx3 = Function(x0) As Double Dim x1 As Double = 1.5 - x0(0) * (1.0 - x0(1)) Dim y1 As Double = 2.25 - x0(0) * (1.0 - x0(1) * x0(1)) Dim z1 As Double = 2.625 - x0(0) * (1.0 - x0(1) * x0(1) * x0(1)) Dim y0 As Double = x1 * x1 + y1 * y1 + z1 * z1 Return y0 End Function ' 実行 Dim sw As Integer If fun = 1 sw = simplex(max, n, k, eps, r1, r2, y, x, snx1) ElseIf fun = 2 sw = simplex(max, n, k, eps, r1, r2, y, x, snx2) Else sw = simplex(max, n, k, eps, r1, r2, y, x, snx3) End If ' 結果の出力 If sw < 0 Console.Write(" 収束しませんでした!") Else Console.Write(" 結果=") For i1 As Integer = 0 To n-1 Console.Write(x(i1) & " ") Next Console.WriteLine(" 最小値=" & y & " 回数=" & sw) End If End Sub '''''''''''''''''''''''''''''''''''''''''' ' シンプレックス法 ' ' max : 最大繰り返し回数 ' ' n : 次元 ' ' k : 初期値設定係数 ' ' r1 : 縮小比率 ' ' r2 : 拡大比率 ' ' y : 最小値 ' ' x : x(初期値と答え) ' ' fn : 関数値を計算する関数 ' ' return : >=0 : 正常終了(収束回数) ' ' =-1 : 収束せず ' '''''''''''''''''''''''''''''''''''''''''' Function simplex(max As Integer, n As Integer, k As Double, eps As Double, r1 As Double, r2 As Double, ByRef y As Double, x() As Double, fn As Func(Of Double(), Double)) ' 初期値の設定 Dim yy(n+1) As Double Dim xg(n) As Double Dim xr(n) As Double Dim xn(n) As Double Dim xx(n+1,n) As Double For i1 As Integer = 0 To n For i2 As Integer = 0 To n-1 xx(i1,i2) = x(i2) Next If i1 > 0 xx(i1,i1-1) += k End If Dim xx1(n) As Double For i2 As Integer = 0 To n-1 xx1(i2) = xx(i1,i2) Next yy(i1) = fn(xx1) Next ' 最大値,最小値の計算 Dim fh As Integer = -1 Dim fg As Integer = -1 Dim fl As Integer = -1 For i1 As Integer = 0 To n If fh < 0 fh = i1 ElseIf yy(i1) > yy(fh) fh = i1 End If If fl < 0 fl = i1 ElseIf yy(i1) < yy(fl) fl = i1 End If Next For i1 As Integer = 0 To n If i1 <> fh If fg < 0 fg = i1 ElseIf yy(i1) > yy(fg) fg = i1 End If End If Next ' 最小値の計算 Dim count As Integer = 0 Dim sw As Integer = -1 Do While count < max and sw < 0 count += 1 ' 重心の計算 For i1 As Integer = 0 To n-1 xg(i1) = 0.0 Next For i1 As Integer = 0 To n If i1 <> fh For i2 As Integer = 0 To n-1 xg(i2) += xx(i1,i2) Next End If Next For i1 As Integer = 0 To n-1 xg(i1) /= n Next ' 最大点の置き換え For i1 As Integer = 0 To n-1 xr(i1) = 2.0 * xg(i1) - xx(fh,i1) Next Dim yr As Double = fn(xr) If yr >= yy(fh) ' 縮小 For i1 As Integer = 0 To n-1 xr(i1) = (1.0 - r1) * xx(fh,i1) + r1 * xr(i1) Next yr = fn(xr) ElseIf yr < (yy(fl)+(r2-1.0)*yy(fh))/r2 ' 拡大 For i1 As Integer = 0 To n-1 xn(i1) = r2 * xr(i1) - (r2 - 1.0) * xx(fh,i1) Next Dim yn As Double = fn(xn) If yn <= yr For i1 As Integer = 0 To n-1 xr(i1) = xn(i1) Next yr = yn End If End If For i1 As Integer = 0 To n-1 xx(fh,i1) = xr(i1) Next yy(fh) = yr ' シンプレックス全体の縮小 If yy(fh) >= yy(fg) For i1 As Integer = 0 To n If i1 <> fl For i2 As Integer = 0 To n-1 xx(i1,i2) = 0.5 * (xx(i1,i2) + xx(fl,i2)) Next Dim xx1(n) As Double For i2 As Integer = 0 To n-1 xx1(i2) = xx(i1,i2) Next yy(i1) = fn(xx1) End If Next End If ' 最大値,最小値の計算 fh = -1 fg = -1 fl = -1 For i1 As Integer = 0 To n If fh < 0 fh = i1 ElseIf yy(i1) > yy(fh) fh = i1 End If If fl < 0 fl = i1 ElseIf yy(i1) < yy(fl) fl = i1 End If Next For i1 As Integer = 0 To n If i1 <> fh If fg < 0 fg = i1 ElseIf yy(i1) > yy(fg) fg = i1 End If End If Next ' 収束判定 Dim e As Double = 0.0 For i1 As Integer = 0 To n If i1 <> fl yr = yy(i1) - yy(fl) e += yr * yr End If Next If e < eps sw = 0 End If Loop If sw = 0 sw = count y = yy(fl) For i1 As Integer = 0 To n-1 x(i1) = xx(fl,i1) Next End If Return sw End Function End Module
情報学部 | 菅沼ホーム | 目次 | 索引 |