[英]Weighted Interval Scheduling problem & Dynamic program
我的問題與其他討論有關 。
我正在嘗試使用動態程序來實現該算法的遞歸調用。
問題陳述:
作業j從sj
開始,在fj
結束,並且具有權重或值vj
。
如果兩個作業不重疊,則它們兼容。
目標:找到相互兼容工作的最大權重子集。
書籍提出的解決方案是使用解決方案表來存儲所有替代,在遞歸迭代調用中需要時將重用這些替代。
解決問題的步驟是:
Input: n, s1,...,sn , f1,...,fn , v1,...,vn
Sort jobs by finish times so that f1 > f2 >... > fn.
Compute p(1), p(2), ..., p(n)
Where p(j) = largest index i < j such that job i is compatible with j.
for j = 1 to n
M[j] = empty <-- solution table
M[j] = 0
M-Compute-Opt(j) {
if (M[j] is empty)
M[j] = max(wj + M-Compute-Opt(p(j)), M-Compute-Opt(j-1))
return M[j]
}
這是我的代碼(相關部分):
全局變量
typedef struct {
long start, stop, weight;
} job;
/* job array */
job *jobs;
/* solutions table */
long *solutions;
/* P(j) */
long *P;
-按完成時間排序作業,以便f1> f2> ...> fn
int compare(const void * a, const void * b) {
const job *ad = (job *) a;
const job *bd = (job *) b;
return (ad->stop - bd->stop);
}
//Jobs is filled above by parsing a datafile
qsort(jobs, njobs, sizeof(job), compare);
計算p(1),p(2),...,p(n)其中p(j)=最大索引i <j,以使作業i與j兼容。
/*bsearch for finding P(J) */
int jobsearch(int start, int high){
if (high == -1) return -1;
int low = 0;
int best = -1;
int mid;
int finish;
while (low <= high){
mid = (low + high) /2 ;
finish = jobs[mid].stop;
if (finish >= start){
high = mid-1;
}else{
best = mid;
low = mid + 1;
}
}
return best;
}
int best;
for (i = 0; i < njobs; i++){
solutions[i] = -1l; //solutions table is initialized as -1
best = jobsearch(jobs[i].start,i-1);
if (best != -1)
P[i] = best;
else
P[i] = 0;
}
M-計算-OPT(J):
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
/**
* The recursive function with the dynamic programming reduction
*/
long computeOpt(long j) {
if (j == 0)
return 0;
if (solutions[j] != -1l) {
return solutions[j];
}
solutions[j] = MAX(jobs[j].weight + computeOpt(P[j]), computeOpt(j - 1));
return solutions[j];
}
long res = computeOpt(njobs-1);
printf("%ld\n", res);
我針對具有大數據(從10k到1m隨機生成的作業集)的幾個測試用例運行程序,將我的輸出與預期結果進行比較。 在某些情況下,它會失敗。 有時我的輸出會比預期結果大一點,有時會比預期結果小一點。 我顯然缺少一些東西。 請注意,在大多數情況下,我的輸出是正確的,因此我認為有些特殊情況無法正確處理
我找不到問題所在。
任何幫助表示贊賞
更新:我將遞歸函數更改為迭代函數,現在結果對於所有測試文件都是正確的。 再次,我不明白為什么遞歸不起作用
讓我們考慮一個簡單的案例,一項工作。 你會打電話
long res = computeOpt(njobs-1); // computeOpt(0)
那你有
if (j == 0)
return 0;
在computeOpt
內部。 因此,您無法從一份工作中獲得任何收入。
通常,由於上面的行,您似乎忽略了第一份工作。 if (j < 0)
應該更好。
PS在轉到“ 10k到1m隨機生成的作業集”之前,請始終測試簡單的情況。 它們更易於驗證和調試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.