簡體   English   中英

算法 - 加權間隔調度問題變體

[英]Algorithm - Weighted interval scheduling problem variant

所以我有一個問題如下:

Xzqthpl 是一個居住在不起眼的 Kepler-1229b 行星上的外星人,它距離地球只有 870 光年左右。 無論是在 Tannhäuser 門外看 C 型光束,還是只是前往天狼星曬太陽,Xzqthpl 都喜歡周末去不同的遙遠恆星和星系旅行。 然而,由於宇宙正在膨脹,隨着時間的推移,其中一些遙遠的地方將越來越遠離 Kepler-1129b。 因此,在遙遠的未來的某個時刻,即使像仙女座這樣相對較近的星系也離 Kepler-1229b 太遠,Xzqthpl 無法在那里進行周末旅行,因為來回旅行會花費太多時間。 有可能訪問的“n”個感興趣的地方的列表。 對於每個地方,Xzqthpl 分配了一個值“v_i”來衡量 Xzqthpl 對該地方的興趣程度,以及一個值“t_i”,表示從現在起該地方將太遠而無法訪問的周數。

現在 Xzqthpl 想通過以下方式計划其周末旅行:

  1. 任何地方都不會被多次訪問。
  2. 每周最多訪問一個地方。
  3. 在“t_i”周后未訪問地點“i”
  4. 訪問地點的值“v_i”的總和最大化

設計一個有效的(“n”中的多項式,獨立於 v_i's 和 t_i's 假設單位成本模型)算法來解決 Xzqthpl 的旅行計划問題。

目前我真的不知道從哪里開始。 這感覺像是“加權間隔調度”算法的一個奇怪變體(盡管我不確定)。 有人能給我一些關於從哪里開始的提示嗎?

我最初的想法是按“t_i”升序對列表進行排序……但我不確定在那之后該怎么做(我的想法甚至可能是錯誤的)。

謝謝!

您可以為此使用最小堆:

算法

  1. t i對輸入進行排序
  2. 創建一個空的最小堆,其中將包含保留的v i
  3. 迭代排序后的輸入。 對於每個i
    • 如果t i < 堆大小,則這意味着不能保留該元素,除非另一個先前選擇的元素被踢出。 檢查堆中的最小值是否小於v i 如果是這樣,那么從堆中取出那個最小值,並把這個v i代替是有益的。
    • 否則,只需將v i添加到堆中。
    • 在任何一種情況下,保持堆的總值更新
  4. 返回堆的總值

為什么這有效

這是有效的,因為在每次迭代中,我們都有這個不變量

堆的大小同時代表件事。 它既是:

  • 我們仍然考慮作為最終解決方案的可能候選項目的數量,以及
  • 已過去的周數。

這個想法是堆中的每個項目都被分配到一個星期,所以我們需要與堆中的項目一樣多的星期。

因此,在每次迭代中,我們都嘗試以 1 周為單位進行改進。 但是,如果下一個訪問的項目只能在已經過去的時間段內被允許(即它最后可能的一周是已經過去的一周),那么我們不能像這樣將它添加到堆中,因為有沒有可用的一周。 相反,我們檢查考慮的項目是否會更好地與我們已經選擇(並且在堆中)的項目交換。 如果我們交換它,丟失的那個不能留在堆中,因為現在我們沒有那個可用的一周(記住它的時間限制更加嚴格——我們按照時間限制的順序訪問它們) . 所以無論我們是否交換,堆大小都保持不變。

其次,堆必須是堆,因為我們需要一種有效的方法來始終知道哪個元素的值最小 否則,如果它是一個簡單的列表,我們將不得不在每次迭代中掃描該列表,以便將其值與我們當前正在處理的(並希望可能交換的)進行比較。 顯然,交換只有在堆的總價值增加時才有利可圖。 所以我們需要一種有效的方法來快速找到錯誤的值。 最小堆提供了這一點。

一個實現

這是在 Python 中的一個實現:

from collections import namedtuple
from heapq import heappush, heapreplace

Node = namedtuple("Node", "time,value")

def kepler(times, values):
    n = len(values)
    # Combine corresponding times and values
    nodes = [Node(times[i], values[i]) for i in range(n)];
    nodes.sort() # by time

    totalValue = 0
    minheap = []
    for node in nodes:
        if node.time < len(minheap): # Cannot be visited in time
            leastValue = minheap[0] # See if we should replace
            if leastValue < node.value:
                heapreplace(minheap, node.value) # pop and insert
                totalValue += node.value - leastValue
        else:
            totalValue += node.value
            heappush(minheap, node.value)
    return totalValue

這是它的一些示例輸入:

times = [3,3,0,2,6,2,2]
values =[7,6,3,2,1,4,5]

value = kepler(times, values)
print(value) # 23

時間復雜度

排序將表示O(nlogn)時間復雜度。 盡管可以考慮使用某種基數排序將其降低到O(n) ,但堆的使用也代表了O(nlogn)的最壞情況。 因此該算法的時間復雜度為O(nlogn)

暫無
暫無

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

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