Hướng dẫn update element in priority queue c++ - cập nhật phần tử trong hàng đợi ưu tiên c ++

Tôi có một ưu tiên_queue của một số đối tượng:

typedef priority_queue Queue;
Queue queue;

Thỉnh thoảng, mức độ ưu tiên của một trong các đối tượng có thể thay đổi - tôi cần có thể cập nhật mức độ ưu tiên của đối tượng đó trong hàng đợi một cách hiệu quả. Hiện tại tôi đang sử dụng phương pháp này hoạt động nhưng có vẻ không hiệu quả:

Queue newQueue;
while (!queue.empty())
{
  Object obj=queue.top();
  queue.pop();

  if (priorityHasChanged(obj))
    newQueue.push_back(Object(new_priority));
  else
    newQueue.push_back(obj);
}

newQueue.swap(queue); // this only works because I actually subclassed the priority_queue
                 // class and exposed a swap method that swaps in the container

Tôi đã thực hiện nó theo cách này bởi vì tôi đã rất vội vàng vào thời điểm đó và đây là điều nhanh nhất tôi có thể làm mà tôi có thể chắc chắn rằng nó sẽ hoạt động tốt. Phải có một cách tốt hơn điều này mặc dù. Thực sự những gì tôi muốn là một cách để:

  • Trích xuất phiên bản với mức độ ưu tiên đã thay đổi và chèn một cái mới với giá trị ưu tiên mới
  • Cập nhật thể hiện với mức độ ưu tiên đã thay đổi và sau đó cập nhật hàng đợi để nó được sắp xếp chính xác

Cách tốt nhất để làm việc này là gì?

Đã hỏi ngày 16 tháng 3 năm 2009 lúc 8:31Mar 16, 2009 at 8:31

Hướng dẫn update element in priority queue c++ - cập nhật phần tử trong hàng đợi ưu tiên c ++

1800 Thông tin1800 Thông tin1800 INFORMATION

128K29 Huy hiệu vàng157 Huy hiệu bạc239 Huy hiệu Đồng29 gold badges157 silver badges239 bronze badges

Tôi có thể đề xuất 2 lựa chọn để giải quyết vấn đề, mặc dù không thực hiện cập nhật thực sự.

  1. Sử dụng phần tử priority_queue và đẩy mỗi lần bạn muốn cập nhật nó. Chấp nhận thực tế rằng bạn sẽ có các mục vô dụng trong hàng đợi. Khi bật giá trị hàng đầu, hãy kiểm tra xem nó có chứa giá trị cập nhật không. Nếu không, hãy bỏ qua nó và bật tiếp theo.

    Bằng cách này, bạn trì hoãn việc loại bỏ phần tử được cập nhật cho đến khi đến đầu. Tôi nhận thấy phương pháp này được sử dụng bởi các lập trình viên hàng đầu nhận ra thuật toán Dijkstra.

  2. Sử dụng 4. Nó cũng được sắp xếp để bạn có thể trích xuất yếu tố lớn nhất trong thời gian logarit. Bạn cũng có thể loại bỏ phần tử lỗi thời trước khi chèn lại. Vì vậy, vẫn không có hoạt động cập nhật có thể, nhưng loại bỏ và tái cấu trúc là có thể thực hiện được.

Có vẻ như sự phức tạp của cả hai phương pháp là như nhau.

Đã trả lời ngày 23 tháng 12 năm 2012 lúc 8:56Dec 23, 2012 at 8:56

5

Tôi nghĩ rằng bạn không may mắn với hàng đợi ưu tiên tiêu chuẩn vì bạn không thể nhận được ở các deque/vector/danh sách cơ bản hoặc bất cứ điều gì. Bạn cần phải thực hiện của riêng bạn - nó không khó lắm.

Đã trả lời ngày 16 tháng 3 năm 2009 lúc 9:09Mar 16, 2009 at 9:09

2

Tôi đã triển khai hàng đợi ưu tiên cập nhật hiệu suất cao và cung cấp nó trên GitHub.

Đây là cách bạn thường sử dụng nó:

better_priority_queue::updatable_priority_queue pQ;
pQ.push(0, 30);   // or pQ.set(0, 30)
pQ.push(1, 20);
pQ.push(2, 10);

pQ.update(2, 25); // or pQ.set(2, 25)

while(!pQ.empty())
    std::cout << pQ.pop_value().key << ' ';

// Outputs: 0 2 1

Để bổ sung cho câu trả lời của Jarekczek, nếu thực sự cả các phương pháp set và "Heap Pure với các mục vô dụng" đều có cùng độ phức tạp, phiên bản stl::set thường hoạt động chậm hơn nhiều so với phiên bản stl::priority_queue do thực tế là nó được thực hiện với Đảm bảo độ sâu của chúng thấp hơn 2*log_2 (n_elements) và yêu cầu cập nhật thường xuyên, trong khi stl::priority_queue là một đống nhị phân nhanh và tinh khiết càng tốt. Đây là lý do tại sao nó thường được sử dụng khi thực hiện Dijkstra.

