• 沒有找到結果。

隨機算法

N/A
N/A
Protected

Academic year: 2022

Share "隨機算法"

Copied!
61
0
0

加載中.... (立即查看全文)

全文

(1)

隨機算法

by boook

Hash Credit by qazwsxedcrfvtg14

(2)

大綱

• When

• 為甚麼、何時要用隨機

• How

• 如何產生隨機的數字

• Hash

• 隨機選擇

• Algorithm

• 最近點對

(3)

為甚麼、何時要用隨機

• 模板很難寫

• 大家都喜歡唬爛

• AC 的效率 vs 出題者的良心

• 在題目限制很寬的時候

• 當出題者的題目出壞掉的時候

(4)

用隨機的後果

• 影響正確率

• 可能程式不總是正確

• -> 讓程式錯誤的機率特別低

• 影響執行時間

• 執行時間不固定

• -> 讓程式期望執行的時間不長

(5)

如何產生隨機的數字

• 大家都會??

• rand()

• srand(time(0))

• 這樣足夠安全嗎?

(6)

哪裡不安全

• 大家都會??

• rand()

• srand(time(0))

• 這樣足夠安全嗎?

(7)

哪裡不安全

(8)
(9)

不要直接使用 rand()

• rand() 在 windows 上預設的回傳範圍為 [0, 65535]

• 解決方法:

• rand() 很多次後將結果拼接成比較大的數字

• 用其他亂數產生器,如 mt19937

• 追求更快效率 -> 自己寫亂數

(10)

使用 mt19937

(11)

自己設計 random function

(12)

自己設計 random function

(13)

暖身-計算隨機正確率

(14)

Hash

(15)

Hash

• 目的:

• 將一個物品的很多資訊壓縮起來,當要判斷兩個物品是否相同時 就判斷兩個物品分別壓縮後的結果是否相同。

• 壓縮過程中會失去一些資訊,因此可能會有兩個不同的物品被 壓縮後產生一樣的結果。

• 如果有兩個物品 A, B ,以及壓縮函數 f

• 錯誤的機率:

• f(A) != f(B),但 A = B。 => 不可能

• f(A) = f(B),但 A != B。 => 錯誤的機率

(16)

Hash

• 譬如:

• f(x) = x % 2

• 所以我們會認為:

• 1 != 2, 因為 1 = f(1) != f(2) = 0

• 2 = 2, 因為 0 = f(2) = f(2) = 0

• 但是我們會認為:

• 4 = 2, 因為 0 = f(4) = f(2) = 0

(17)

f(A) = f(B),但 A != B

• 好的 hash function 要滿足「碰撞」

的機率足夠小,也就是

f(A) = f(B),但 A != B 的機率。

• P(f(A) = f(B),但 A != B) < 1e-9

• 當錯誤的機率「足夠小」,那麼就可以

「假裝」hash function 不會碰撞

• 有時候 1e-9 仍然不夠,需視情況調整

• 生活上的例子 (checksum)

(18)

Hash table

• 可以構造讓 hash table 變得非常慢

,但在隨機的 使用下,

insert、

delete 都是 O(1)。

(19)

Hash 的安全性

• 對於一個 hash function x -> f(x) 有三種等級的安全性:

• Preimage attack:

• 知道 f(x) 還原出 x

• Second preimage resistance:

• 在知道 f(x) 的情況下,找到另一組 y -> f(y) = f(x)

• collision resistance:

• 找到一對 a, b 使得 f(a) = f(b)

(20)

Hash 的安全性 - 生日悖論

• 一個房間要多少人,則兩個人的生日相同的機率大於 50%?

• 23人

• 有 n 個人,每人都隨機地從 N 個特定的數中選擇出來一個數。

• p(n) = 有兩個人選擇了同樣的數字。

• 這個機率有多大?

(21)

Rolling hash

• 又稱 RK 算法(Robin-Karp Algorithm)

• 核心

• 也可以用來當作亂數產生器

(22)

Rolling hash - 如果 C = 10

• S = 21334531

• M = 10000000000000000000000000000000000000000000

• H(1) = 2

• H(2) = 21

• H(3) = 213

• H(4) = 2133

• H(5) = 21334

• H(6) = 213345

• H(7) = 2133453

