拉格朗日插值法入門


什么是插值

在離散數據的基礎上補插連續的函數,使得這條連續函數經過所有離散數據點,這個過程就叫插值。

其意義在於:

插值是離散函數逼近的重要方法,利用它可通過函數在有限個點處的取值狀況,估算出函數在其他點處的近似值。

你猜對了,以上均來自百度百科的 “ 插值 ” 詞條。

怎么理解這個東西呢?舉個例子,操場上有人在踢足球。球員一腳把球踢飛了,假設球始終在一個平面上運行,它的軌跡就可以抽象為一個函數\(f(t)\)(假設它只與與時間相關)。

現在,你借來了一台高速攝像機,拍下了很多張片照片,那么一張照片實際上就是得到了函數圖像上的一個點 \((t_i,f(t_i))\)

插值就相當於,你知道了一些照片(離散的數據),想要還原出球的運動軌跡 \(f(t)\)。當然,由於你只可能有有限的照片,而函數是連續的,那么你只能去近似地還原函數。這也意味之,插值的結果 \(g(t)\)總是無窮多的。

插值有許多方法,包括:三角函數插值;線性插值法;牛頓插值法;拉格朗日插值法......

下面請出今天的主角——拉格朗日...插值法!拍肚皮拍肚皮拍肚皮......

拉格朗日插值法

拉格朗日插值法 ( Lagrange Interpolation Polynomial ) 是以十八世紀數學家約瑟夫·拉格朗日 ( Joseph-Louis Lagrange ) 命名的插值法,它可以根據已有離散數據得出多項式的差值結果

它的思想非常簡單,大概可以理解為——硬性配湊!

怎么配湊呢?我們舉個例子,平面上有三個點, \((x_1,y_1),(x_2,y_2),(x_3,y_3)(x_1<x_2<x_3)\),我們現在用它們仨插值。

threepoints

根據小學基礎知識,我們知道,這三個點肯定可以唯一確定一個二次函數。

那么我們就嘗試找到它,怎么找?拉格朗日想到了一個比較粗暴的方法——咱對於每個點都搞一個子函數 \(f_i(x)\),要求 \(f_i(x)\)\(x=x_i\) 的時候得到 \(1\),在 \(x=x_j(j\not=i)\) 的時候得到 \(0\),把 \(n\) 個子函數湊起來,得到的函數不就過了 \(n\) 個點了!

也就是說,我們要計算 \(n\) 個子函數,第 \(i\) 個子函數為:

