簡體   English   中英

加權區間調度問題與動態程序

[英]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.

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