Python はさまざまな最適化アルゴリズムを実装します

coldplay.xixi
リリース: 2020-12-02 17:03:58
転載
6006 人が閲覧しました

Python ビデオ チュートリアルこのコラムでは、さまざまな最適化アルゴリズムを紹介します

Python はさまざまな最適化アルゴリズムを実装します

#関連する無料学習の推奨事項: Python ビデオ チュートリアル

二分法メソッド

詳細については、rres を参照してください。このコードにより、アルゴリズムが 2 回実行されます

def asdf(x):
    rres=8*x**3-2*x**2-7*x+3
    return rres

i=2
left=0
right=1
while i>0 :
    i = i-1
    ans = 0.1
    mid1 = (left + right + ans) / 2
    mid2 = (left + right - ans) / 2
    a=asdf(mid1)
    c=asdf(mid2)
    if a > c :
        right = mid1
    else :
        left = mid2
b=(left+right) / 2
print("左极限=%s,右极限=%s,极小值x=%s"%(left,right,b))
ログイン後にコピー
左极限=0.45,右极限=0.775,极小值x=0.6125
ログイン後にコピー
Harvest :

これは私が実装した最初のコードです。アルゴリズムを学習した後は、基本的に論理フレームワークが完成し、明確にする必要があるのは、対応する Python 言語だけです。そこで、「関数の定義方法」(詳細はmofanのYoukuを参照)、「ループ本体」と「if条件文」の形式(https://blog.csdn.net/qq_39407518/article/details/)を探し始めました。 79822498) 「数学記号」 (詳細については mofan の Youku を参照)、および印刷の使用

1.def は Python の中指定義であり、一般に関数を定義するために使用されます。ネットワークを構築する場合、ネットワークを定義するために使用できます。注意すべき点の 1 つは、

return を関数の後の新しい行に追加する必要があることです。

理由はわかりませんが、追加しないと関数式が花瓶のように出力できない結果になってしまいます。

2. 最もわかりにくいのはロジックです。最初はロジックが明確でなかったか、コードに省略があったため、ループ本体に left と right を挿入しましたが、結果は予測可能です。しかし、このエラーのおかげで、pycharm でデバッグを使用する方法を知ることができました。非常に簡単で、Baidu はすぐにそれを思いつきました。

3. 理由はわかりませんが、私が見たビデオで一緒に出力された print 複数の変数は、私の pycharm では使用できず、結果は非常に奇妙なものになります。おそらくそれは私がiOSではなくwin10を使用しているためです。 print 複数の変数をまとめて出力する場合は、print("Name: %s, Name 2: %s" % (a, b)) とする必要があります。結果の出力は、name: a、Name 2: b

となります。質問: 1. なぜリターンを追加するのですか?
return は、この def 内の任意の変数値を結果として出力することを意味します。一般的に、出力関数の関係式は、この関数を呼び出したときに変数に対応する関数の値が表示されるように名前が付けられていますが、それ以外の場合は結果が得られずに実行されるだけで効果はありません。

グリッド法 - 3点等分割法

import numpy as np
def qwer(x):
    third = np.exp(x) - 5*x
    return third

left = 1
right = 2
mid1 =float(left+right) / 2
mid2 = (left+mid1) / 2
mid3 = (mid1+right) /2
a = qwer(mid1)
b = qwer(mid2)
c = qwer(mid3)
i = 5
while i > 0:
    i=i-1
    if a > b:
        if c > b :
            #b
            right = mid1
            mid1 = mid2
            a=b
            mid2 = (left + mid1) / 2
            mid3 = (mid1 + right) / 2
            b = qwer(mid2)
            c = qwer(mid3)
        else:#b>c
            #c
            left = mid1
            mid1 = mid3
            a = c
            mid2 = (left + mid1) / 2
            mid3 = (mid1 + right) / 2
            b = qwer(mid2)
            c = qwer(mid3)
    else:#b>a
            if a > c:
                #C
                left = mid1
                mid1 = mid3
                a = c
                mid2 = (left + mid1) / 2
                mid3 = (mid1 + right) / 2
                b = qwer(mid2)
                c = qwer(mid3)
            else:#b>a&c>a
                # a
                left = mid2
                right = mid3
                mid2 = (left + mid1) / 2
                mid3 = (mid1 + right) / 2
                b = qwer(mid2)
                c = qwer(mid3)

print("最小值=%s"%mid1)
print("函数值=%s"%a)
ログイン後にコピー
最小值=1.609375
函数值=-3.047189552275773
ログイン後にコピー

Pythonのデータ変数について。最初の実行の結果は明らかに間違っていたので、デバッグを使用しました。 Mid1 は 1.5 ではなく常に 1 であることが判明したため、データ変数を理解し始めました。最初は、Python のすべての変数はデフォルトで整数型であると推測しましたが、二分法の結果に基づいて、この推測は間違っていることがわかり、ファイル全体の変数形式を変更する必要はありませんでした。そこで、mid1 の式の前に float を追加したところ、結果は 1.5 と表示されました。しかし、式全体を () で囲み、前に float を追加しても、結果は 1 のままです。理由がよくわかりません。ただし、Python のデータ形式は入力量に基づいて決定されることはわかっています。つまり、入力量が整数の場合、それに直接関係する計算出力は整数型でなければならず、整数型ですキャリーを使わないもの。 float/.0 メソッドを使用する前は、mid1 ~ 3 はすべて整数でした。

left = 1.0
right = 2.0
mid1 =(left+right) / 2
ログイン後にコピー
または、mid1 の前に float を追加する代わりに、入力量の後のドットをクリックするだけです。

印刷に関して本当に文句を言いたいのですが、とても面倒です。毎回 %s を取得しなければなりません。そして、場合によっては組み立てられないこともあります! ! ! !

フィボナッチ法

def fibonacci(n):
    i=0
    a = 0
    b = 1
    for i in range(n):
        i=i+1
        c = a+b
        a = b
        b = c
    return c
def bn(x):
    ert = x**2 - 6*x + 2
    return ert
z = 2
p = 0
left = 0.00000
right = 10.00000
L1 = right - left
while z < 100:
    m = fibonacci(z)
    l = L1/m
    k = 1.000/m
    if k < 0.03:
        print("n=%s,Fn=%s"%(z,m))
        L2 = l*fibonacci(z-1)
        t = left + L2
        r = right -L2
        while p < 3:
            p = p + 1
            l3 = t - r
            e= bn(t)
            o = bn(r)
            if e>o :
                right = t
                t = r
                r = left + l3
            else:#o>e
                left = r
                r = t
                t = right - l3
        break
    else:
        z = z + 1

okk=(left+right)/2
okky=bn(okk)
print(left)
print(right)
print("极小值x=",okk)
print("极小值y=",okky)
ログイン後にコピー

私が何をマスターしたかは聞かないで、このコードを書いた後、Python の精度表現がどれだけ気に入ったか聞いてください:-) 私は単に数式を書くことにしました。今後のコードでは、入力量の小さな数学的ポイントの後に大量の 0

