#include #include #include "lists.h" struct Interval { float start; float finish; float value; }; struct Intervals { struct Interval * items; int number; }; struct WIS_result { float best_value; list best_set; }; struct Intervals read_intervals(char * filename) { struct Intervals result; result.number = 0; result.items = 0; FILE * handle = fopen(filename, "rb"); if (handle == 0) { printf("cannot open %s\n", filename); return result; } fscanf(handle, "%d", &(result.number)); result.items = malloc(sizeof(struct Interval) * (1 + result.number)); // printf("number = %d\n", result.number); result.items[0].start = 0; result.items[0].finish = 0; result.items[0].value = 0; int counter; for (counter = 1; counter <= result.number; counter++) { float start, finish, value; fscanf(handle, "%f %f %f", & start, & finish, & value); result.items[counter].start = start; result.items[counter].finish = finish; result.items[counter].value = value; // printf("%3d: start = %5.1f, finish = %5.1f, value = %5.1f\n", counter, start, finish, value); if (finish < result.items[counter-1].finish) { printf("error, intervals are not sorted\n"); exit(1); } } return result; } int * compute_last_complete(struct Intervals intervals) { int * last_complete = malloc(sizeof(int) * (1+intervals.number)); last_complete[0] = 0; int counter, second_counter; for (counter = 1; counter <= intervals.number; counter++) { float start = intervals.items[counter].start; second_counter = counter - 1; while(1) { float finish = intervals.items[second_counter].finish; if (finish <= start) { last_complete[counter] = second_counter; // printf(" last_complete[%d] = %d\n", counter, second_counter); break; } second_counter--; } } return last_complete; } struct WIS_result wis(struct Intervals intervals) { int * last_complete = compute_last_complete(intervals); int * last_used = malloc(sizeof(int) * (1+intervals.number)); float * solutions = malloc(sizeof(float) * (1+ intervals.number)); solutions[0] = 0; last_used[0] = 0; int counter; for (counter = 1; counter <= intervals.number; counter++) { float solution_without = solutions[counter - 1]; float value = intervals.items[counter].value; float solution_with = solutions[last_complete[counter]] + value; if (solution_with > solution_without) { solutions[counter] = solution_with; last_used[counter] = counter; } else { solutions[counter] = solution_without; last_used[counter] = last_used[counter-1]; } // printf("counter %4d: solution_without = %6.1f, solution_with = %6.1f, best = %6.1f\n", // counter, solution_without, solution_with, solutions[counter]); } // begin backtracking list best_set = newList(); counter = last_used[intervals.number]; while(counter != 0) { struct Interval * interval = malloc(sizeof(struct Interval)); *interval = intervals.items[counter]; insertAtBeginning(best_set, newLink(interval)); counter = last_used[last_complete[counter]]; } struct WIS_result result; result.best_value = solutions[intervals.number]; result.best_set = best_set; free(solutions); free(last_complete); free(last_used); return result; } void print_interval_list(list intervals) { link current; for (current = listFirst(intervals); current != NULL; current = linkNext(current)) { struct Interval * interval = (struct Interval *) linkItem(current); float start = interval->start; float finish = interval->finish; float value = interval->value; printf("start = %5.1f, finish = %5.1f, value = %5.1f\n", start, finish, value); } } int main() { struct Intervals intervals = read_intervals("wis1.txt"); struct WIS_result result = wis(intervals); printf(" best_value = %6.2f\n", result.best_value); print_interval_list(result.best_set); free(intervals.items); destroyList(result.best_set); return 0; }