2011-01-10 30 views
7

Tôi đã liệt kê một số danh sách có số phần tử biến đổi. Mỗi danh sách được sắp xếp, nhưng thuật toán sắp xếp không được biết. Tôi muốn hợp nhất các danh sách thành một danh sách lớn chứa tất cả các danh sách theo cùng một thứ tự, không trùng lặp.Hợp nhất một số danh sách được sắp xếp với trình tự thứ tự không xác định

Example Input:

  1. XS, M, L, XL
  2. S, M, XXL
  3. XXS, XS, S, L

Dự kiến ​​kết quả:

  • XXS, XS, S, M, L, XL, XXL

Kết quả dự kiến ​​thu được bằng cách kết hợp lên các chuỗi đầu vào để có được một kết quả sáp nhập có chứa các yếu tố của mỗi chuỗi đầu vào theo đúng thứ tự như sau:

XS M L XL 
     S M  XXL 
XXS XS S L 
------------------- 
XXS XS S M L XL XXL 

Chức năng cần thông báo, nếu có những yếu tố có vị trí mơ hồ. Ở đây, nó sẽ là XXL (nó có thể ở lại sau khi M, L hoặc XL) và tôi cần phải xác định vị trí của nó bằng tay sau XL (vì ở đây tôi biết thuật toán phân loại và có thể giúp). Tôi đã nghĩ về việc xác định các cặp của mỗi hai phần tử, mỗi cặp theo thứ tự như trong danh sách gốc. Từ này có thể xây dựng danh sách đầy đủ.

+0

Tôi không hiểu cách bạn có thể hợp nhất các danh sách nếu các quy tắc ưu tiên không xác định. –

+0

@TylerDurden Tôi đã chỉnh sửa câu hỏi để hy vọng làm cho nó rõ ràng hơn một chút. cái đó có giúp ích không? – jcsanyi

+0

Không, làm thế nào là nó mà bạn quyết định nơi XXL là liên quan đến L và XL? –

Trả lời

3

