嗯,這裏是也許是最簡單的方法,我可以理解你的問題的解決方案:
讓我們假設每個項目,我們考慮兩種可能性:
我們在放置其意位置(間隔即中心)
我們不
然後,我們可以將這個問題重新表達爲以下函數:找到可以放置在它們間隔中心而不重疊的項目的最大子集合。
這似乎是應該有一個貪婪的解決方案,但我必須承認,我能做的最好的是想出一個非常天真的動態編程算法。這裏是我如何制定的重現:
假設我們正在考慮第n個項目(從左邊開始),並且我們要分配它,使得此項目的左邊緣不會通過右邊的最前面所有前面的項目。然後,它必須是真正的最佳分配滿足:
best_align(n, right) =
if center[n]-radius[n] > right[n]:
max(best_align(n+1, right+radii[n], 1+best_align(n+1,center[n]+radius[n])
else:
best_align(n+1, right+radius[n])
這有一個明顯的DP解決方案,我編碼了(在Python中)。結果如下:
#Assumes that the items are sorted left-to-right by their centers
def best_align(radii, centers):
assignments = { (radii[0]+centers[0]):[0], (-100000):[] }
for i in range(1, len(radii)):
nc = centers[i] + radii[i]
nassignments = { nc : [i] }
for right, assigned in assignments.items():
#Handle case where object is not inserted
nr = right+radii[i]
if not nr in nassignments or len(assigned) > len(nassignments[nr]):
nassignments[nr] = assigned
#Handle inclusion case
if right <= centers[i]-radii[i] and len(assigned) >= len(nassignments[nc]):
nassignments[nc] = assigned + [i]
assignments = nassignments
return max([ (len(l), l) for l in assignments.values() ])[1]
可變半徑是各種項目的半徑,而中心是目標分配位置。該算法返回可放置在期望位置的項目的最大子集。剩下的項目必須儘可能地儘可能地被模糊。例如,這裏有一些輸出:
在[11]:plc.best_align([1,5,1],[0,2,3])
缺貨[11]:[2 ]
又如:
在[18]:plc.best_align([1,10,1,1,1,1,1],[0,2,4,6, 8,10,12])
Out [18]:[2,3,4,5,6]
這個實現的時間複雜度是三維的,因爲處理這些分配集合的方式很幼稚。人們可以很容易地優化,通過將python列表替換爲之前列出的列表(儘管它會使演示文稿更加糟糕)來獲得二次方案。
考慮兩個項目,(a = 0-10)和(b = 1-2),哪個應該先到? –
只需觀察一下問題:由於間隔不重疊,而且您願意將項目移出間隔,所以間隔似乎並不重要,只有他們的中心纔會這樣做。你可以只爲每個物品提供一個「理想位置」的問題,並說你想要訂單保存等。 – ShreevatsaR
@ShreevatsaR:你是對的;我懷疑OP比他們提到的更受期望的限制。要麼是這個,要麼是爲了確定他們是否能夠掌握你的精確點而設計的作業。 –