今天聽說了一篇很牛逼的論文,標題就把我嚇到了:《Hamiltonian Cycle Problem is in P》。網址:https://arxiv.org/abs/2105.07608。
我懷着好奇的心情下載讀了一下,大概讀懂了它的算法意思,我簡單地解釋一下。
先從幾個定義看起。
定義一大致意思說的就是對原圖 \(G\) 建一個 \(n + 1\) 層的分層圖 \(G'\),其中第 \(0\) 層和第 \(n\) 層只有一個節點 \(1\)(原文寫的是任選一個節點 \(v\) 作為回路的起點和終點,根據習慣我就簡單地當做是 \(1\) 號節點了),中間的 \(1\) 到 \(n - 1\) 層每層都有節點 \(2\) 到節點 \(n\) 這 \((n - 1)\) 個節點,於是一共有 \((n - 1) ^ 2 + 2\) 個節點。然后對於原圖的每條邊都在分層圖每相鄰兩層的對應端點連邊。
總結起來就是非常標准的分層圖建法,除了一些小細節處理可以理解為常數優化以外和我們習慣的建圖方法一樣。我不知道這玩意兒官方名稱是不是叫 hologram,但就感覺這個 “全息圖” 的名字老帥了。
定義二說的就是一條從起點 \(<1, 0>\)(\(<u, l>\) 表示第 \(l\) 層的 \(u\) 號節點對應的節點,下同)到終點 \(<1, n>\) 的一條路徑,除了起點終點經過的點都不相同。很容易發現如果把層那一維去掉,這條路徑就是要求的一個哈密頓回路。
定義三比較有意思。它在分層圖 \(G'\) 上的每一個點 \(<u, k>\) 定義了一個路徑集合 \(\text{PS}[<u, k>]\)。這個數組里面記錄了起點 \(<1, 0>\) 到這個點 \(<u, k>\) 上所有的路徑。顯然朴素的記錄方法是 \(O(\)路徑數\()\),不是多項式復雜度的,但是這里用了一個很“聰明”的方法:把每一層可能出現的點整理在一起合並起來。
舉個例子,如果出現了這樣的路徑集合:\(\{(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 4, 2)\}\),那么對應的 \(\text{PS} = \{(1), (2, 3), (3, 4), (2, 3, 4)\}\)。因為第一個位置只出現了 \(1\),第二個位置出現了 \(2, 3\),第三個位置出現了 \(3, 4\),第四個位置出現了 \(2, 3, 4\)。這樣一來就是多項式復雜度內的了。
如果你有做過哈密頓回路問題,應該能很明顯的察覺出:PS 數組是沒有意義的。事實上,這篇論文最大的問題就出在這里,請慢慢往下看。
定義四給了一些東西的簡單記號。\(N ^ {-}(v)\) 表示原圖上 \(v\) 點的入邊集合,\(N ^ {+}(v)\) 表示原圖上 \(v\) 點的出邊集合。\(\text{PS}_{<u, k>}[i]\) 指的就是 \(\text{PS}[<u, k>]\) 這個集合數組,第 \(i\) 層的那個集合。\(AF ^ {-}(<v, i>)\) 和 \(AF ^ {+}(<v, i>)\) 我不知道怎么表述它,大概你根據那個定義理解一下,形象說一下就是這個點對路徑記錄的上一層的連通性的影響。
定義到這結束了。接下來它扔了幾個結論,說是會在附錄里證明它們。
結論一:原圖存在哈密頓回路當且僅當分層圖有那么一條路徑。這個顯然,拍扁了就是。這個結論沒問題。
結論二:原圖存在哈密頓回路當且僅當做完 PHG-BP 算法(PHG-BP 是作者給的該問題主算法的名字,全稱為 Path HoloGram - Basic Path)后 \(\text{PS}[<1, n>]\) 非空。這個也沒有問題。這個數組的定義就是所有能夠到它的合法路徑(合法指除了起點終點以外沒有重復點)點集並起來,從定義出發就是正確的。但是這個 PHG-BG 算法是否真的能夠求出 \(\text{PS}[<1, n>]\) 我表示懷疑。如果真的實現了,那么至少完成了在多項式時間內判斷一張圖是否有哈密頓回路,這成果不亞於找出哈密頓回路。
結論三到結論五都在說這個 PHG-BP 算法的正確性。其中 CM 算法(Consitency Maintain)和 LPM 算法(Longest Path Merging)都是 PHG-BP 算法中運用里調用的一些子函數。LPM 是非常簡單的合並過程,但 CM 算法問題很大,接下來會詳細介紹。
結論六說知道了 \(\text{PS}[<1, n>]\) 后可以用一個叫 FHC 算法(Find Hamilton Cycle)的東西路徑還原得到哈密頓回路。這更離譜了,論文里給的算法問題非常明顯,反例是很容易給出的,下文會介紹。
前置部分介紹完了,進入它主要的算法流程。
算法主要分為三大部分:GPHG(Generate Path HoloGram)、PHG-BP(Path HoloGram - Basic Path)和 FHC(Find Hamilton Cycle)。
GPHG 是簡單的,就是普通的分層圖建法。不贅述。
然后先來研究一下這個神奇的 FHC 函數。
我看到這直接大跌眼鏡。原本以為有什么高妙的方法還原,實際上是這樣的:從終點開始,選擇一條非冗余的合法的前向邊走過去,要求走到的節點 \(<v, i>\) 滿足 \(v \in \text{PS}_{<1, n>}[i]\)(即 \(v\) 在可能出現的曼哈頓路徑上)且還沒有被加入過。
啊,槽點太多我不知道怎么說好。
要說復雜度是多項式的……的確。但是這個正確性……
算了直接扔個反例上來吧。
哈密頓路徑有兩條:\(1 \to 2 \to 3 \to 4 \to 5 \to 1\) 和 \(1 \to 3 \to 4 \to 2 \to 5 \to 1\)。所以 \(\text{PS} = \{(1), (2, 3), (3, 4), (2, 4), (5), (1)\}\)。當走到第三層(即 \(<2, 4>\) 層)的 \(2\) 時,如果剛好選到 \(3 \to 2\) 這條邊走到了 \(3\),接下來立刻就無解了,找不出哈密頓回路。
最后看到這個最最最神奇的 PHG-BP 算法。
主函數就是一個 DP 的過程,從 \(<1, 0>\) 開始一層層往上推 \(\text{PS}\) 數組。有意思的在它的兩個子函數 CM 和 LPM。
CM 函數的功能為,確定加入了這個新點 \(<u, i>\) 后,\(\text{PS}\) 數組(路徑集合)會變成什么樣。
LPM 函數的功能為,把這種情況的 \(\text{PS}\) 數組(路徑集合)與已經求得的路徑集合合並。
你可以理解為 DP 轉移的過程。\(\texttt{f[u] = merge(f[u], plus(g[v], u))}\),其中 \(f\) 數組就是 \(\text{PS}\) 數組,\(\text{merge}\) 函數對應 \(\text{CM}\) 函數,而 \(\text{plus}\) 函數對應 \(\text{LPM}\) 函數。
LPM 比較正常。它做的事情就是把傳進來兩個 \(\text{PS}\) 數組各層的點集合並起來,沒什么特殊的。我們着重關注 CM。
我們舉加入一個點 \(<v, k>\) 為例。CM 函數分兩類討論。
一類是新加入的點 \(v\) 在之前的路徑集合里出都沒有出現過,這是最理想的情況,直接新開一個第 \(k\) 層給 \(v\) 就好。
否則出現過,那么出現了一些沖突。因為這一層只有 \(v\) 就說明這一層經過的點一定是 \(v\),那么 \(v\) 在之前的層里不能出現。這里麻煩可大了,用最淺白的話解釋:出現了后效性。按照我們的認知,這個動態規划過程已經可以被否決掉了。可是這篇論文比較牛逼,它給出了一個調整 \(\text{PS}\) 數組的方法,可以多項式時間內退出新一步的 \(\text{PS}\) 數組。
調整法基於一個很膚淺的觀察:第 \(k\) 層必須經過 \(v\) 點,那么前 \(k - 1\) 層所有有含 \(v\) 的路徑全部都得刪掉(可以參考論文中的圖)。
可是怎么刪呀?這時候最牛逼的函數出來了:LAFDR (Left Action Field Deleting-Replenishing)和 RAFDR(Right Action Field Deleting-Replenishing)。由於 RAFDR 和 LAFDR 對稱,這里只介紹 LAFDR。
(可以這玩意該怎么介紹好啊?我完全無法理解它到底為什么可以這樣做,直接根據偽代碼看吧。具體的反例什么的先挖個坑待填吧。)
到這里論文最核心的東西講完了。剩下那個 Conclusion 章節就說什么這個多項式算法適用性很廣啊,價值很大啊,是一個 breakthrough 之類的。看着看着就笑了,笑着笑着就哭了。
怎么說呢?就覺得很厲害好吧。很厲害。