フィボナッチ関数の定義が追加されるため、デバッグ後は毎回手が震えます O(∩_∩)O~

黄金分割方法

def gold(x):
    gg= x**2 - 6*x + 9
    return gg

left = 1
right = 7
ans = 0.4
a = left + 0.618 * (right - left)
b = left + 0.382*(right - left)
gga = gold(a)
ggb = gold(b)
i = 0
while i < 7:
    print("i=%s" % i)
    print("left=%s,right=%s" % (left, right))
    print("x左=%s,x右=%s" % (a, b))
    print("y左=%s,y右=%s" % (ggb, gga))
    c = right - left
    if c > 0.4:
        i = i + 1
        if gga > ggb:
            right = a
            a = b
            b = left + 0.382*(right - left)
            gga = ggb
            ggb = gold(b)
        else:#gga<ggb
            left = b
            b = a
            a = left + 0.618 * (right - left)
            ggb = gga
            gga = gold(a)
    else:
        break
ログイン後にコピー

いつから強迫性障害になったのかわかりませんが、コードの下に「~」がある限り、それを取り除く必要があります。笑って、泣いて。これは非常に単純で、最初の 4 つはフィボナッチを除いてすべて単純です。

間接法 - 2 次補間法

def yy(x):
    y=x**4-4*x**3-6*x**2-16*x+4
    return y

def xing(xm1,xm2,xm3,fm1,fm2,fm3):
    yxxx=0.5000*((xm2**2-xm3**2)*fm1+(xm3**2-xm1**2)*fm2+(xm1**2-xm2**2)*fm3)/((xm2-xm3)*fm1+(xm3-xm1)*fm2+(xm1-xm2)*fm3)
    return yxxx

x1 = -1.0000
f1 = yy(x1)
x3 = 6
f3 = yy(x3)
x2 = 0.50000*(x1+x3)
f2 = yy(x2)
xp = xing(x1,x2,x3,f1,f2,f3)
fp = yy(xp)
a = abs(xp-x2)
while abs(xp-x2) > 0.05000:
    a = abs(xp - x2)
    if xp > x2:
        if fp > f2:
            x3=xp
            f3=fp
            xp = xing(x1, x2, x3, f1, f2, f3)
            fp = yy(xp)
            print("ans=%s" % a)
            print("left=%s,right=%s" % (x1, x3))
            print("x*=%s,fp*=%s" % (xp, fp))
            print("x2=%s,f2=%s" % (x2, f2))
            print("******************")
        else:#f2>fp
            x1 = x2
            f1 = f2
            x2 = xp
            f2 = fp
            xp = xing(x1, x2, x3, f1, f2, f3)
            fp = yy(xp)
            print("ans=%s" % a)
            print("left=%s,right=%s" % (x1, x3))
            print("x*=%s,fp*=%s" % (xp, fp))
            print("x2=%s,f2=%s" % (x2, f2))
            print("******************")
    else:#xp<x2
        if fp > f2:
            x1 = xp
            f1 = fp
            xp = xing(x1, x2, x3, f1, f2, f3)
            fp = yy(xp)
            print("ans=%s" % a)
            print("left=%s,right=%s" % (x1, x3))
            print("x*=%s,fp*=%s" % (xp, fp))
            print("x2=%s,f2=%s" % (x2, f2))
            print("******************")
        else:
            x3 = x2
            f3 = f2
            x2 = xp
            f2 = fp
            xp = xing(x1, x2, x3, f1, f2, f3)
            fp = yy(xp)
            print("ans=%s" % a)
            print("left=%s,right=%s" % (x1, x3))
            print("x*=%s,fp*=%s" % (xp, fp))
            print("x2=%s,f2=%s" % (x2, f2))
            print("******************")
