Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Knuth_optimization.md #76

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Cr-bubble
Copy link

@Cr-bubble Cr-bubble commented May 14, 2023

#38

  • Read Contribute to NTHU-CPP.
  • Rebase to the latest main branch.
  • List all the references.
  • Successfully build the website by mdBook with no error after the change.
  • Exclude any irrelevant files.
  • Link to the issue which is related to your change.
  • Review the content by myself.
  • Pass tests/CI.

@harry900831 harry900831 linked an issue May 18, 2023 that may be closed by this pull request
@Cr-bubble Cr-bubble marked this pull request as ready for review June 10, 2023 17:19
@Cr-bubble Cr-bubble changed the title Add Monotone_optimization.md draft Add Monotone_optimization.md Jun 10, 2023
@Cr-bubble
Copy link
Author

Hi @harry900831, the outline and most of the content is finished, except problem descriptions and solutions for the exercises. I will add them as soon as possible. I think I can ask for comments first so I can fix the content. Thanks.

Copy link
Contributor

@harry900831 harry900831 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 現在看下來這三個主題塞在同一篇內容會有點太多,同時對你完成這次作業來說也會有點太多,我覺得可以分成三篇1. 1D/1D單調 2. Knuth optimization 3. divide and conquer optimization。看你想要先 focus 在哪一篇我們先 merge 那一篇進去。
  • 目前的大問題是 1. 解釋的不是很清楚,至少我看過去還是看不懂QQ 2. 要準備 teamplate code 3. 對於應用的題目需要證明他確實有這個單調性
  • 每一個技巧希望都能詳細講解個兩題,題目最好使用 CF, Atcoder, CSES 等等真找不到的話再去用一些不常用的OJ
  • 我的建議是多用圖片輔助解釋,但是圖片上也需要標示清楚,先專心將其中一個技巧講清楚就好,那就已經會花掉很多時間了。不要只針對我有 comment 的地方去修改。

@@ -0,0 +1,552 @@
# Monotone optimization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這個主題名稱是你自己訂的嗎?
還是真的有這個名詞?

- **凹四邊形不等式** (concave Monge condition):若 \\(A\\) 滿足凹四邊形不等式,則 \\(a+d\ge c+b\\)
- **凸四邊形不等式** (convex Monge condition):若 \\(A\\) 滿足凹四邊形不等式,則 \\(a+d\le c+b\\)

<img src="image\Monotone_optimization\blank.JPG" width="500" style="display:block; margin: 0 auto;"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

請避免非白底與手繪風的圖示

Comment on lines 13 to 15
- **凹四邊形不等式** (concave Monge condition):若 \\(A\\) 滿足凹四邊形不等式,則 \\(a+d\ge c+b\\)
- **凸四邊形不等式** (convex Monge condition):若 \\(A\\) 滿足凹四邊形不等式,則 \\(a+d\le c+b\\)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

只有 Monge 有大寫正常嗎?

- **凹完全單調** (concave totally monotone):若 \\(A\\) 滿足凹完全單調,則 \\(a\le b\implies c\le d\\)
- **凸完全單調** (convex totally monotone):若 \\(A\\) 滿足凸完全單調,則 \\(a\ge b\implies c\ge d\\)
- **凹四邊形不等式** (concave Monge condition):若 \\(A\\) 滿足凹四邊形不等式,則 \\(a+d\ge c+b\\)
- **凸四邊形不等式** (convex Monge condition):若 \\(A\\) 滿足凹四邊形不等式,則 \\(a+d\le c+b\\)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

凹 -> 凸


首先來看看單調性在 1D/1D 的應用。定義一個 1D/1D 的 DP 問題:

> 要求的是一維代價 \\(dp[j]\\): \\[dp[j] = \underset {0\le i\lt j}{min}\\{f(i,j,dp[i])\\}, \forall 1\le j\le n\\]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

請使用函數表示的方式 f(i) 而非 dp[i]

習慣的表示方式 是要求 i 然後去枚舉 j
所以應該是 f(i) = f(j) + .... for all j < I 之類的

