Hướng dẫn thuật toán

Trùm CUỐI 2022-01-05 5:22:44 2022-01-06 8:31:41

Emo Welzl đưa ra một thuật toán dùng random như sau: Gọi f(S, T) là đường tròn nhỏ nhất chứa tất cả các điểm trong tập S và T là tập hợp các điểm phải nằm trên đuờng tròn. Điều ta cần tìm là f(S_0, \{\}) trong đó S_0 là tất cả các điểm được cho, \{\} là tập rỗng.

  • Nếu T chứa ba điểm: Trả về đường tròn đi qua ba điểm này.
  • Nếu S rỗng:
    • Nếu T chứa 0 điểm, trả về một đường tròn có bán kính âm (một đường tròn không chứa điểm nào).
    • Nếu T chứa 1 hoặc 2 điểm, trả về đường tròn bé nhất chứa các điểm này.
  • Ngược lại, tức là nếu T chứa 0, 1 hoặc 2 điểm, và S không rỗng:
    • Chọn một điểm I ngẫu nhiên trong S .
      • Nếu I nằm trong đường tròn f(S-\{I\}, T) , trả về f(S-\{I\}, T) .
      • Ngược lại, trả về f(S-\{I\}, T+\{I\}) .

Nhờ việc chọn ngẫu nhiên điểm I trong S , thuật toán này chạy trong O(n) .

Để giảm độ sâu của việc đệ quy (có thể lên đến O(n) nếu cài không tốt), có thể khử đệ quy như sau: Gọi f(n, T) là đường tròn nhỏ nhất chứa tất cả các điểm a[1..n] T là tập hợp các điểm phải nằm trên đuờng tròn. Điều ta cần tìm là f(n, \{\}) trong đó, \{\} là tập rỗng.

Vòng for trong hàm hoạt động như sau:

  1. Result = f(0, T)
  • For i từ 1 đến n :
    • Tóm tắt: Với mỗi i , ta sẽ tính f(i, T) dựa vào Result (hay chính là f(i-1, T) ). Kết quả của f(i, T) sẽ được lưu trở lại vào biến Result. Sau khi vòng for kết thúc, Result chính là f(n, T) .
    • Nếu Result chứa a[i] , ta giữ nguyên Result.
    • Ngược lại, gán Result = f(i-1, T+\{a[i]\})