2010/05/22

region elimination methods

Exercise 1: Use region elimination methods to estimate the two minima and one maximum of the function
                            f(x)=10x^6 -72x^5 +165x^4 -120x^3 +72
with the estimation error less than 0.01,where x is defined the real line.



這個其實是最佳化作業一,當時還在學 Python ,所以就順手用 Python 做作業了。
就把它貼在這邊吧,不然這邊好久沒有新東西了,我都在做作業...
其實還蠻想貼類神經的作業呢 ... BPNN, LVQ, CPN, SOM, ART, ...
不過這些是分組作業的,所以得尊重趴呢,(時間都耗在這上面阿...)

廢話不多說了,直接來貼 code

#-*- coding:UTF-8 -*-

def f(x):
    return 10*x**6 - 72*x**5 + 165*x**4 -120*x**3 + 72

global result #儲存最大最小值
result = []

def findminInterval(x0,d):
    x = [] # 儲存全部的x值
    x.append(x0) #x0
    d = d #step-size
    n = 0
    global x_down #需要找的下界
    global x_up   #需要找的上界
    t = [f(x[0]-d), f(x[0]), f(x[0]+d)] #儲存f(x0)的值
    print "x%d = %d" %(n,x[0])
    print "d = ", d
    print "f(x%d - d) = %f" %(n, t[0])
    print "f(x%d) = %f" %(n, t[1])
    print "f(x%d + d) = %f" %(n, t[2])
    #判斷一開始的大小
    if t[0] == max(t) and t[2] == min(t):
        print "f(x%d - d) >= f(x%d) >= f(x%d + d)" %(n,n,n)
        state = True
        while state:
            beforevalue = f(x[n])
            x.append(x[n] + d*(2**n))
            n = n + 1
            print "x%d = %f" %(n,x[n])
            nowvalue = f(x[n])
            if nowvalue < beforevalue:
                print "f(%f) = %f < f(x%d)" %(x[n],nowvalue,n-1)
            else:
                print "f(%f) = %f > f(x%d)" %(x[n],nowvalue,n-1)
                print "x = ", x
                if len(x) > 2:
                    x_down = x[n-2]
                    x_up = x[n]
                else:
                    x_down = x[0]-d
                    x_up = x[0]+d
                state = False #找到最小值所在之區間,跳出迴圈
    elif t[0] == min(t) and t[2] == max(t):
        print "f(x%d - d) <= f(x%d) <= f(x%d + d)" %(n,n,n)
        state = True
        while state:
            beforevalue = f(x[n])
            x.append((x[n] - d*(2**n)))
            n = n + 1
            print "x%d = %f" %(n,x[n])
            nowvalue = f(x[n])
            if nowvalue < beforevalue:
                print "f(%f) = %f < f(x%d)" %(x[n],nowvalue,n-1)
            else:
                print "f(%f) = %f > f(x%d)" %(x[n],nowvalue,n-1)
                print "x = ", x
                if len(x) > 2:
                    x_down = x[n]
                    x_up = x[n-2]
                else:
                    x_down = x[0]-d
                    x_up = x[0]+d
                state = False #找到最小值所在之區間,跳出迴圈
    elif t[1] == min(t):
        print "f(x%d - d) >= f(x%d) <= f(x%d + d)" %(n,n,n)
        print "x%d = %f" %(n,x[n])
        x_down = x[0] - d
        x_up = x[0] + d
    elif t[1] == max(t):
        print "f(x%d - d) <= f(x%d) >= f(x%d + d)" %(n,n,n)
        print "x%d = %f" %(n,x[n])
        print "It must have maximum in the interval!"
        x_down = x[0] - d
        x_up = x[0] + d
    else:
        print "It may have some problem!!!"
    print "%f <= x* <= %f" %(x_down,x_up)

def findmaxInterval(x0,d):
    x = [] # 儲存全部的x值
    x.append(x0) #x0
    d = d #step-size
    n = 0
    global x_down #需要找的下界
    global x_up   #需要找的上界
    t = [f(x[0]-d), f(x[0]), f(x[0]+d)] #儲存f(x0)的值
    print "x%d = %f" %(n,x[0])
    print "d = ", d
    print "f(x%d - d) = %f" %(n, t[0])
    print "f(x%d) = %f" %(n, t[1])
    print "f(x%d + d) = %f" %(n, t[2])
    #判斷一開始的大小
    if t[0] == max(t) and t[2] == min(t):
        print "f(x%d - d) >= f(x%d) >= f(x%d + d)" %(n,n,n)
        state = True
        while state:
            beforevalue = f(x[n])
            x.append(x[n] - d*(2**n))
            n = n + 1
            print "x%d = %f" %(n,x[n])
            nowvalue = f(x[n])
            if nowvalue > beforevalue:
                print "f(%f) = %f > f(x%d)" %(x[n],nowvalue,n-1)
            else:
                print "f(%f) = %f < f(x%d)" %(x[n],nowvalue,n-1)
                print "x = ", x
                if len(x) > 2:
                    x_down = x[n]
                    x_up = x[n-2]
                else:
                    x_down = x[0]-d
                    x_up = x[0]+d
                state = False #找到最大值所在之區間,跳出迴圈
    elif t[0] == min(t) and t[2] == max(t):
        print "f(x%d - d) <= f(x%d) <= f(x%d + d)" %(n,n,n)
        state = True
        while state:
            beforevalue = f(x[n])
            x.append((x[n] + d*(2**n)))
            n = n + 1
            print "x%d = %f" %(n,x[n])
            nowvalue = f(x[n])
            if nowvalue > beforevalue:
                print "f(%f) = %f > f(x%d)" %(x[n],nowvalue,n-1)
            else:
                print "f(%f) = %f < f(x%d)" %(x[n],nowvalue,n-1)
                print "x = ", x
                if len(x) > 2:
                    x_down = x[n-2]
                    x_up = x[n]
                else:
                    x_down = x[0]-d
                    x_up = x[0]+d
                state = False #找到最大值所在之區間,跳出迴圈
    elif t[1] == min(t):
        print "f(x%d - d) >= f(x%d) <= f(x%d + d)" %(n,n,n)
        print "x%d = %f" %(n,x[n])
        print "It must have minima value!!"
        x_down = x[0] - d
        x_up = x[0] + d
    elif t[1] == max(t):
        print "f(x%d - d) <= f(x%d) >= f(x%d + d)" %(n,n,n)
        print "x%d = %f" %(n,x[n])
        x_down = x[0] - d
        x_up = x[0] + d
    else:
        print "It may have some problem!!!"
    print "%f <= x* <= %f" %(x_down,x_up)