• H(8) = 21334531

(23)

Rolling hash

• 假設你有一個字串,且你已經知道其hash值

• 下列哪些操作可以O(1)執行?

• 加一個字元在前面

• 加一個字元在後面

• 從前面刪除一個字元

• 從後面刪除一個字元

(24)

Rolling hash

• 可以把Rolling hash想像成一個前高後低三角形

• H(1) = 2

• H(2) = 21

• H(3) = 213

• H(4) = 2133

• H(5) = 21334

(25)

Rolling hash

• 兩個hash接起來

• 一個字元也可以 算是一個hash

*𝐶

𝑏

• S = 213

• P = 123

• H(S) = 213

• H(P) = 123

• H(S+P)

= 213 * 1000 + 123

(26)

Rolling hash

• 刪除前面的字元

*𝐶

𝑏

• S = 12345

• H(S) = 12345

• 12345 – 12000

= 345

(27)

Rolling hash

• 刪除後面的字元

*𝐶

−𝑏

模逆元

• S = 12345

• H(S) = 12345

• (12345 – 45) / 100

= 123

• 8 / 2 != 2 / 2 (mod 6)

(28)

Rolling hash

• 因為這些性質

• 我們經常會預處理好字串每個前綴的Rolling hash

(29)

Rolling hash

• 這樣之後就能直接算出任意一段的hash值

• S = 21334

• H(1) = 2

• H(2) = 21

• H(3) = 213

• H(4) = 2133

• H(5) = 21334

• H(3~4)

= H(4) – H(2) * 100 = 33

(30)

例題 - 怎麼訂 hash 值

• 給一個矩陣大小為 N * N

• Q 次詢問兩個大小相同的子矩陣是否相同。

• N <= 5000

• Q <= 500000

• hash 可不可以推廣到二維?

(31)

二維 hash

(32)

例題 – 怎麼訂 hash 值

• 假設兩個字串相似的定義如下

• 如果存在一個字元的置換方式,使得兩個字串相等,則這兩個字串相似

• 例:

• AAA=BBB

• XYX=ABA

• ABA!=AAA

• 問1:給你字串集 A 和字串 B ,A 中有多少字串和 B 相似?

• 問2:給你一個字串 C,Q 次問兩段區間是否相似?

• Sum(|Ai|), |A|, |B| < 10^6, C, Q <= 10^6

(33)

例題 – 矩陣相成的結果

• 給定三個大小為 N 的 N × N 矩陣 A、B、C,請問 A × B = C 是否成立?

• N <= 1000

• 直接做是 O(N^3)

• 能不能更快一點?

(34)

例題 – 矩陣相成的結果

• 讓 R 是一個 N × 1 的矩陣,那麼只需要檢查

• ((A×B))=(C)

• ((A×B)×R)=(C×R)=C′

• (A×(B×R))=(C×R)=C′

• 乘法個過程中與字串 hash 做的 事情相同

(35)

例題 – 成雙成對

• 給出一個 N 個數字的序列 a_1, a_2, …, a_n。現在 有 Q 個詢問,每次詢問會給出 l, r,請問如果考慮 a_l, …, a_r 是否每種數字都出現偶數次?

• N <= 1,000,000

• Q <= 1,000,000

(36)

例題 – 成雙成對

• XOR 好性質:

• X ⊕ Y ⊕ Z ⊕ Y ⊕ X ⊕ Z = 0

• XOR 不夠好性質:

• 1 ⊕ 2 ⊕ 3 = 0

• One time pad:一次性密碼本

• N 個 ∈ [0, 2^k) 的隨機數字 XOR 起來的結果是隨機的

• 隨機將 a_i 映射成一個隨機的大數字

• 每次錯誤率 1 / (2^k),讓 k = 60

(37)

例題 – 成堆成堆

• 給出一個 N 個數字的序列 a_1, a_2, …, a_n。現在 有 Q 個詢問,每次詢問會給出 l, r,請問如果考慮 a_l, …, a_r 是否每種數字都出現 K 的倍數次?

• N <= 1,000,000

• Q <= 1,000,000

(38)

例題 – 成堆成堆

• 設計一個 hash function

• XOR 可以 加法也可以

• 只要滿足:

• 答案是 YES 的時候一定判斷得出來