ログイン後にコピー
この式は非常に面倒そうなので、書くときは注意が必要です。前回、セミコロンの下に 2 を入れたところ、結果が非​​常に大きくなったので、0.5 に変換した方がよいでしょう (追記: 0 という長い川を忘れないでください)。

コードは非常に長いですが、主な原因は出力が多すぎるためです。最初に印刷するつもりだったのですが、最後の部分が抜けてしまいます。他の方法を考えるのが面倒なので、このままにしておきます。

間接法 - ニュートン法

def fd(x):
    y = 4*x**3-12*x**2-12*x-16
    return y
def fdd(x):
    ys = 12*x**2-24*x-12
    return ys

i = 1
x0 = 3.00000
ans = 0.001
while i < 7:
    fd0 = fd(x0)
    fdd0 = fdd(x0)
    if abs(fd0) > ans:
        x1 = x0 - (fd0/fdd0)
        x0 = x1
        print("次数:%s,所得的值x:%s"%(i,x1))
        i = i + 1
    else:#fd0<0.001
        print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
        print("Bingo!顺利通关!祝您开学愉快!")
        print("Boss  X=%s"%x0)
        break
ログイン後にコピー

最初、while で「次のように記述」すると実行が失敗しました。この場合、デバッグは使用できません。ネットで調べたところ、「インターネット接続なし」「ブレークポイントが選択されていません」ということが分かりました。最後にelseで内容を出力してみようと思ったのですが、実行後に画面が更新されてしまいました。そこで、i<7 に変更してもやはり動作しなかったので、ループから抜け出すためにブレークを追加しようと考えたところ、動作しました。

それでデバッグしたところ、i 1 が if にあることがわかりました。1 に到達する方法がないため、常に i=6 が存在し、ループし続けます。 Breakでもi1でも付けても問題ないのでOKです。

ちょうど 1 時間半前、私は 6 つの主要なコードの最適化を、外部の力を一切使わずにすべて手作業で完了しました。嬉しいです!

これは、私が自分で実装した最初の Python コードのセットであり、Python 言語で組み立てられた数式です。始めた当初は、言語に何を反映する必要があるかはおおよそわかっていましたが、明確ではありませんでした。そこでインターネットでいくつかの二分法を探しました。それらはすべて異なりますが、枠組みは似ています。しかし、私たちの公式を使用したい場合は、多くの変更が必要です。それから問題を分析し始めたところ、通常、関数定義とループ本体の 2 つの部分が必要であることがわかりました。でも、関数の定義の仕方も、数式の書き方も、変数の作り方も分からない、つまり細かいことのやり方も分からないので、直接Baiduに行くことにしました。なぜなら、私は自分が優れた読書家であることを知っており、ビデオから重要なポイントを抽出するよりも、読書から重要なポイントを理解する方が得意だからです。目的を持って知識ポイントを見つけて、よりしっかりと把握しましょう。
そこで私は最初の二項対立を書き始めました。たくさんの間違いを犯しており、その多くは非常に基本的なものであったことがわかりました。しかし、私はまだビデオを選択せず​​、ビデオの後では要点が見つからない可能性があるため、代わりに Baidu でこれらの質問を直接探しました。もちろん、これは段階的なプロセスであり、単にプログラムを導入して少しずつ変更するだけではありません。
最初の 2 つの成功により、私はこれらのコードに自信を持っていることがわかり、その偽装を見破って本質を把握できたようです。また、8月以降、私の学習能力はかなり向上しており、より効果的な学習方法があることにも気づきました。あらゆる面で確かな目覚めがありました。最初にいくつか間違ったコードを見つけた以外は、すべて自分のロジックに従って書いたもので、ロジックを理解した後、言語の特定の部分を翻訳する方法が分からない場合は、そのまま翻訳してしまいます。実際、これらのルーチンはすべて同じであるか、数式を変換するルーチンは同じです。
また、アセンブリが実際には最も難しい言語であることにも気づきました。これまでに学んだことは、アセンブリの多くは自分で定義して理解する必要があるためです。多くの命令を覚えておく必要があり、柔軟性がありません。ただし、その他の場合は、対応するものをいくつか書き留めるだけで済みます。 Pythonは本当にシンプルです。そして今日、私は新しい世界の扉を開いたような気がしました精神性に満ち、厳格な美しさに満ち、未知の変化に満ちたこのものに恋をしてしまいました。コード付き。 Pythonに限らず、これらの言語は課題がたくさんあります。迷ったときは自分の直感を信じる必要があると思います。少なくとも私はそれが非常に正確であると感じました

以上がPython はさまざまな最適化アルゴリズムを実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:jianshu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート