# -*- 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))