# -*- coding: UTF-8 -*- from math import * import numpy as np ############################################ # シンプレックス法 # 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 ---------------------------------- # -*- coding: UTF-8 -*- import numpy as np import sys from math import * from function import simplex ############################################ # シンプレックス法による最小値の計算 # 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))