簡體   English   中英

Select 來自一組子集的 n 個項目

[英]Select n items from a set of subsets

我想知道是否存在可以解決此問題的算法:

假設您有一個包含集合的集合,其中每個集合可能有也可能沒有元素,例如,讓集合的可能元素為 1,2 和 3,那么我們將有一個像 {{1, 2,3}{1}{1,2}... } 那么,我如何 select 多個集合,這樣我每個項目都有n 個元素,例如,讓 n=200 那么我想要 200 1s , 200在這個例子中是2s和 200 個3s

在我深入回答之前,有一些疑問句。

假設我們有一個方法 f() 給定一組集合(如您的示例中的那個),它需要找到什么?

如果我們將 n = 3 插入 f(3),它需要找到這樣的集合,使得我們每個項目都有 n 個元素(3 個 1s、3 個 2s 和 3 個 3s)准確嗎? 讓我們假設這種情況。

那么我們方法的 output 應該是滿足上一個問題的集合的子集還是只需要返回我們的子集中的集合數? 例如 f(3) 在一組集合中如下

[[1,2,3][1][1,2][1,2][1,2,3][3]... ]

我們可以看到一個解決方案子集是[[1,2,3][1,2][1,2,3][3]]我們可以返回這個子集,或者更確切地說是這個子集中的集合數,即 4。 (這可能與算法的空間復雜度有關)。

現在對於解決方案,一種朴素的方法可能是這種形式:

  1. 循環遍歷集合。
  2. 對於單個集合中的每個元素,增加一個元素計數器(例如,集合 [1,2] 將 1 和 2 計數器分別增加一個。
    1. 如果其中一個元素計數大於“n”,那么我們不會將該集合考慮到我們的解決方案中。
    2. 否則,將集合考慮到您的解決方案集中。
    3. 無論如何,請再次調用您的方法,但不要考慮前一組。
    4. 如果您發現每個元素都增加了等於“n”的計數器,則返回。

偽代碼將如下所示:

method find_sets(n,sets, sol_sets, element_counters):

    for each set in sets:
        updated_counter = element_counter +  1 for each element in set
        sets = sets.pop(set)

        if for a element in updated_counter > n:
            return method find_sets(n, sets, sol_sets, element_counters)

        else if for any element in updated_counter < n:
            sol_sets.add(set)
            return method find_sets(n, sets, sol_sets, updated_counter)

        else if for every element in updated_counter = n:
            sol_sets.add(set)
            return sol_sets

    # If the solution could not be found
     return None

考慮一組 N 個集合,最壞的情況是循環每個元素,考慮到這是一個遞歸算法,我們可以預期時間復雜度為 n²。

希望這可以為找到更好的解決方案帶來光明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM