欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Python共軛梯度法與最速下降法之間的對比

 更新時間:2020年04月02日 16:54:13   作者:像在吹  
這篇文章主要介紹了基于Python共軛梯度法與最速下降法之間的對比,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

在一般問題的優(yōu)化中,最速下降法和共軛梯度法都是非常有用的經(jīng)典方法,但最速下降法往往以”之”字形下降,速度較慢,不能很快的達到最優(yōu)值,共軛梯度法則優(yōu)于最速下降法,在前面的某個文章中,我們給出了牛頓法和最速下降法的比較,牛頓法需要初值點在最優(yōu)點附近,條件較為苛刻。

算法來源:《數(shù)值最優(yōu)化方法》高立,P111

我們選用了64維的二次函數(shù)來作為驗證函數(shù),具體參見上書111頁。

采用的三種方法為:

共軛梯度方法(FR格式)、共軛梯度法(PRP格式)、最速下降法

# -*- coding: utf-8 -*-
"""
Created on Sat Oct 01 15:01:54 2016
@author: zhangweiguo
"""
import sympy,numpy
import math
import matplotlib.pyplot as pl
from mpl_toolkits.mplot3d import Axes3D as ax3
import SD#這個文件里有最速下降法SD的方法,參見前面的博客
#共軛梯度法FR、PRP兩種格式
def CG_FR(x0,N,E,f,f_d):
  X=x0;Y=[];Y_d=[];
  n = 1
  ee = f_d(x0)
  e=(ee[0]**2+ee[1]**2)**0.5
  d=-f_d(x0)
  Y.append(f(x0)[0,0]);Y_d.append(e)
  a=sympy.Symbol('a',real=True)
  print '第%2s次迭代:e=%f' % (n, e)
  while n<N and e>E:
    n=n+1
    g1=f_d(x0)
    f1=f(x0+a*f_d(x0))
    a0=sympy.solve(sympy.diff(f1[0,0],a,1))
    x0=x0-d*a0
    X=numpy.c_[X,x0];Y.append(f(x0)[0,0])
    ee = f_d(x0)
    e = math.pow(math.pow(ee[0,0],2)+math.pow(ee[1,0],2),0.5)
    Y_d.append(e)
    g2=f_d(x0)
    beta=(numpy.dot(g2.T,g2))/numpy.dot(g1.T,g1)
    d=-f_d(x0)+beta*d
    print '第%2s次迭代:e=%f'%(n,e)
  return X,Y,Y_d
def CG_PRP(x0,N,E,f,f_d):
  X=x0;Y=[];Y_d=[];
  n = 1
  ee = f_d(x0)
  e=(ee[0]**2+ee[1]**2)**0.5
  d=-f_d(x0)
  Y.append(f(x0)[0,0]);Y_d.append(e)
  a=sympy.Symbol('a',real=True)
  print '第%2s次迭代:e=%f' % (n, e)
  while n<N and e>E:
    n=n+1
    g1=f_d(x0)
    f1=f(x0+a*f_d(x0))
    a0=sympy.solve(sympy.diff(f1[0,0],a,1))
    x0=x0-d*a0
    X=numpy.c_[X,x0];Y.append(f(x0)[0,0])
    ee = f_d(x0)
    e = math.pow(math.pow(ee[0,0],2)+math.pow(ee[1,0],2),0.5)
    Y_d.append(e)
    g2=f_d(x0)
    beta=(numpy.dot(g2.T,g2-g1))/numpy.dot(g1.T,g1)
    d=-f_d(x0)+beta*d
    print '第%2s次迭代:e=%f'%(n,e)
  return X,Y,Y_d
