Мой вопрос связан с этим другим обсуждением .
Я пытаюсь реализовать этот алгоритм с использованием динамической программы в рекурсивный вызов.
Постановка задачи:
Задание 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]
}
И это мой код (соответствующие части):
global vars:
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
/*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-Compute-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);
Я запускаю свою программу на нескольких тестовых примерах с большими данными (от 10 до 1 м сгенерированных случайных заданий) comсопоставить мой вывод с ожидаемым результатом.В некоторых случаях это не удается.Иногда мой результат немного больше, а иногда немного меньше, чем ожидаемый результат.Я что-то упускаю, очевидно.Обратите внимание, что в большинстве случаев мой вывод правильный, поэтому я думаю, что есть некоторые особые условия, которые я не могу обработать должным образом
Я не могу найти, где проблема.
Любойпомощь приветствуется
ОБНОВЛЕНИЕ: Я изменил рекурсивную функцию на итеративную, и теперь результат верен для всех тестовых файлов.Опять не могу понять, почему рекурсивный не работает