åèã«ããã®ã¯ï¼ãã¤ãã® CS166 ã®ã¹ã©ã¤ãï¼
ãã§ããæä½ãããã®æä½ã§ã§ãããããããã¨ããå®è£ ãã®é ã«æ¸ãã¾ãï¼äºå®ï¼ï¼
è±èªã楽ã«èªãã人ã¯ä¸ã®ã¹ã©ã¤ããè¦ãã¨ããããã§ãï¼
ã§ããæä½
ã¾ãï¼ããã¯ãã¼ããªã®ã§ï¼åªå 度ã¤ããã¥ã¼ã®åºæ¬ä¸æ¼ç®ãã§ãã¾ãï¼
- push(k, v)
- åªå 度ã k ã§ããè¦ç´ v ã追å ãã
- \(O(1)\) time
- top()
- åªå 度ãæãé«ãè¦ç´ ãè¿ã
- \(O(1)\) time
- pop()
- åªå 度ãæãé«ãè¦ç´ ãåãé¤ã
- amortized \(O(\log n)\) time
便å®ä¸ï¼ãè¦ç´ v ãå ¥ã㦠v ã®å¤ã§æ¯è¼ãããã§ã¯ãªããåªå 度 k ãæã¤è¦ç´ v ãå ¥ã㦠k ã®å¤ã§æ¯è¼ãããã¨ãããã¨ã«ãã¦ããã¾ãï¼
ã§ï¼ããã«å ãã¦ä»¥ä¸ã®æä½ãã§ãã¾ãï¼
- meld(h)
- å¥ã® Fibonacci ãã¼ã h ã¨çµ±åãã
- \(O(1)\) time
- prioritize(e, k')
- // e ã¯è¦ç´ (k, v) ã¸ã®åç §
- e ã®åªå 度ãå ã ã® k ããé«ã k' ã«å¤æ´ãã
- amortized \(O(1)\) time (!!)
åªå 度ã®æä½ããªããå®æ°æéã§ã§ãã¦ããããã§ãï¼
æä½ã®å¼ã³æ¹ã«ã¤ãã¦
prioritize 㯠decrease-key ã¨æ¸ãããããããã¨ãå¤ãã®ããªãï¼min ã max ãªã©ã«å¯¾ãã¦ä¸ç«ãªè¡¨ç¾ãæ¢ãã¦ãã¾ããï¼
prioritizeã©ãã ãã
— è¡è¤æ¸ (@eto_nagisa) October 26, 2019
ãããã¨ããããã¾ããï¼
ãããããã¨
ä¾ã¨ãã¦ï¼Dijkstra æ³ã®è¨ç®éã®ãªã¼ãã¼æ¹åãæãã¾ãï¼
Dijkstra æ³ã¯åä¸å§ç¹ã®æçè·é¢ãæ±ãããã®ã§ï¼æ¦ã次ã®ãããªã¢ã«ã´ãªãºã ã§ãï¼ ä¸åã¯è¦ããã¨ããã人ã対象ã¨ãã¦æ¸ãã¦ããã¤ããã§ãï¼
dijkstra(g, s) { // g ã¯ã°ã©ãã表ãé£æ¥ãªã¹ãï¼é ç¹æ° n ã§è¾ºæ° m ã¨ãã // s ããã®æçè·é¢ãæ±ãã vector<weight_type> dp(n, inf); dp[s] = 0; priority_queue<pair<weight_type, index_type>> pq; pq.push({0, s}); // s ã¸ã®è·é¢ ã 0 while (!pq.empty()) { weight_type w; index_type v; tie(w, v) = pq.top(); // æãè¿ãé ç¹ v ã¨ããã¸ã®è·é¢ w pq.pop(); if (dp[v] < w) continue; // w ããçãè¡ãããªããã¹ for (auto e: g[v]) { weight_type = nw = dp[v] + e.cost index_type nv = e.target if (nw < dp[nv]) { // çãè¡ãããã¨ãããã£ããæ´æ°ãã¦ãã¼ãã«ãå ¥ãã dp[nv] = nw pq.push({nw, nv}); // *** } } } return dp; }
ã§ï¼***
ã®é¨åãªãã§ããï¼å®éã«è¦ç´ (nw, nv)
ãå
¥ãç´ãå¿
è¦ã¯ãªãã¦ï¼ãã§ã«å
¥ã£ã¦ããè¦ç´ nv
ã®åªå
度ã nw
ã«ãããã¨ãã§ããã°ããããã§ãããï¼
s
以å¤ã®è¦ç´ ãï¼åªå
度ã inf
ã¨ãã¦æåãããã¼ãã«å
¥ãã¦ããã¨èãã¾ãï¼
ããããã¨ï¼çµå±ï¼ãã¼ãã«å¯¾ããæä½ã¯æ¬¡ã®ããã«ãªãã¾ãï¼
- \(n\) åã® push
- \(O(n)\) time
- \(n\) åã® pop
- æåã®è¿½å ã®å¾ï¼æ°ãã«é ç¹ããã¼ãã«å ¥ããã¨ã¯ãªããã
O(n log m) time- \(O(n \log n)\) time
- \(m\) åã® prioritize
- åé ç¹ããåºã辺ã«å¯¾ãã¦ï¼ä¸åãã¤ããè¦ãããªããã
- \(O(m)\) time
ã¾ãï¼ã°ã©ãã®æ§è³ªãã m = O(n2)ã§ï¼ O(log m) = O(log n) ã§ãã®ã§ï¼ å
¨ä½ã§ \(O(m + n \log n)\) time ã¨ãªãã¾ãï¼
ãããã \(n\) åãããã¼ãä¸ã«å
¥ããªãã®ã§ \(\log m\) ã¨ãã¯é¢ä¿ãªãã£ãã§ããï¼
å®è£
tl; drï¼ãã¤ã³ã¿ã§ããããããã°ãã¾ãï¼ããããªäººã¯ã¤ãããï¼
以ä¸ã®ãããªæµãã§èª¬æãã¾ãï¼
- ãã¼ã¹ã¨ãªãäºé
ãã¼ãã«ã¤ãã¦ã®è©±
- binomial heapï¼äºåãã¼ã (binary heap) ã¨ã¯å¥
- ãã¤ã³ã¿ã«ããæ¨ã«åºã¥ããã¼ã
- ä¸ã«æ¸ãã Fibonacci heap ã®æä½ã®ãã¡ï¼prioritize 以å¤ãã§ãã
- prioritize ãè¡ãæ¹æ³
- ãã¼ã¿æ§é ã®è¡¨ç¾æ¹æ³
- æç´ãªãã¤ã³ã¿æ¨ã 㨠amortized \(O(1)\) time ãå®ç¾ã§ããªãã®ã§å·¥å¤«ããå¿ è¦ããã
äºé ãã¼ã
2 ã¹ãã®è¦ç´ æ°ã®ãã¼ããã¡ãé£çµãªã¹ãï¼linked listï¼ã§æã¡ã¾ãï¼
list<heap>
ã®ãããªãã®ãã¤ã¡ã¼ã¸ããã¨ããã¦ï¼ããå
¨ä½ã§äºé
ãã¼ãã§ãï¼
é£çµãªã¹ãã§ç®¡çãããåãã¼ãããåãã¼ããï¼å ¨ä½ããªããã¼ããã親ãã¼ããã¨å¼ã¶ãã¨ã«ãã¾ãï¼
親ãã¼ããæã£ã¦ããã®ã¯æ¬¡ã®äºã¤ã§ãï¼
- åãã¼ããè¦ç´ ã¨ãã¦æã¤é£çµãªã¹ã
- å ¨ä½ã§æãåªå 度ãé«ãè¦ç´ ã管çããåãã¼ãã¸ã®ãã¤ã³ã¿
åãã¼ããã©ã表ç¾ãããã®èª¬æã¯å¾åãã«ãã¾ããï¼åãã¼ãã¯ä»¥ä¸ã®æä½ãã§ããã¨ãã¾ãï¼
- meld(h) in \(O(1)\) time
- å¥ã®åãã¼ã h ã¨çµ±åãã
- ããã«ããè¦ç´ æ°ã 2 åã«ãªã
- Note: \(2^i + 2^i = 2^{i+1}\)
- top() in \(O(1)\) time
- æãåªå 度ã®é«ãè¦ç´ ãè¿ã
- pop() in \(O(i)\) time
ãã¦ï¼ããã®ãã¨ã§ï¼è¦ªãã¼ãã«å¯¾ããå¦çãã¡ãèãã¾ãï¼
push
è¦ç´ æ° 1 ã®åãã¼ããã¤ããï¼ãªã¹ãã®æ«å°¾ã«è¿½å ãã¾ãï¼\(O(1)\) time ã§ã§ãã¾ããï¼ å¿ è¦ã«å¿ãã¦ï¼æãåªå 度ãé«ãè¦ç´ ãæã¤åãã¼ãã¸ã®ãã¤ã³ã¿ãæ¸ãæãã¾ãï¼
Note: \(1 = 2^0\)ï¼
meld
ãªã¹ãå士ããã£ã¤ããã ãï¼å½ç¶ \(O(1)\) time ã§ã§ãã¾ãï¼ãã¤ã³ã¿æ¸ãæããé©å®ï¼
top
æãåªå 度ãé«ãè¦ç´ ãæã¤åãã¼ãã¸ã®ãã¤ã³ã¿ãæã£ã¦ãã¾ããï¼ ãããæããã¼ãã« top ãèãã°ããã§ãï¼\(O(1)\) timeï¼
pop
ããã¼ï¼
ã¾ãï¼æãåªå 度ãé«ãè¦ç´ ãæã¤åãã¼ãããã©ãã¾ãï¼ ä¸ã§è¿°ã¹ãåãã¼ãã® pop ã§ã§ããããåãã¼ããã¡ããªã¹ãã«å ¥ãã¾ãï¼
ããã¾ã§ã® push ãï¼ä»ã®å¦çãªã©ã®çµæï¼è¦ç´ æ°ãå°ãªãåãã¼ããããããããã®ãã¤ã¡ã¼ã¸ã§ãã¦ããããã¨ããããã§ãï¼
ãã®ç¶æ ã§æ¬¡ã«åªå 度ãé«ãè¦ç´ ãæ¢ããã¨ããã¨å¤§å¤ãããªã®ã§ï¼ã§ããã ãè¦ç´ æ°ãæ¸ããã¦ããããã§ãï¼ å ¨ä½ã§è¦ç´ æ°ã \(n\) ã®ã¨ãï¼ããããã¾ã¨ãä¸ã㦠\(\log_2 n+O(1)\) åã®åãã¼ãã«ããã®ãç®æ¨ã«ãã¾ãï¼
è¦ç´ æ° \(2^i\) ã®ãã¼ããµãã¤ã meld ããã¨è¦ç´ æ° \(2^{i+1}\) ã®åãã¼ããã²ã¨ã¤ã§ããã®ããã¤ã³ãã§ãï¼
é£çµãªã¹ãã§ç®¡çãã¦ããåãã¼ããé ã«è¦ã¦ï¼åãè¦ç´ æ°ã®åãã¼ããç¾ããããããã meld ãã¦ããã¾ãï¼
ãã®çµæï¼\(n\) ãäºé²æ°ã§è¡¨ããã¨ãã« \(i\) bit ç®ãç«ã£ã¦ããã° \(2^i\) ãµã¤ãºã®åãã¼ããã§ããããã¾ãï¼
\(n\) 㯠\(\log_2 n+O(1)\) bit ã§è¡¨ããã®ã§ï¼åãã¼ãã®åæ°ãããã§æãããããã¨ã«ãªãã¾ãï¼
ãã¨ã¯ï¼ãã®ã¾ã¨ããããåãã¼ãã®ä¸ã§æãåªå 度ã®é«ããã®ãæã¤ãã®ãæ¢ãã°ããã§ãï¼
è¨ç®éã®ç´æçãªè©±
\(n\) å push ããå¾ã« pop ãè¡ã㨠\(O(n)\) time ããã£ã¦ãã¾ãã¾ããï¼ç¶ãã¦ããä¸åº¦ pop ããå ´åï¼åãã¼ãã®åæ°ãæ¸ã£ã¦ããã®ã§ \(O(\log n)\) time ã§å¦çãçµããã¾ãï¼
ãªããè¨ç®éããåå¼·ãã¾ãããï¼
åãã¼ãã®è¡¨ç¾
åãã¼ãã¯å¤åæ¨ã§è¡¨ãã¾ãï¼
åãè¦ç´ æ°ã®æ¨ããã£ã¤ããã¨ãã¯ï¼çæ¹ã®æ ¹ãä»æ¹ã®æ ¹ã«ã¤ãªãã¾ãï¼åªå 度ã®é«ãæ¹ãæ°ããªæ ¹ã«ãã¾ãï¼
è¦ç´ æ°ã大ãããªãé ã«ï¼æ¬¡ã®ãããªæ¨ã«ãªãã¾ãï¼
äºé ãã¼ãã§ã¯ï¼ãã®æ¨ã left-child/right-sibling (LCRS) 表ç¾ã§è¡¨ãã¾ãï¼ ã\(i\) çªç®ã®å㯠\(i\) åç®ã®ãã¤ã³ã¿ãã®ãããªãã®ã§ã¯ãªãï¼ãåã¸ã®ãã¤ã³ã¿ãã¨ã次ã®å å¼ã¸ã®ãã¤ã³ã¿ããæã¡ï¼äºåæ¨ã®ããã«æ±ãã¾ãï¼
ããã«ããï¼ãã¶ãæ ¹ã pop ããã®ãå¹ççã«è¡ãããã ã£ãã¨æãã¾ãï¼
Fibonacci ãã¼ãã®æ¨ã§ã¯å¥ã®è¡¨ç¾æ¹æ³ãããã®ã§ï¼ããã§ã¯æ·±å ¥ããã¾ããï¼
ã¨ãããï¼ããã¾ã§ã®è©±ãã¡ããã¨èªãã¨äºé ãã¼ããå®è£ ã§ããã¯ãã§ãï¼
ãåãã¼ããè«ççã«ã¯ããããæ¨ã®å½¢ã§æã¤ãã¨ããã®ã¨ããã®æ¨ãããããæ¹æ³ã§è¡¨ç¾ãããã¨ããäºã¤ã®ã¬ã¤ã¤ã¼ããããã¨ã«æ³¨æããã¨ããããããã¾ããï¼ ä¸ã®å³ã¯åè ã«å¯¾å¿ãã¦ãã¦ï¼LCRS 表ç¾ã®ãªã³ã¯ã®å¼µãæ¹ã§ã¯ãªãã§ãï¼
prioritize
ãã¦ï¼ä¸ã§ä½ã£ãæ¨ã¯ãã¼ãæ¡ä»¶ãæºããã¦ãã¾ãï¼ã¤ã¾ãï¼è¦ªã¯ã©ã®åãããåªå 度ãé«ãã§ãï¼
ãããã¼ãã®åªå 度ãé«ãã¦ãï¼è¦ªã®åªå 度ãè¶ ããªããã°ãã¼ãæ¡ä»¶ãå´©ããªãã®ã§ããã§çµäºã§ãï¼
親ã®åªå 度ããé«ããªã£ã¦ãã¾ã£ãå ´åã¯ã©ããã¾ããããï¼
A Crazy Idea
ãã®ãã¼ãã親ããåãé¢ãã¦ãã¾ãã¾ãããï¼ ããããã°ãã¼ãæ¡ä»¶ãå´©ãã¾ãããï¼ããããï¼ï¼
ãã®ãã¼ããæ ¹ã¨ããåãã¼ãããªã¹ãã«è¿½å ãã¾ãããï¼å¿ è¦ã«å¿ãã¦ãã¤ã³ã¿ãæ¸ãæãã¾ãï¼
ããã ãã§çµäºã§ãï¼ã ã¨è©±ã¯åç´ãªãã§ããï¼ãããããã¾ããï¼
ç´°ããåãã¼ããç°¡åã«ããããä½ããã¨ãã§ãã¦ãã¾ãï¼pop ã®ãªããè¨ç®éãæªåãã¦ãã¾ãã¾ãï¼
対ç
ç´°ããåãã¼ããç°¡åã«ä½ãããªããã°ãããã§ãããï¼ ãã詳ããã¯ï¼ååãã¼ãã次ã®ãã¨ãæºããã¦ãããã¨ããã§ã*1ï¼
- æ ¹ãã¼ããæã¤åã®æ°ã«å¯¾ãã¦ï¼å ¨ä½ã®ãã¼ãæ°ãææ°çã«å¤§ãã
ã¨ãããã¨ã§ï¼æ ¹ãé¤ãåãã¼ãã«ã¤ãã¦ï¼åãé¢ããåãã¼ãã¯ããã ãä¸ã¤ã¨ããå¶ç´ãã¤ãã¦ã¿ã¾ãããï¼
ä¸åº¦åãã¼ããåãé¢ãããã¨ãï¼ãã®ãã¨ãè¦ãã¦ããããã«ãã¾ãï¼damaged ã¨å¼ãã§ãã¾ãï¼ï¼
damaged ãªãã¼ã v ããåã³åãåãé¢ããããªã£ãã¨ãã¯ï¼ã©ããã¾ããããï¼ v 㨠v ã®è¦ªãåãé¢ããã¨ã«ãã¾ãããï¼ããã«ããï¼é£éçã«åãé¢ããçºçãããã¨ã¯ããã¾ããï¼åé¡ãªããããã®ã§åé¡ãªãã§ãï¼
ã¨ããããã§ï¼prioritize ãã§ãã¾ããï¼
æ¨ã®è¡¨ç¾æ¹æ³
Fibonacci ãã¼ãã§æ±ãæ¨ã§ã¯ï¼ä»¥ä¸ã®ãããªæä½ãè¦æ±ããã¾ãï¼
- ãã¼ã u ã®åã«ãã¼ã v ã追å ãã
- ãã¼ã v ã®è¦ªã«ã¢ã¯ã»ã¹ãã
- damaged ã®ãã©ã°ãæ¸ãæãï¼ããã³å¤ã®æ¯è¼ãå¿ è¦
- ãã¼ã v ã¨ãã®è¦ª u ãåãé¢ã
ããããå®æ°æéã§è¡ããªãã¨è©±ã«ãªãã¾ããï¼
ãã¨ãã°ï¼åã®ãã¤ã³ã¿ã®é åãæã¡ï¼\(i\) çªç®ã®è¦ç´ 㯠\(i\) çªç®ã®åãæãï¼ããã¨ã¯å¥ã§è¦ªã¸ã®ãã¤ã³ã¿ãæã£ã¦ã¿ãã¨ãã¾ãããï¼æ¬¡ã®ãããªå³ã«å¯¾å¿ãã¾ãï¼
åãåãé¢ãéã«ï¼åã®åæ°ã«å¯¾ãã¦ç·å½¢ã¨ã対æ°æéããã£ã¦ãã¾ãã¾ããï¼
ããã§ï¼æ¬¡ã®ãããªè¡¨ç¾æ¹æ³ãæ¡ç¨ãã¾ãï¼
å å¼é㯠circularly doubly-linked list ã«ãªã£ã¦ãã¾ãï¼ åãã親ã¸ã¯ãªã³ã¯ãå¼µããã¦ãã¾ããï¼è¦ªããã¯ä»£è¡¨ã®åã«ã®ã¿ãªã³ã¯ãå¼µããã¦ãã¾ãï¼
ããã«ããï¼è¦ªããã®ãªã³ã¯ãå¼µãæ¿ããã®ã¯ï¼ä»£è¡¨ã®åãåãé¢ãã¨ãã®ã¿ã§ãããªãã¾ãï¼
ä»ã®æä½ãå®æ°æéã§è¡ãã¾ããï¼
注æãããã¨
è¦ç´ æ° 1 ã® circularly doubly-linked list ãã¤ããã¨ãï¼é£ã®åã NULL ã¨ãããèªåèªèº«ã¨ãããã¯ã©ã¡ãã§ãããã¨æãã¾ããï¼è¦ç´ æ° 2 ã®ç¶æ ããéã«åé¤ãè¡ãã¨å¾è ã®ç¶æ ã«ãªãã®ã§ï¼æå³ããªãç¶æ ã«ãªã£ã¦ããªããæ°ãã¤ãã¾ãããï¼
説æããã
ã«ãã¼ï¼
ãªããè¨ç®éãªã©ã®è°è«ãã¡ããã¨ããæ¹ãããã£ãã®ãããªãã§ããï¼å²æãã¦ãã¾ãã¾ããï¼ åé ã«ãªã³ã¯ãç½®ããå ã¹ã©ã¤ãã«ã¯æ¸ããã¦ããã®ã§ï¼ãããè¦ãã¨ããããããã¾ããï¼
å²æããããã§ãªã Fibonacci ãã¼ããªã®ãã®èª¬æãã§ãã¦ãã¾ãããï¼è§£æã®éä¸ã§ Fibonacci æ°åãåºã¦ãã¾ãï¼
å®æ¸¬
ããï¼ãã£ãããããã¼ãã¯é ãã¨è¨ããã¾ããï¼
å®éã«è¨æ¸¬ãã¦ç¢ºããã¦ã¿ã¾ãããï¼Dijkstra ãè²¼ãã¨è§£ããåé¡ã¨ãã¦ï¼æ¬¡ã®åé¡ã使ãã¾ãï¼
ã°ã©ã㯠\(3\le n \le 1002\), \(m = n(n-1)\) ã«ãªã£ã¦ããã¨æãã¾ãï¼
å®è¡æéã¯æ¬¡ã®éãã§ãï¼
ã¾ãï¼1268 ms ã®ãã¤ã¯ Fibonacci ãã¼ãã§æ®éã® Dijkstra ãå®è£ ãããã®ã§ãï¼å®ã®æã¡è ãã§ããï¼å®æ°åãéãã¦ã¤ãããã§ãï¼
114 ms ã®ãã¤ã STL ã® std::priority_queue
ã§ãï¼äºåãã¼ããé
åã§è¡¨ç¾ãããã®ã使ããã¦ãã¦ï¼ãã¯ãéãã§ããï¼
41 ms ã®ãã¤ã¯èªåãã¼ãã§ï¼äºåãã¼ãã®é å表ç¾ã«å ãï¼\(O(\log n)\) time 㧠prioritize ããµãã¼ããããã®ã§ãï¼éãã§ããï¼
ãã¦ï¼37 ms ã®ãã¤ã Fibonacci ãã¼ãã«ãã \(O(m+n\log n)\) ã® Dijkstra ã§ãï¼ä¸çªéãã¦ç´ æµã§ããï¼ããããï¼
ä¸ããï¼
— ãã³ã¡ãã (@rsk0315_h4x) October 28, 2019
- STL ã®äºåãã¼ãã® Dijkstra
- Fibonacci ãã¼ãã®æç´ Dijkstra, O(E log V)
- Fibonacci ãã¼ãã® Dijkstra, O(E+V log V)
ãªã¼ãã¼æ¹åãã¦ãå®æ°åã§è² ããæµãã ã¨æã£ã¦ãã®ã§ãããã pic.twitter.com/iiB4RZGKLU
ã¤ãã§ã«æ¿èªæ¬²æ±ãæºãããã¦ãã¼ããã¼ãã§ãï¼
ä»åã¯ããã§ãããã§ãï¼ãã¤ãããã¾ã§ããï¼
*1:ããã§ããçç±ã«ã¤ãã¦ã¯ï¼ãªããè¨ç®éã®è°è«ãã¡ããã¨ããå¿ è¦ãããã¾ãï¼