Tuy nhiên, cách tiếp cận có thể nhanh hơn khi thực hiện nhiều bản cập nhật trên một vài nút cơ sở. Đây cũng là nơi sử dụng thư viện của tôi sẽ mang lại cho bạn sự cải thiện nhất.

Đã trả lời ngày 9 tháng 12 năm 2018 lúc 23:53Dec 9, 2018 at 23:53

LềuTen

1.1138 huy hiệu bạc12 Huy hiệu đồng8 silver badges12 bronze badges

Cấu trúc dữ liệu thích hợp được gọi là "Fibonacci Heap". Nhưng bạn cần phải tự thực hiện nó. Chèn/cập nhật là O (1) Trích xuất là o (logn)

Đã trả lời ngày 20 tháng 7 năm 2010 lúc 20:19Jul 20, 2010 at 20:19

NimanimaNima

8533 Huy hiệu vàng10 Huy hiệu bạc18 Huy hiệu đồng3 gold badges10 silver badges18 bronze badges

1

Cách đơn giản nhất để làm điều này với STL (mà tôi biết) là xóa mục nhập, cập nhật mức độ ưu tiên của nó và sau đó đặt lại nó. Làm điều này khá chậm bằng cách sử dụng std :: ưu tiên_queue, tuy nhiên bạn có thể làm điều tương tự với std :: set. Thật không may, bạn phải cẩn thận để không thay đổi mức độ ưu tiên của một đối tượng khi nó ở trong tập hợp.

Tôi đã thực hiện một lớp dựa trên lớp Mutable_priority_queue với nhau một std :: multimap (ưu tiên lập bản đồ giá trị) và bản đồ STD :: (cho giá trị để ánh xạ ưu tiên) cho phép bạn chèn/xóa thời gian. Bạn có thể lấy mã và một ví dụ về cách sử dụng nó ở đây

Đã trả lời ngày 6 tháng 2 năm 2010 lúc 21:34Feb 6, 2010 at 21:34

2

Bạn có thể muốn có một cái nhìn về replace_if với một ví dụ ở đây.

Đã trả lời ngày 16 tháng 3 năm 2009 lúc 8:46Mar 16, 2009 at 8:46

Dubndedubndedubnde

4.2999 Huy hiệu vàng41 Huy hiệu bạc63 Huy hiệu Đồng9 gold badges41 silver badges63 bronze badges

1

Thật không may, bạn không thể cập nhật giá trị trong ưu tiên_queue. ưu tiên_queue không cung cấp giao diện như vậy.

Tôi nghĩ rằng bạn nên sử dụng set như Jarekczek đã nói hoặc sử dụng giải pháp này (sử dụng Make_Heap).

Đã trả lời ngày 2 tháng 1 năm 2017 lúc 1:06Jan 2, 2017 at 1:06

Làm thế nào để bạn cập nhật một yếu tố hàng đợi ưu tiên?

Để cập nhật mức độ ưu tiên trong hàng đợi ưu tiên, hãy lấy chỉ mục của phần tử mà bạn muốn cập nhật mức độ ưu tiên và gán khóa mới cho phần tử. Sau khi cập nhật mức độ ưu tiên của một yếu tố, chúng ta cần phải tăng nhiệt để duy trì cấu trúc dữ liệu heap.get the index of the element that you want to update the priority of and assign a new key to the element. After updating the priority of an element, we need to heapify the heap to maintain the heap data structure.

Làm cách nào để cập nhật hàng đợi ưu tiên của tôi trong STL?

7 câu trả lời..
Sử dụng phần tử Priority_queue và đẩy mỗi khi bạn muốn cập nhật nó.Chấp nhận thực tế rằng bạn sẽ có các mục vô dụng trong hàng đợi.Khi bật giá trị hàng đầu, hãy kiểm tra xem nó có chứa giá trị cập nhật không.....
Sử dụng bộ.Nó cũng được sắp xếp để bạn có thể trích xuất yếu tố lớn nhất trong thời gian logarit ..

Làm thế nào bạn có thể đặt ưu tiên cho các yếu tố trong hàng đợi ưu tiên?

Trong một hàng đợi ưu tiên, nói chung, giá trị của một phần tử được xem xét để gán mức độ ưu tiên.Ví dụ: phần tử có giá trị cao nhất được gán ưu tiên cao nhất và phần tử có giá trị thấp nhất được gán ưu tiên thấp nhất.the value of an element is considered for assigning the priority. For example, the element with the highest value is assigned the highest priority and the element with the lowest value is assigned the lowest priority.

Chúng ta có thể loại bỏ yếu tố cụ thể trong hàng đợi ưu tiên không?

Phương thức loại bỏ () của lớp ưu tiên của gói java.util được sử dụng để loại bỏ một phần tử cụ thể khỏi ưu tiên. util package is used to remove a particular element from a PriorityQueue.