Comment on lines 247 to 251
> **Monge condition implies Monotonic Optimal Split Point**
>
> 當上述 2D/1D 問題的代價 \\(w\\) 符合凸四邊形不等式,即:
> \\[dp[i]\[j]+dp\[i+1][j+1] \ge dp\[i][j+1]+dp\[i+1][j]\\]
> 則決策點具有單調性 : \\(opt\[i][j-1]\le opt\[i][j]\le opt\[i+1][j]\\),即 \\(dp\[i][j]\\) 的決策點位在 \\(dp\[i][j-1]\\) 到 \\(dp\[i+1][j]\\) 的決策點之間。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

請使用 f(i, j) and opt(i, j)


<details><summary> Solution Code </summary>

- 觀察可發現代價函數 \\(C\\) 滿足 Monge condition (等號都成立),可以套用 Knuth Optimization 解決。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要證明

>
> 令 \\(F(i,j)\\) 為一個對所有 \\(1\le i\le j\le N\\) 的正整數 \\(i,j\\) 都有定義的函數。對於所有的 \\(1\le j\le N\\),求 \\(\underset {i\le j}{min}\space F(i,j)\\) 或 \\(\underset {i\le j}{max}\space F(i,j)\\)。

直接來看一題題目最清楚。
Copy link
Contributor

@harry900831 harry900831 Jun 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

為什麼這個技巧又直接看題目比較清楚了
前面都沒有這個待遇XD


不妨先假設 \\(B\\) 具有凹單調性且 \\(B\\) 中所有元素皆相異 (若有相同元素隨意定序即可),若我們已經知道 \\(x = B\[i]\[j]\\) 是第 \\(j\\) 行的最小值,也就是 \\(dp\[j]\\) 的答案,則根據凹單調性可知:

- 對於任意 \\(i^{\prime}\lt i,j^{\prime}\lt j\\) 有 \\(B\[i]\[j^{\prime}]\lt B\[i^{\prime}]\[j^{\prime}]\\) (\\(\because B\[i]\[j]\lt B\[i^{\prime}]\[j]\\),由凹單調的逆反命題得知),因此所有位於 \\(B\[i][j]\\) 左上角的元素都不可能是最佳的轉移來源。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

誰的最佳轉移來源