\[f_i(x)= \begin{cases} 1 & x=x_i\\ 0 & x=x_j(j\not=i)\\ I\ don't\ care & otherwise \end{cases} \]

那么插值的結果就是:

\[f(x)=\sum_{i=1}^n y_if_i(x) \]

回到原問題上面來。考慮構造 \(f_1(x)\),對於 \(f_1(x_j)=0(j>1)\) 的情況很好滿足,可以想到:

\[f_1(x)=(x-x_2)(x-x_3) \]

怎么讓 \(f_1(x_1)=1\) 呢?我們只需要把不用的丟掉就好:

\[f_1(x)=\frac{(x-x_2)(x-x_3)}{(x_1-x_2)(x_1-x_3)} \]

所以最后就有 \(f_1(x_1)\) 長成下面這個亞子:

f1

同理構造出 \(f_2(x)\)

f2

\(f_3(x)\)

f3

求和得到\(f(x)\)

\[f(x)=\frac{y_1(x-x_2)(x-x_3)}{(x_1-x_2)(x_1-x_3)}+\frac{y_2(x-x_1)(x-x_3)}{(x_2-x_1)(x_2-x_3)}+\frac{y_3(x-x_1)(x-x_2)}{(x_3-x_1)(x_3-x_2)} \]

mergeed

也可以很方便地推廣到一般形式:對於\(n\)個點\((x_1,y_1),(x_2,y_2),...,(x_n,y_n)(x_1<x_2<...<x_n)\),設:

\[f_i(x)=\frac{\prod_{j\not=i}(x-x_j)}{\prod_{j\not=i}(x_i-x_j)} \]

那么插值結果就是:

\[f(x)=\sum_{i=1}^ny_if_i(x)=\sum_{i=1}^ny_i\times \frac{\prod_{j\not=i}(x-x_j)}{\prod_{j\not=i}(x_i-x_j)} \]

模板LGP4781

for( int i = 1 ; i <= N ; i ++ )
{
	fi = 1;
	for( int j = 1 ; j <= N ; j ++ )
		if( i ^ j )
			fi = 1ll * fi * fix( k - x[j] ) % mod * inv( fix( x[i] - x[j] ) ) % mod;
	ans = ( ans + 1ll * fi * y[i] % mod ) % mod;
}

拉格朗日插值法的應用

多項式插值

拉格朗日插值法可以直接用於離散數據的多項式插值,普通方法的時間復雜度是 \(O(n^2)\),經過多項式膜法優化之后可以達到 \(O(n\log_2^2n)\)(沒錯,多項式快速插值就是從拉格朗日插值法優化來的)。

其實,如果不知道拉格朗日插值法,也可以使用一般方法進行多項式插值——直接上待定系數法,用高斯消元解方程組就可以。但是拉格朗日方法顯然優點明顯:

  1. 快,快,快得多。高斯消元 \(O(n^3)\),拉格朗日只有 \(O(n^2)\),還可以優化至 \(O(n\log_2^2n)\)

2.拉格朗日插值法支持取模,而高斯消元法......

3.還有很多優點,我這里就不一一列舉了

不過,在實際應用中,拉格朗日插值法也存在一些缺點。比如說,如果離散數據是變化的,時不時就會多一個點或者少一個點,那么每次變化,拉格朗日插值法都需要重新計算一遍每一個子函數,導致效率非常非常低下。這個時候可以考慮采用易於處理這種情況的牛頓插值法或者拉格朗日插值法的改進版。

再比如,拉格朗日插值法的結果的次數與插值點數成正比。這就意味着,插值點多幾個,拉格朗日插值法在非插值點的位置,就有可能會顯出很大的偏差。(具體可以參考龍格現象

DP 優化

這兩個東西怎么會有關系呢?嗯?

它們確實有關系......

在一類計數 DP 中,如果判定 DP 可以被表示為關於狀態內某個變量的多項式函數,那么我們就可以利用小范圍的點值,插值得到函數,再代入題目所需的數據求解。

這種方法通常要求小范圍的點值可以在時間限制內快速計算,但最關鍵的還是,要找出“ DP 為變量的多項式函數”這一性質,並且准確地猜測估計計算出函數的次數

該方法的主要意義還是在於縮減數據范圍,當規模小到可以直接計算,就直接計算,然后倒推回答案。

經典例題:[集訓隊互測]calc

求自然數冪和

這個應用基於一個性質:設 \(S_k(n)=\sum_{i=1}^ni^k\),那么 \(S_k(n)\) 就一定可以被表示為一個關於 \(n\)\(k+1\) 次多項式

證明可以由自然數冪和的推導方式得來(比如差分法),或者使用數學歸納法,之類的。

然后,既然知道了這個結論,我們就直接用,求 \(S_k(n)\) 的時候,我們先算出前 \(k+2\) 項的冪和,然后就可以把 \(n\) 代入求值。由於前 \(k+2\) 個自然數是連續的一段整數,因此可以很方便地對插值過程中的系數進行遞推。單次可以做到 \(O(k\log_2p)\),其中 \(p\) 為模數(需要存在逆元)。

題外話:求自然數冪和的方法不少,插值法之外還有 伯努利數 + 多項式膜法 ,第二類斯特林數 等等。

其它插值方法

拉格朗日插值法改進版

這個方法其實......就是對原先的式子稍微修改一下。

考察 \(f_i(x)\)

\[\begin{aligned} f_i(x) &=\frac{\prod_{j\not=i}(x-x_j)}{\prod_{j\not=i}(x_i-x_j)}\\ &=\frac{\prod_{j=1}^n(x-x_j)}{(x-x_i)}\times \frac{1}{\prod_{i\not=j}(x_i-x_j)} \end{aligned} \]

經過這樣的變換,我們發現每個子函數都有一大塊是相似的,因此定義:

\[\ell(x)=\prod_{i=1}^n (x-x_j) \]

於是就有:

\[f_i(x)=\frac{\ell(x)}{(x-x_i)}\times \frac{1}{\prod_{i\not=j}(x_i-x_j)} \]

對 " 各具特色 " 的后半部分專門定義,稱為重心權

\[w_i=\frac{1}{\prod_{i\not=j}(x_i-x_j)} \]

於是我們就得到了拉格朗日公式改進版

\[f(x)=\sum_{i=1}^n \ell(x)\frac{w_i}{(x-x_i)} \]

這個公式的優點在於,插值點多一個或者少一個,它就只會影響到共 \(n\) 個值。而這 \(n\) 個值的修改理論可以做到單個 \(O(1)\),總的修改時間就是 \(O(n)\)

重心拉格朗日插值法

待填坑


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM