簡體   English   中英

資源分配算法

[英]Resource allocation algorithm

我知道算法存在,但我在命名它並找到合適的解決方案時遇到了問題。

我的問題如下:

  • 我有一組需要完成的J作業。

  • 所有工作都需要不同的時間來完成,但時間已知。

  • 我有一套R資源。

  • 每個資源R可以具有1到100個實例中的任何數字。

  • 作業可能需要使用任意數量的資源R.

  • 作業可能需要使用資源R的多個實例,但從不超過資源R具有實例。 (如果資源只有2個實例,則作業永遠不會超過2個實例)

  • 作業完成后,它會將其使用的所有資源的所有實例返回到池中,以供其他作業使用。

  • 一旦開始工作就不能被搶占。

  • 只要資源允許,對可以同時執行的作業數量沒有限制。

  • 這不是有向圖問題,作業J可以按任何順序執行,只要它們可以聲明其資源即可。

我的目標:安排作業以最小化運行時間和/或最大化資源利用率的最佳方式。

我不確定這個想法有多好,但您可以將其建模為整數線性程序,如下所示(未經測試)

定義一些常量,

Use[j,i] = amount of resource i used by job j
Time[j] = length of job j
Capacity[i] = amount of resource i available

定義一些變量,

x[j,t] = job j starts at time t
r[i,t] = amount of resource of type i used at time t
slot[t] = is time slot t used

限制是,

// every job must start exactly once
(1). for every j, sum[t](x[j,t]) = 1
// a resource can only be used up to its capacity
(2). r[i,t] <= Capacity[i]
// if a job is running, it uses resources
(3). r[i,t] = sum[j | s <= t && s + Time[j] >= t] (x[j,s] * Use[j,i])
// if a job is running, then the time slot is used
(4). slot[t] >= x[j,s] iff s <= t && s + Time[j] >= t

第三個約束意味着如果作業最近啟動到足以使其仍在運行,則其資源使用將添加到當前使用的資源中。 第四個約束意味着如果作業最近啟動到足以使其仍在運行,則使用此時隙。

目標函數是時隙的加權和,后續時隙的權重較高,因此它更喜歡填充早期時隙。 從理論上講,權重必須以指數方式增加,以確保使用較晚的時隙總是比僅使用較早時隙的任何配置更差,但解算器不喜歡這樣,實際上你可能會使用增長較慢的權重。

你需要足夠的插槽以便存在解決方案,但最好不要超過你最終需要的數量,所以我建議你從一個貪婪的解決方案開始,給你一個有希望的時間上限的非平凡上限(顯然還有所有任務的長度總和)。

有很多方法可以獲得貪婪的解決方案,例如,只需在最早的時間段內逐個安排作業。 通過某種程度的“硬度”對它們進行排序可能會更好,並將硬質量放在第一位,例如你可以根據它們使用資源的程度給出一個分數(比如, Use[j,i] / Capacity[i]的總和Use[j,i] / Capacity[i] ,或者可能是最大值?誰知道,嘗試一些事情)然后按降序排序。

作為獎勵,你可能並不總是必須解決完整的ILP問題(這是NP難的,所以有時可能需要一段時間),如果你只解決線性松弛(允許變量采用小數值,而不僅僅是0或者1)你得到一個下限,而近似的貪婪解決方案給出了上限。 如果它們足夠接近,您可以跳過昂貴的整數階段並采取貪婪的解決方案。 在某些情況下,如果線性松弛的舍入目標與貪婪解決方案的目標相同,這甚至可以證明貪婪解是最優的。

這可能是Dykstra算法的一項工作。 對於您的情況,如果您想最大化資源利用率,那么搜索空間中的每個節點都是將作業添加到您將立即執行的作業列表的結果。 然后,邊緣將是您將作業添加到您將要執行的作業列表時剩余的資源。

那么,目標是找到具有作為最小值的入射邊緣的節點的路徑。

另一種更直接的選擇是將其視為背包問題

要將此問題構建為背包問題的實例,我將執行以下操作:

假設我有J個作業, j_1, j_2, ..., j_nR資源,我想找到J的子集,這樣當調度該子集時, R被最小化(我將其稱為J' )。

在偽代碼中:

def knapsack(J, R, J`):
  potential_solutions = []
  for j in J:
    if R > resources_used_by(j):
      potential_solutions.push( knapsack(J - j, R - resources_used_by(j), J' + j) )
    else:
      return J', R
  return best_solution_of(potential_solutions)

暫無
暫無

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

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