Dưới đây là những gì tôi sẽ làm gì:

  1. preprocess các danh sách: tìm ra rằng XXS nhỏ hơn XS là nhỏ hơn so với S là nhỏ hơn so với ... XXL là một [hạn chế vấn đề sự hài lòng] (http://en.wikipedia.org/wiki/Constraint_satisfaction_problem). Loại vấn đề này liên quan đến việc tìm kiếm một thứ tự chính xác trong số tất cả các phần tử đã đưa ra các ràng buộc được xác định trong danh sách gốc.
  2. Tạo ánh xạ hai chiều từ tập {XXS, ..., XXL} đến tập {1, ..., 6}, sau khi bạn đã thực hiện bước 1.
  3. Đối với mỗi danh sách, hãy tạo một danh sách khác theo sử dụng ánh xạ được xác định trong 2.
  4. Sử dụng [loại hợp nhất đã sửa đổi] (http://en.wikipedia.org/wiki/Merge_sort) để kết hợp hai danh sách. Sửa đổi thuật toán kết hợp để nó báo cáo nếu hai mục được so sánh là giống hệt nhau (và bỏ qua một trong các mục được hợp nhất).
  5. Thực hiện bước 4 cho mỗi cặp danh sách cho đến khi có một danh sách.
  6. Sử dụng ánh xạ được xác định trong 2, tạo phiên bản văn bản của danh sách.
+0

Tôi nghĩ rằng bạn cho rằng thứ tự của các phần tử (trong 1.), nhưng nó không được biết đến. Từ danh sách đầu tiên tôi chỉ biết thứ tự của XS, M, L và XL. Từ danh sách thứ hai phải là S Gabriel

+0

Tôi xin lỗi, tôi phải hiểu lầm. Câu đầu tiên của bạn cho biết rằng các danh sách đã được sắp xếp, điều này khiến tôi nghĩ rằng bạn biết danh sách là gì (và do đó biết tất cả các phần tử). Nó có thể là tốt để viết lại câu đầu tiên để nói: "Tôi đã sắp xếp danh sách có nội dung tôi không biết." – Davidann

+0

Ngoài ra, tôi đã cập nhật câu trả lời của mình cho tài khoản về sự hiểu lầm. – Davidann

14

Điều này có thể được giải quyết bằng thuật toán Topological Sort.

Nếu bạn xem mỗi chuỗi đầu vào của bạn là một đường dẫn thông qua biểu đồ được chỉ dẫn, sắp xếp topo sẽ sắp xếp các nút của bạn từ trái sang phải theo cách mà mỗi cạnh được hướng sang phải. Diagram of a directed graph after topological sorting

Các trang wikipedia trên Topological Sorting bao gồm thuật toán này, lần đầu tiên được mô tả bởi Arthur Kahn năm 1962:

L ← Empty list that will contain the sorted elements 
S ← Set of all nodes with no incoming edges 
while S is non-empty do 
    remove a node n from S 
    insert n into L 
    for each node m with an edge e from n to m do 
     remove edge e from the graph 
     if m has no other incoming edges then 
      insert m into S 
if graph has edges then 
    return error (graph has at least one cycle) 
else 
    return L (a topologically sorted order) 

thuật toán này, như viết tay, không thực sự thất bại nếu nó tìm thấy chuỗi mơ hồ, nhưng đó là dễ dàng để thêm bằng cách chèn một dấu kiểm ở đầu vòng lặp, như sau:

... 
while S is non-empty do 
    if S contains more than 1 item 
     return error (inputs are ambiguous) 
    remove a node n from S 
    ... 

Tôi không biết bạn đang làm việc với ngôn ngữ nào, nhưng tôi đã cùng nhau triển khai thực hiện PHP này của khái niệm:

function mergeSequences($sequences, $detectAmbiguity = false) { 

    // build a list of nodes, with each node recording a list of all incoming edges 
    $nodes = array(); 
    foreach ($sequences as $seq) { 
     foreach ($seq as $i => $item) { 
      if (!isset($nodes[$item])) $nodes[$item] = array(); 
      if ($i !== 0) { 
       $nodes[$item][] = $seq[$i-1]; 
      } 
     } 
    } 

    // build a list of all nodes with no incoming edges 
    $avail = array(); 
    foreach ($nodes as $item => $edges) { 
     if (count($edges) == 0) { 
      $avail[] = $item; 
      unset($nodes[$item]); 
     } 
    } 

    $sorted = array(); 
    $curr = '(start)'; 
    while (count($avail) > 0) { 

     // optional: check for ambiguous sequence 
     if ($detectAmbiguity && count($avail) > 1) { 
      throw new Exception("Ambiguous sequence: {$curr} can be followed by " . join(' or ', $avail)); 
     } 

     // get the next item and add it to the sorted list 
     $curr = array_pop($avail); 
     $sorted[] = $curr; 

     // remove all edges from the currently selected items to all others 
     foreach ($nodes as $item => $edges) { 
      $nodes[$item] = array_diff($edges, array($curr));     
      if (count($nodes[$item]) == 0) { 
       $avail[] = $item; 
       unset($nodes[$item]); 
      } 
     } 

    } 

    if (count($nodes) > 0) { 
     throw new Exception('Sequences contain conflicting information. Cannot continue after: ' . join(', ', $sorted)); 
    } 

    return $sorted; 
} 

Bạn có thể gọi hàm như thế này:

$input = array(
    array('XS', 'M', 'L', 'XL'), 
    array('S', 'M', 'XXL'), 
    array('XXS', 'XS', 'S', 'L'), 
); 
echo(join(', ', mergeSequences($input))); 
echo(join(', ', mergeSequences($input, true))); 

Để có được kết quả như sau:

XXS, XS, S, M, XXL, L, XL 
Uncaught exception 'Exception' with message 'Ambiguous sequence: M can be followed by L or XXL' 
+1

Phân loại topo cũng được mô tả tốt trong TAOCP Volume 1. –

6

Bạn đang cố gắng hợp nhất partially ordered sets, hoặc posets. Các phần không rõ ràng của hợp nhất được gọi là antichains. Vì vậy, bạn muốn có một thuật toán kết hợp các vị trí và cho bạn biết các antichains là gì.

Here is a paper describing an algorithm for merging posets and detecting antichains, cũng như link to the first author's homepage trong trường hợp bạn muốn liên hệ với anh ấy để xem có mã nguồn nào không.

+0

Cảm ơn. Thông thường, phần khó nhất về việc tìm kiếm giải pháp là biết đúng thuật ngữ để tìm kiếm. – jcsanyi

-1

Để sắp xếp một phần, tôi cho rằng Sắp xếp hợp nhất là đủ theo mô tả của bạn. Một điều cần sửa đổi là trong quá trình hợp nhất, chúng ta nên bỏ qua các phần tử tại mảng đầu vào nếu phần tử đầu tiên của mảng đầu vào giống với mảng kết quả.

Nếu tôi hiểu chính xác, bạn muốn xây dựng tổng số thứ tự của toàn bộ các yếu tố đầu vào có thể. Một số đơn đặt hàng một phần đã được xác định trong các bản ghi đầu vào (vì chúng đã được sắp xếp), trong khi những thứ khác cần được người dùng chỉ định. Ví dụ trong câu hỏi, trật tự

'S' < 'M' < 'XXL'

'XS' < 'M' < 'L' < 'XL'

'XXS' < ' XS '<' S '<' L '

được xác định rõ. Nhưng thuật toán vẫn không biết liệu 'XXL' lớn hơn hay nhỏ hơn 'XL', 'L'.
Kể từ khi ba bản ghi đầu vào được sắp xếp, phải có tổng số thứ tự của các phần tử đầu vào. Vì vậy, đề nghị của tôi là yêu cầu nhà cung cấp dữ liệu của bạn cho một danh sách theo thứ tự của tất cả các yếu tố dữ liệu có thể. Nghe có vẻ ngu ngốc, nhưng đó là một cách dễ dàng.

Nếu danh sách này không có sẵn, cách dễ dàng để xử lý là nhắc sắp xếp cặp cho người dùng, sau đó kiểm tra xem xung đột này với chuỗi đầu vào hiện tại và nhớ nó, khi thuật toán gặp phải một cặp không rõ ràng. Tôi nghĩ rằng việc phân loại topo mạnh hơn ứng dụng này. Vì chúng ta xử lý các phần tử dữ liệu đơn lẻ, nên phải thoát khỏi tổng số thứ tự. Trong khi topo phân loại là để đối phó với trật tự một phần.

Các vấn đề liên quan