• 答案是 NO 的時候有很低的機率會錯

(39)

例題 – 成堆成堆

• 設計一個 hash function:加法

• 改成在模 p 底下做事情避免溢位

• 單筆詢問答對機率: 1 / p

1 1 1 1 1 1 1

x x -2x x x -2x x

1 1 2 1 3 1 2 2 2 3

x x y -2x z x y -2y y z

(40)

例題 – 長度為 8 的簡單路

• 給 N 點 M 邊的有向圖,並給出兩點 S 和 T

• 請找一條 S 到 T 且含頭尾恰經過 8 個點的簡單路徑

• 簡單路徑:路徑中不存在兩個相同的點

• 1 <= N <= 100, 1 <= M <= 2000

(41)

例題 – 長度為 8 的簡單路

• 也就是說不含頭尾一共 6 個點 => O(n^6)

• 問題在簡單路徑上,不然就可以?

• 為什麼不是簡單路徑就可以做

(42)

例題 – 長度為 8 的簡單路

• 也就是說不含頭尾一共 6 個點 => O(n^6)

• 問題在簡單路徑上,不然就可以?

• 為什麼不是簡單路徑就可以做

• Dp[point][step] = True or false

(43)

例題 – 長度為 8 的簡單路

• 那如果現在點上面有顏色呢

• 給 N 點 M 邊的有向圖,並給出兩點 S 和 T。

圖上除了 S 和 T 之外每個點 i 都被塗上了顏色 C_i。

請找一條 S 到 T 且含頭尾恰經過 8 個點的簡單路徑,

並在路上蒐集滿 6 種不同的顏色

• 1 <= N <= 100, 1 <= M <= 2000, 0 <= C_i <= 5

(44)

例題 – 長度為 8 的簡單路

• 給 N 點 M 邊的有向圖,並給出兩點 S 和 T。

圖上除了 S 和 T 之外每個點 i 都被塗上了顏色 C_i。

請找一條 S 到 T 且含頭尾恰經過 8 個點的簡單路徑,

並在路上蒐集滿 6 種不同的顏色

• 1 <= N <= 100, 1 <= M <= 2000, 0 <= C_i <= 5

• Dp[point][bit_mask] = True or False

• O(point × bit_mask) × O(轉移) = O(2^6 M)

(45)

例題 – 長度為 8 的簡單路

• 如果點有顏色多好 => 自己上色

• 隨機把每個點塗上 C_i = 𝑥 ∈ 0, 5

• 至少多少機率會答對:

• 如果只有一條符合條件的路徑

• 中間六個點的顏色都要不一樣: 6!

• 總方法數量: 66

• 隨機一次會答錯的機率: 1 − 6!

66

(46)

例題 – 長度為 8 的簡單路

(47)

隨機選擇

• How:

• 字面上的意思

• 隨機選擇一條路 => 估計答對的機率

(48)

隨機選擇 - 例題

• 給定 N 個二為平面上面的點,請問有沒有一條通過至少 k % 的直線?

• 2 <= N <= 2 × 106

• k >= 20

(49)

直觀的想法

• 直觀的想法

• 1. 隨機兩個點 𝑎, 𝑏

• 2. 檢查有多少個點在 𝑎, 𝑏 兩點構成的直線上面

• 3. 做很多次

• 重複隨機選擇 𝑎, 𝑏 兩點 50 次,錯誤率

1 − 20% × 20% 50 ≈ 12.98%

(50)

隨機少一點「維度」

• 1. 隨機一個點 𝑎

• 2. 以 𝑎 點作為圓心的極角進行排序

• 3. 做很多次

• 重複隨機選擇 𝑎 點 40 次,錯誤率

1 − 20% 40 ≈ 0.013%

(51)

錯排數 (Derangement)

• 錯排數 DN :滿足對於所有的1 ≤ 𝑖 ≤ 𝑁 ,𝐴𝑖 ≠ 𝑖 這樣的 permutation

• DN/ N! ≈ 1/𝑒 ≈ 0.367879

• 也就是說有大概 1/3 的機率隨機一個 permutation 可以隨機 到一個 Derangement。

(52)

隨機選擇 - 例題 CF330E

