[英]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 想通過以下方式計划其周末旅行:
- 任何地方都不會被多次訪問。
- 每周最多訪問一個地方。
- 在“t_i”周后未訪問地點“i”
- 訪問地點的值“v_i”的總和最大化
設計一個有效的(“n”中的多項式,獨立於 v_i's 和 t_i's 假設單位成本模型)算法來解決 Xzqthpl 的旅行計划問題。
目前我真的不知道從哪里開始。 這感覺像是“加權間隔調度”算法的一個奇怪變體(盡管我不確定)。 有人能給我一些關於從哪里開始的提示嗎?
我最初的想法是按“t_i”升序對列表進行排序……但我不確定在那之后該怎么做(我的想法甚至可能是錯誤的)。
謝謝!
您可以為此使用最小堆:
這是有效的,因為在每次迭代中,我們都有這個不變量:
堆的大小同時代表兩件事。 它既是:
這個想法是堆中的每個項目都被分配到一個星期,所以我們需要與堆中的項目一樣多的星期。
因此,在每次迭代中,我們都嘗試以 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.