Comment on lines 70 to 76
l = tp.l-1, r = tp.r;
while(r-l > 1)
{
mid = (l+r)>>1;
if(cal(tp.pos,mid) >= cal(i,mid)) l = mid;
else r = mid;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這 l, r 應該可以換成更有效率的做法

@Cr-bubble Cr-bubble changed the title Add Monotone_optimization.md Add Knuth Optimization.md Jun 24, 2023
@Cr-bubble Cr-bubble changed the title Add Knuth Optimization.md Add Monotone_optimization.md Aug 10, 2023
@Cr-bubble Cr-bubble closed this Aug 10, 2023
@Cr-bubble Cr-bubble reopened this Aug 10, 2023
@Cr-bubble Cr-bubble changed the title Add Monotone_optimization.md Add Knuth_optimization.md Aug 10, 2023
@harry900831 harry900831 self-requested a review September 10, 2023 09:32

要優化 DP 算法可以從以上 3 種下手,本文要介紹的 Knuth's Optimization 是透過減少**每個狀態轉移的狀態數**來加速 DP。Knuth's optimization 通常用於解決具有以下形式轉移的 2D/1D 問題:

> 要求的是一個二維函數 \\(dp(i,j)\\):> \\[ dp(i,j) = w(i,j) + \underset{i\le k\lt j}{min} \\{dp(i,k)+dp(k+1,j)\\}, \forall 1\le i\lt j\le n\\]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:>
what is this symbol?

Comment on lines +13 to +15
Knuth's Optimization 的應用可說是非常簡單,以 [Atcoder DP contest-Slime](https://atcoder.jp/contests/dp/tasks/dp_n) 為例,我們可以列出這個 DP 式(在此就不詳細解釋細節):\\[dp(i,j) = w(i,j) + \underset{i\le k\lt j}{min}\\{dp(i,k)+dp(k+1,j)\\}\\]

可用下面這段 \\(O(n^3)\\) 的程式片段求出答案 \\(dp(1,n)\\)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's worth to make this problem as an example

and explain what is w(i, j)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這會讓讀者閱讀比較順暢
並不是所有人都知道slime是什麼


- Note : \\(x\\)D/\\(y\\)D 問題是指有 \\(N^x\\) 子問題,每個子問題需 \\(N^y\\) 子問題轉移,因此有時間複雜度為\\(O(N^{x+y})\\) 的 DP 做法。

Knuth's Optimization 的應用可說是非常簡單,以 [Atcoder DP contest-Slime](https://atcoder.jp/contests/dp/tasks/dp_n) 為例,我們可以列出這個 DP 式(在此就不詳細解釋細節):\\[dp(i,j) = w(i,j) + \underset{i\le k\lt j}{min}\\{dp(i,k)+dp(k+1,j)\\}\\]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要把 base case 也列上去

Comment on lines +17 to +63
```cpp=
for(int i=1;i<=n;i++)
{
for(int k=1;k<=n;k++)
{
dp[i][k] = (i == k ? 0 : INF);
}
}
for(int len=2;len<=n;len++)
{
for(int i=1;i+len-1<=n;i++)
{
int j = i+len-1;
for(int k=i;k<j;k++)
{
dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]+pre[j]-pre[i-1]);
}
}
}
```

若我們知道這題可套用 Knuth's Optimization 要運用……

只需將 **\\(i\le k\lt j\\)** 換成 \\(opt\[i][j-1]\le k\le opt\[i+1][j]\\) 就好!

```cpp=
int i,j,k,len;
for(i=1;i<=n;i++) dp[i][i] = 0, opt[i][i] = i;
for(len=2;len<=n;len++)
{
for(i=1;i+len-1<=n;i++)
{
j = i+len-1;
dp[i][j] = INF;
int optl = opt[i][j-1];
int optr = opt[i+1][j];
for(k=optl;k<=optr;k++)
{
if(dp[i][j] > w(i,j) + dp[i][k] + dp[k+1][j])
{
dp[i][j] = w(i,j) + dp[i][k] + dp[k+1][j];
opt[i][j] = k;
}
}
}
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the style of two code is not the same?

I would prefer change the first one to something like:

vector<vector<int>> dp(n + 1, vector<int>(n + 1, INF));

auto w = [&](int i, int j) {
  return pre[j] - pre[i - 1];
}

for (int i = 1; i <= n; i++) dp[i][i] = 0;
for (int len = 2; len <= n; len++) {
  for (int i = 1; i + len - 1 <= n; i++) {
    int j = i + len - 1;
    for (int k = i; k < j; k++) {
      int val = dp[i][k] + dp[k + 1][j] + w(i, j);
      dp[i][j] = min(dp[i][j], val);
    }
  }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please verify the code by yourself

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if you are not demanded on using your own coding style, I would prefer the code to be formated by clang-format

Comment on lines +65 to +67
\\(opt\[i][j-1]\\) 為 \\(dp\[i][j]\\) 的最佳轉移點,神奇的事發生了,這段程式的複雜度為 \\(O(n^2)\\)!

接下來我們來詳細解釋 Knuth's Optimization 實際上做了什麼。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我覺得解釋玩什麼是四邊形優化,再來把 slime 優化到 O(n^2) 會比較順

不知道你怎麼看

Comment on lines +103 to +129
Lemma : 假設以上條件成立,\\( dp \\) 函數也會滿足凸四邊形不等式。

- 定義 \\( dp_t(i,j) = dp(i,t)+dp(t+1,j)+w(i,j) \\)
- 對於 \\(i\lt j\\) 我們可以找到 \\(p ,q\\) 使 \\(i\le p\le q\lt j-1\\),且令 \\(opt(i,j-1) = q\\)

如果我們能證明 \\(dp_p(i,j-1) \ge dp_q(i,j-1) \implies dp_p(i,j) \ge dp_q(i,j) , \forall i \le p \lt q\\)

則顯然 \\( opt(i,j-1) \le opt(i,j) \\)。

對於 \\( p+1 \le q+1 \le j-1 \le j \\),根據四邊形不等式我們有:\begin{align}
&dp(p+1, j-1) + dp(q+1, j) ≤ dp(q+1, j-1) + dp(p+1, j) \\\\
\implies& (dp(i, p) + dp(p+1, j-1) + C(i, j-1)) + (dp(i, q) + dp(q+1, j) + C(i, j)) \\\\
\leq& (dp(i, q) + dp(q+1, j-1) + C(i, j-1)) + (dp(i, p) + dp(p+1, j) + C(i, j)) \\\\
\implies& dp_{p}(i, j-1) + dp_{q}(i, j) ≤ dp_{p}(i, j) + dp_{q}(i, j-1) \\\\
\implies& dp_{p}(i, j-1) - dp_{q}(i, j-1) ≤ dp_{p}(i, j) - dp_{q}(i, j) \\\\
\end{align}
\begin{align}
&dp_{p}(i, j-1) \geq dp_{q}(i, j-1) \\\\
&\implies 0 \leq dp_{p}(i, j-1) - dp_{q}(i, j-1) \leq dp_{p}(i, j) - dp_{q}(i, j) \\\\
&\implies dp_{p}(i, j) \geq dp_{q}(i, j)
\end{align}
如此一來就證明 \\( opt(i,j-1) \le opt(i,j) \\),而另一半不等式用相似方法亦可證明。

<details><summary> Prove Lemma </summary>

有興趣的讀者可以參考這篇 [Efficient Dynamic Programming Using Quadrangle Inequalities](https://dl.acm.org/doi/pdf/10.1145/800141.804691)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這裡我就整段看不懂了QQQ

Comment on lines +127 to +131
<details><summary> Prove Lemma </summary>

有興趣的讀者可以參考這篇 [Efficient Dynamic Programming Using Quadrangle Inequalities](https://dl.acm.org/doi/pdf/10.1145/800141.804691)

</details>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這種如果是證明過程中 refer 出去的不需要用 <details> 包起來
不過你 refer 到論文有點@@

我會建議如果不難的話 至少用個幾句話給個淺顯的證明 或是提供一些直覺上會對的想法


\\[
\begin{array}{ccc}
opt_{i-2,j-3} \le opt_{i-2,j-2} \le opt_{i-1,j-2}\\\\
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

既然 i - j = 0 代表 i == j 那 opt(i - 2, j - 3) 真的存在嗎?這是一個右界小於左界的case?

Comment on lines +147 to +157
會發現前式轉移點的右界剛好是後式轉移點的左界!這樣一想,計算每個斜排時,最多只有 \\( O(N) \\) 種轉移來源,又約有 \\( 2N \\) 排,所以如果我們以索引值 \\(j-i\\) 由小到大遞增的順序計算 DP 表格,算出 DP 表格的複雜度 \\(O(N)\times O(2N) = O(N^2)\\),比直接算的 \\(O(N^3)\\) 快多了!

但這樣做的正確性呢?若我們以索引值 \\(j-i\\) 由小到大遞增的順序計算,索引值差為 \\( j-i-1 \\) 的 \\( dp(i,j-1) \\) 與 \\( dp(i+1,j) \\) 會在算索引值差 \\( j-i \\) 的 \\( dp(i,j) \\) 前算出來,因此要算 \\( dp(i,j) \\) 時,\\( opt(i,j-1)、opt(i+1,j) \\) 都是已知,我們就不必再跑過所有轉移來源 \\([i,j]\\),只需要去檢查 \\( [opt(i,j-1), opt(i+1,j)] \\) 就能求得 \\(dp(i,j)\\) 與 \\(opt(i,j)\\)。

下圖中黑色格子為非法值,黃色已知,綠色為正在計算,灰色未計算,計算順序如箭頭所示。

<img src="image\Knuth_optimization\dp_order.png" width="300" style="display:block; margin: 0 auto;"/>

\\[ 計算每塊綠色格子只需左邊與下方黃色格子的 opt\\]

以下為程式碼片段
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這一段也看不懂QQ

我懂覺得你的圖與你的敘述講得很像是在算某一條斜排的值上的每個元素只會使用到它左邊和下面的元素

但事實上其實是要 iterate from opt 表格上 他左邊的值 to opt 表格上他下面的值


<img src="image\Knuth_optimization\dp_order.png" width="300" style="display:block; margin: 0 auto;"/>

\\[ 計算每塊綠色格子只需左邊與下方黃色格子的 opt\\]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

完全會被這句話帶歪

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Monotone optimization(四邊形優化)
2 participants