if __name__=='__main__':
  '''
  G=numpy.array([[21.0,4.0],[4.0,15.0]])
  #G=numpy.array([[21.0,4.0],[4.0,1.0]])
  b=numpy.array([[2.0],[3.0]])
  c=10.0
  x0=numpy.array([[-10.0],[100.0]])
  '''
  
  m=4
  T=6*numpy.eye(m)
  T[0,1]=-1;T[m-1,m-2]=-1
  for i in xrange(1,m-1):
    T[i,i+1]=-1
    T[i,i-1]=-1
  W=numpy.zeros((m**2,m**2))
  W[0:m,0:m]=T
  W[m**2-m:m**2,m**2-m:m**2]=T
  W[0:m,m:2*m]=-numpy.eye(m)
  W[m**2-m:m**2,m**2-2*m:m**2-m]=-numpy.eye(m)
  for i in xrange(1,m-1):
    W[i*m:(i+1)*m,i*m:(i+1)*m]=T
    W[i*m:(i+1)*m,i*m+m:(i+1)*m+m]=-numpy.eye(m)
    W[i*m:(i+1)*m,i*m-m:(i+1)*m-m]=-numpy.eye(m)
  mm=m**2
  mmm=m**3
  G=numpy.zeros((mmm,mmm))
  G[0:mm,0:mm]=W;G[mmm-mm:mmm,mmm-mm:mmm]=W;
  G[0:mm,mm:2*mm]=-numpy.eye(mm)
  G[mmm-mm:mmm,mmm-2*mm:mmm-mm]=-numpy.eye(mm)
  for i in xrange(1,m-1):
    G[i*mm:(i+1)*mm,i*mm:(i+1)*mm]=W
    G[i*mm:(i+1)*mm,i*mm-mm:(i+1)*mm-mm]=-numpy.eye(mm)
    G[i*mm:(i+1)*mm,i*mm+mm:(i+1)*mm+mm]=-numpy.eye(mm)
  x_goal=numpy.ones((mmm,1))
  b=-numpy.dot(G,x_goal)
  c=0
  f = lambda x: 0.5 * (numpy.dot(numpy.dot(x.T, G), x)) + numpy.dot(b.T, x) + c
  f_d = lambda x: numpy.dot(G, x) + b
  x0=x_goal+numpy.random.rand(mmm,1)*100
  N=100
  E=10**(-6)
  print '共軛梯度PR'
  X1, Y1, Y_d1=CG_FR(x0,N,E,f,f_d)
  print '共軛梯度PBR'
  X2, Y2, Y_d2=CG_PRP(x0,N,E,f,f_d)
  figure1=pl.figure('trend')
  n1=len(Y1)
  n2=len(Y2)
  x1=numpy.arange(1,n1+1)
  x2=numpy.arange(1,n2+1)
  
  X3, Y3, Y_d3=SD.SD(x0,N,E,f,f_d)
  n3=len(Y3)
  x3=range(1,n3+1)
  pl.semilogy(x3,Y3,'g*',markersize=10,label='SD:'+str(n3))
  pl.semilogy(x1,Y1,'r*',markersize=10,label='CG-FR:'+str(n1))
  pl.semilogy(x2,Y2,'b*',markersize=10,label='CG-PRP:'+str(n2))
  pl.legend()
  #圖像顯示了三種不同的方法各自迭代的次數(shù)與最優(yōu)值變化情況,共軛梯度方法是明顯優(yōu)于最速下降法的
  pl.xlabel('n')
  pl.ylabel('f(x)')
  pl.show()

最優(yōu)值變化趨勢:

從圖中可以看出,最速下降法SD的迭代次數(shù)是最多的,在與共軛梯度(FR與PRP兩種方法)的比較中,明顯較差。

補充知識:python實現(xiàn)牛頓迭代法和二分法求平方根,精確到小數(shù)點后無限多位-4

首先來看一下牛頓迭代法求平方根的過程:計算3的平方根

如圖,是求根號3的牛頓迭代法過程。這里使用的初始迭代值(也就是猜測值)為1,其實可以為任何值最終都能得到結(jié)果。每次開始,先檢測猜測值是否合理,不合理時,用上面的平均值來換掉猜測值,依次繼續(xù)迭代,直到猜測值合理。

原理:現(xiàn)在取一個猜測值 a, 如果猜測值合理的話,那么就有a^2=x,即x/a=a ,x為被開方數(shù)。不合理的話呢,就用表中的猜測值和商的平均值來換掉猜測值。當(dāng)不合理時,比如 a>真實值,那么x/a<真實值,這時候取a 與 x/a 的平均值來代替a的話,那么新的a就會比原來的a要更接近真實值。同理有 a<真實值 的情況。于是,這樣不斷迭代下去最終是一個a不斷收斂到真實值的一個過程。于是不斷迭代就能得到真實值,證明了迭代法是正確的。

附上我的python代碼:

利用python整數(shù)運算,python整數(shù)可以無限大,可以實現(xiàn)小數(shù)點后無限多位

#二分法求x的平方根小數(shù)點下任意K位數(shù)的精準(zhǔn)值,利用整數(shù)運算 #思想:利用二分法,每次乘以10,取中間值,比較大小,從而定位精確值的范圍,將根擴大10倍,則被開方數(shù)擴大100倍。 #quotient(商)牛頓迭代法:先猜測一個值,再求商,然后用猜測值和商的中間值代替猜測值,擴大倍數(shù),繼續(xù)進行。

 
 
import math
from math import sqrt
 
def check_precision(l,h,p,len1):#檢查是否達到了精確位
  l=str(l);h=str(h)
  if len(l)<=len1+p or len(h)<=len1+p:
    return False
  for i in range(len1,p+len1):#檢查小數(shù)點后面的p個數(shù)是否相等
    if l[i]!=h[i]:     #當(dāng)l和h某一位不相等時,說明沒有達到精確位
      return False
  return True
 
def print_result(x,len1,p):
  x=str(x)
  if len(x)-len1<p:#沒有達到要求的精度就已經(jīng)找出根
    s=x[:len1]+"."+x[len1:]+'0'*(p-len(x)+len1)
  else:s=x[:len1]+"."+x[len1:len1+p]
  print(s)
 