def findmin(xdown, xup):
    a = xdown  # 下界
    b = xup # 上界
    global xm
    state = True
    while state:
        L = b - a
        xm = (a + b)*0.5
        x1 = a + 0.25*L
        x2 = b - 0.25*L
        print "*"*50
        print "a = %f" %a
        print "b = %f" %b
        print "L = %f" %L
        print "xm = %f" %xm
        print "x1 = %f" %x1
        print "x2 = %f" %x2
        t = [f(xm), f(x1), f(x2)] #暫存計算結果
        if t[1] > t[0] and t[2] > t[0]:
            print "f(%f) = %f > f(%f) = %f" %(x1, t[1], xm, t[0])
            print "f(%f) = %f > f(%f) = %f" %(x2, t[2], xm, t[0])
            a = x1
            b = x2
        elif t[1] < t[0] and t[2] > t[0]:
            print "f(%f) = %f < f(%f) = %f" %(x1, t[1], xm, t[0])
            print "f(%f) = %f > f(%f) = %f" %(x2, t[2], xm, t[0])
            b = xm
        elif t[1] > t[0] and t[2] < t[0]:
            print "f(%f) = %f > f(%f) = %f" %(x1, t[1], xm, t[0])
            print "f(%f) = %f < f(%f) = %f" %(x2, t[2], xm, t[0])
            a = xm
        else:
            print "f(%f) = %f <= f(%f) = %f" %(x1, t[1], xm, t[0])
            print "f(%f) = %f <= f(%f) = %f" %(x2, t[2], xm, t[0])
            print "You must try to find the maximum."
            state = False
        if b - a < 0.01:
            print "The minima must be %f" %xm
            result.append("The minima must be %f" %xm) #將最小值結果加入結果串中
            state = False

def findmax(xdown, xup):
    a = xdown  # 下界
    b = xup # 上界
    global xm
    state = True
    while state:
        L = b - a
        xm = (a + b)*0.5
        x1 = a + 0.25*L
        x2 = b - 0.25*L
        print "*"*50
        print "a = %f" %a
        print "b = %f" %b
        print "L = %f" %L
        print "xm = %f" %xm
        print "x1 = %f" %x1
        print "x2 = %f" %x2
        t = [f(xm), f(x1), f(x2)] #暫存計算結果
        if t[1] < t[0] and t[2] < t[0]:
            print "f(%f) = %f < f(%f) = %f" %(x1, t[1], xm, t[0])
            print "f(%f) = %f < f(%f) = %f" %(x2, t[2], xm, t[0])
            a = x1
            b = x2
        elif t[1] < t[0] and t[2] > t[0]:
            print "f(%f) = %f < f(%f) = %f" %(x1, t[1], xm, t[0])
            print "f(%f) = %f > f(%f) = %f" %(x2, t[2], xm, t[0])
            a = xm
        elif t[1] > t[0] and t[2] < t[0]:
            print "f(%f) = %f > f(%f) = %f" %(x1, t[1], xm, t[0])
            print "f(%f) = %f < f(%f) = %f" %(x2, t[2], xm, t[0])
            b = xm
        else:
            print "f(%f) = %f >= f(%f) = %f" %(x1, t[1], xm, t[0])
            print "f(%f) = %f >= f(%f) = %f" %(x2, t[2], xm, t[0])
            print "You must try to find the minima."
            state = False
        if b - a < 0.01:
            print "The maximum must be %f" %xm
            result.append("The maximum must be %f" %xm) #將最大值結果加入結果串中
            state = False


def main():
    findminInterval(0,0.001)
    findmin(x_down, x_up)
    state = True
    while state:
        try:
            findmaxInterval(xm+0.1,0.001)
            findmax(x_down, x_up)
            findminInterval(xm+0.1,0.001)
            findmin(x_down, x_up)
        except OverflowError:
            print "It may have no other max or min interval."
            state = False
    print "*"*50
    #print result
    print "Use region elimination methods to estimate the two minima and one maximum of the function"
    print "f(x)=10x^6-72x^5+165x^4-120x^3+72"
    print "with the estimation error less than 0.01, where x is defined on the real line."
    print
    print "The result is:"
    n = 0
    while n < len(result):
        print result[n]
        n = n + 1
    print "*"*50

if __name__ == "__main__":
    main()
    raw_input("Please for closing this window.")



這東西我就不解釋了,實在不是很好解釋...

沒有留言:

張貼留言