Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Chương trình tìm đường đi có xác suất tối đa bằng Python

Giả sử chúng ta có một đồ thị vô hướng có trọng số với n nút (được đánh số từ 0), đồ thị này được cung cấp dưới dạng danh sách cạnh, mỗi cạnh e có xác suất thành công khi đi qua cạnh đó là probability[e]. Chúng ta cũng có nút bắt đầu và nút kết thúc, nhiệm vụ là tìm đường đi có xác suất thành công lớn nhất từ start đến end và trả về xác suất đó. Nếu không tìm thấy đường đi nào, trả về 0.

Ví dụ, với đầu vào như hình minh họa:

Chương trình tìm đường đi có xác suất tối đa bằng Python

Kết quả sẽ là 0.24 vì có hai đường đi từ nút 0 đến 2: một đường trực tiếp với xác suất 0.2, đường còn lại qua nút 1 có xác suất 0.4 × 0.6 = 0.24, đây là giá trị lớn nhất.

Thuật toán giải quyết

Chúng ta thực hiện theo các bước sau:

  • Xây dựng đồ thị g từ danh sách cạnh, sử dụng xác suất làm trọng số.
  • Khởi tạo hàng đợi q.
  • Đưa cặp (start, 1) vào q (xác suất ban đầu là 1).
  • Sử dụng bản đồ visited để lưu xác suất lớn nhất đã biết đến mỗi nút.
  • Lặp lại cho đến khi q rỗng:
    • Lấy cặp (node, prob) đầu tiên khỏi q.
    • Nếu visited[node] > prob, bỏ qua vòng lặp này.
    • Ngược lại, cập nhật visited[node] = prob.
    • Duyệt qua các nút liền kề adj và xác suất nextProb trong g[node]:
      • Nếu visited[adj] < prob × nextProb, đưa (adj, prob × nextProb) vào cuối q.
  • Trả về visited[end].

Ví dụ triển khai

from collections import defaultdict, deque

def solve(edges, probability, start, end):
    g = defaultdict(list)
    for i in range(len(edges)):
        src, dst = edges[i][0], edges[i][1]
        prob = probability[i]
        g[src].append((dst, prob))
        g[dst].append((src, prob))
    q = deque()
    q.append((start, 1))
    visited = defaultdict(int)
    while q:
        node, prob = q.popleft()
        if visited[node] > prob:
            continue
        else:
            visited[node] = prob
        for adj, nextProb in g[node]:
            if visited[adj] < prob * nextProb:
                q.append((adj, prob * nextProb))
    return visited[end]

edges = [[0,1],[1,2],[0,2]]
probability = [0.5,0.5,0.2]
start = 0
end = 2
print(solve(edges, probability, start, end))

Đầu vào

[[0,1],[1,2],[0,2]], [0.5,0.5,0.2], 0, 2

Đầu ra

0.25