• 給出一張 𝑁 個點 M 條邊的無向圖,並且圖上保證每個點最多 只接了兩條邊,請構造出一張新圖滿足以下條件,若無解則輸出

− 1 :

• 新圖上與原圖有相同數量的點和相同數量的邊。

• 圖上保證每個點最多只接了兩條邊。

• 對於圖上兩個點 𝑢, 𝑣 ,若在原圖上這兩點之間存在一條邊,則在新圖上 這兩點之間必定沒有邊。

1 ≤ 𝑀 ≤ 𝑁 ≤ 105

(53)

隨便做?

• 把圖的編號隨機打亂 => 做完了!

• 估計錯誤率 => 想想看什麼樣的測資容易錯

• 題意裡面的圖為很多環和很多鍊

• 加一條邊 = 加上一個限制 (很多環)

• 很多連通塊會導致條件被獨立分開

• 圖是一個很大的環

• 拓展錯排數:滿足對任意的相鄰的兩數字差不是 1 或 N – 1 條件的排列 p_1, p_2, ..., p_n

(54)

性質

• 滿足條件的排列 / N! = 𝑒−2

• (1−𝑒−2)90 ≈ 2.07×10−6

• 可以寫個簡單的程式估計一下:滿足條件的排列 / N!

(55)

最近點對

(56)

最近點對

• 給定 N 個二維平面上面的點,請找出距離最近的兩個點。

• 1 <= N <= 10^5

• 傳說做法?旋轉排序

(57)

• 1. 把 N 個點平移到第一象限

• 2. 把 N 個點的順序隨機打亂,d = dis(𝑎1, 𝑎2)

• 3. 以 𝑟 = 𝑑/2 的大小將二維平面切成網格狀,並將這些網格也 以座標表示:點 (𝑥, 𝑦) 會落入座標為 (𝑥

𝑟 , 𝑦

𝑟)

• 不會有兩個點在同一個格子內

最近點對

(58)

• 4. 一直把點加進網格中

• 如果產生新的最近點對一定會出現在以某個點為中心的 5 × 5 宮格內

d/2~d d/2~d d/2~d d/2~d d/2~d d/2~d 0~d/2 0~d/2 0~d/2 d/2~d d/2~d 0~d/2

某個點

0~d/2 d/2~d d/2~d 0~d/2 0~d/2 0~d/2 d/2~d d/2~d d/2~d d/2~d d/2~d d/2~d

最近點對

(59)

• 5.找到更近的最近點對:

• 更新 r = 新的最近點對 / 2

• 回到步驟三重來 O(i+1)

最近點對

(60)

• 期望複雜度

• 令 𝑑𝑖 為考慮 𝑎1, 𝑎2, … , 𝑎𝑖 這些點的最近點對距離。

• 當加入點 𝑎𝑖+1 時,出現一個 𝑎𝑗 使得 (𝑎𝑗, 𝑎𝑖+1) 是新的最近點對的機 率為:

• 𝑃 𝑑𝑖𝑠 𝑎𝑗, 𝑎𝑖+1 < 𝑑𝑖 = 𝑖

𝐶2𝑖+1 = 𝑖×2

𝑖×(𝑖+1) = 2

𝑖+1

• 出現一個 𝑎𝑗 要付出的時間代價: O 𝑖 + 1

• 每加入一個點考慮期望複雜度為 機率 × O(代價) = 2

𝑖 + 1 × 𝑖 + 1 = 2 = 𝑂(1)

• 總共要加 N 個點 => O(N)

最近點對

(61)

• End

參考文獻

相關文件

機器人、餐飲服務、花藝、雲端運算、網路安全、3D 數位遊戲藝術、旅 館接待、行動應用開發、展示設計、數位建設

作為 19 世紀最傑出的藝術家,梵高熱愛生活卻倍 感艱辛。他的畫像目光鮮明,紅髮、紅鬍子、稜角 分明的臉,浮現躁鬱不安的心情,從畫作中看到他

微算機原理與應用 第6

從右邊的食品清單 中,為你自己設計三 份早餐和三份小食。..

• 一個簡單有效的 Hash function,又稱 RK 算法 (Rabin- Karp Algorithm/ Rabin fingerprint ).

錯排數

自己設計 random function 自己設計 random function... 自己設計 random function 自己設計

自己設計 random function.. 自己設計