diff --git a/01-knapsack/ks_dp-ng.c b/01-knapsack/ks_dp-ng.c index 7830651..ddb0d04 100644 --- a/01-knapsack/ks_dp-ng.c +++ b/01-knapsack/ks_dp-ng.c @@ -7,12 +7,14 @@ #define NONE -1 +enum { RELAX = 0, NO_RELAX }; enum { SORT_DESC = 0, SORT_ASC }; enum { UNSORTED = 0, SORT_WR, SORT_VR, SORT_RW, SORT_RV}; static int debug; static int sort; static int sort_order; +static int relax; typedef struct _InputItem { @@ -25,6 +27,7 @@ typedef struct _SolverItem { int i; /* index of the selected item */ int v; /* cumulated value */ int w; /* cumulated weight */ + float r; /* linear relaxation best value */ } SolverItem; typedef struct _Solver @@ -87,11 +90,39 @@ item_cmp(const void *p1, const void *p2) return 0; } +static inline float relax_item(Solver* solver, SolverItem* data, int start) +{ + int w; + int i; + float relax; + const InputItem *item; + + w = data->w; + relax= data->v; + item = &solver->items[start]; + for (i = start; i < solver->n; i++, item++) + { + if ((w + item->w) <= solver->k) + { + w += item->w; + relax += item->v; + } + else + { + relax += (item->v * ((solver->k - w) / (float)item->w)); + break; + } + } + + return relax; +} + static void solve(Solver* solver) { int n, k; int v, w; int i, j; + float r; int min_c, lower_bound; const InputItem *item; SolverItem *data; @@ -105,7 +136,16 @@ static void solve(Solver* solver) if (debug > 2) { - printf("\nformat V(i,W)\n"); + printf("\nformat V(i,W,r)\n"); + } + + /* RELAXATION */ + if (relax == RELAX) + { + data = solver->column; + r = relax_item(solver, data, 0); + for (j = 0; j <= k; j++, data++) + data->r = r; } /* SOLVE */ @@ -134,6 +174,12 @@ static void solve(Solver* solver) data->v = v + up_left->v; data->w = w + up_left->w; } + + /* RELAXTION must be cached */ + if (relax == RELAX) + { + data->r = relax_item(solver, data, (i + 1)); + } } if (debug > 2) @@ -141,8 +187,8 @@ static void solve(Solver* solver) printf("i=%d; j=k; j<=%d:\n", i, lower_bound); data = solver->column; for (j = 0; j <= k; j++, data++) - printf(" %d : % 4d(% 2d % 2d)\n", - j, data->v, data->i, data->w); + printf(" %d : % 4d(% 2d % 2d %.1f)\n", + j, data->v, data->i, data->w, data->r); printf("\n"); } } @@ -152,8 +198,8 @@ static void solve(Solver* solver) printf("i=%d:\n", solver->n - 1); data = solver->column; for (j = 0; j <= k; j++, data++) - printf(" % 4d(% 2d % 2d)\n", - data->v, data->i, data->w); + printf(" % 4d(% 2d % 2d %.1f)\n", + data->v, data->i, data->w, data->r); } if (debug > 0) @@ -194,10 +240,11 @@ int main(int argc, char** argv, char** env) InputItem *item; debug = 0; + relax = NO_RELAX; sort = UNSORTED; sort_order = SORT_DESC; excpected_value = NONE; - while ((opt = getopt(argc, argv, "d:e:s:S")) != -1) { + while ((opt = getopt(argc, argv, "d:e:s:SR")) != -1) { switch (opt) { case 'd': debug = atoi(optarg); @@ -211,6 +258,9 @@ int main(int argc, char** argv, char** env) case 'S': sort_order = SORT_ASC; break; + case 'R': + relax = RELAX; + break; default: /* '?' */ fprintf(stderr, "Usage: %s [falgs] input\n", argv[0]);