def binary_sqrt(x,p):
  x0=int(sqrt(x))
  if x0*x0==x: #完全平方數(shù)直接開方,不用繼續(xù)進行
    print_result(x0,len(str(x0)),p)
    return 
  len1=len(str(x0))#找出整數(shù)部分的長度
  l=0;h=x
  while(not check_precision(l,h,p,len1)):#沒有達到精確位,繼續(xù)循環(huán)
    if not l==0:#第一次l=0,h=x時不用乘以10,直接取中間值
      h=h*10 #l,h每次擴大10倍
      l=l*10
      x=x*100 #x每次要擴大100倍,因為平方
    m=(l+h)//2
    if m*m==x:
      return print_result(m,len1,p)
    elif m*m>x:
      h=m
    else:
      l=m
  return print_result(l,len1,p)#當(dāng)達到了要求的精度,直接返回l
 
#牛頓迭代法求平方根
def newton_sqrt(x,p):
  x0=int(sqrt(x))
  if x0*x0==x: #完全平方數(shù)直接開方,不用繼續(xù)進行
    print_result(x0,len(str(x0)),p)
    return
  len1=len(str(x0))#找出整數(shù)部分的長度
  g=1;q=x//g;g=(g+q)//2
  while(not check_precision(g,q,p,len1)):
    x=x*100
    g=g*10
    q=x//g   #求商
    g=(g+q)//2 #更新猜測值為猜測值和商的中間值
  return print_result(g,len1,p)
 
while True:  
  x=int(input("請輸入待開方數(shù):"))
  p=int(input("請輸入精度:"))
  print("binary_sqrt:",end="")
  binary_sqrt(x,p)
  print("newton_sqrt:",end="")
  newton_sqrt(x,p)

以上這篇基于Python共軛梯度法與最速下降法之間的對比就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • python爬蟲之你好,李煥英電影票房數(shù)據(jù)分析

    python爬蟲之你好,李煥英電影票房數(shù)據(jù)分析

    這篇文章主要介紹了python爬蟲之你好,李煥英電影票房數(shù)據(jù)分析,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)python爬蟲的小伙伴們有一定的幫助,需要的朋友可以參考下
    2021-04-04
  • python3 http提交json參數(shù)并獲取返回值的方法

    python3 http提交json參數(shù)并獲取返回值的方法

    今天小編就為大家分享一篇python3 http提交json參數(shù)并獲取返回值的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • PyQt信號和槽機制的具體使用

    PyQt信號和槽機制的具體使用

    信號和槽機制是一種通信機制,在PyQt中,信號是一種特殊的函數(shù),它可以傳遞任何類型的數(shù)據(jù),而槽則是一種接收信號的函數(shù),本文就介紹了PyQt信號和槽機制的具體使用,感興趣的可以了解一下
    2023-08-08
  • 簡單談?wù)刾ython中的語句和語法

    簡單談?wù)刾ython中的語句和語法

    下面小編就為大家?guī)硪黄唵握務(wù)刾ython中的語句和語法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 使用Python制作讀單詞視頻的實現(xiàn)代碼

    使用Python制作讀單詞視頻的實現(xiàn)代碼

    我們經(jīng)常在B站或其他視頻網(wǎng)站上看到那種逐條讀單詞的視頻,但他們的視頻多多少少和我們的預(yù)期都不太一致,然而,網(wǎng)上很難找到和自己需求符合的視頻,所以本文給大家介紹了使用Python制作讀單詞視頻的實現(xiàn),需要的朋友可以參考下
    2024-04-04
  • python如何實現(xiàn)DES加密

    python如何實現(xiàn)DES加密

    這篇文章主要介紹了python如何實現(xiàn)DES加密,幫助大家更好的理解和學(xué)習(xí)密碼學(xué),感興趣的朋友可以了解下
    2020-09-09
  • Python中刪除文件的程序代碼

    Python中刪除文件的程序代碼

    很多軟件在運行時會自動創(chuàng)建一些備份文件,在程序退出后又不自動刪除備份文件,隨著文件數(shù)量的增加,每隔一段時間就要清理一下。
    2011-03-03
  • 解決python opencv無法顯示圖片的問題

    解決python opencv無法顯示圖片的問題

    今天小編就為大家分享一篇解決python opencv無法顯示圖片的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • 基于Django的樂觀鎖與悲觀鎖解決訂單并發(fā)問題詳解

    基于Django的樂觀鎖與悲觀鎖解決訂單并發(fā)問題詳解

    這篇文章主要介紹了基于Django的樂觀鎖與悲觀鎖解決訂單并發(fā)問題詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • Python實現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之鏈表詳解

    Python實現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之鏈表詳解

    這篇文章主要介紹了Python實現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之鏈表,詳細(xì)分析了鏈表的概念、定義及Python實現(xiàn)與使用鏈表的相關(guān)技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04

最新評論