diff options
Diffstat (limited to '01-knapsack')
-rw-r--r-- | 01-knapsack/ks_dp-ng.c | 224 | ||||
-rwxr-xr-x | 01-knapsack/run | 18 |
2 files changed, 242 insertions, 0 deletions
diff --git a/01-knapsack/ks_dp-ng.c b/01-knapsack/ks_dp-ng.c new file mode 100644 index 0000000..9f98a0d --- /dev/null +++ b/01-knapsack/ks_dp-ng.c @@ -0,0 +1,224 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <time.h> +#include <unistd.h> + +#define NONE -1 + +static int debug; + +typedef struct _InputItem +{ + int i; /* item index */ + int v; /* item value */ + int w; /* item weight */ +} InputItem; + +typedef struct _SolverItem { + int i; /* index of the selected item */ + int v; /* cumulated value */ + int w; /* cumulated weight */ +} SolverItem; + +typedef struct _Solver +{ + int k; /* capacity */ + int n; /* items # */ + InputItem *items; /* items */ + SolverItem *column; /* solver column */ +} Solver; + +static void solve(Solver* solver) +{ + int n, k; + int v, w; + int i, j; + const InputItem *item; + SolverItem *data; + const SolverItem *up_left; + + unsigned int counter; + + n = solver->n; + k = solver->k; + + if (debug > 2) + { + printf("\ncurrent V(i,s,W,r)\n"); + } + + /* SOLVE */ + counter = 0; + item = solver->items; + for (i = 0; i < n; i++, item++) + { + v = item->v; + w = item->w; + data = NULL; + data = solver->column + solver->k; + up_left = solver->column + (solver->k - w); + + for (j = k; j >= w; j--, data--, up_left--) + { + counter++; + + if (data->v < (v + up_left->v)) + { + data->i = i; + data->v = v + up_left->v; + data->w = w + up_left->w; + } + } + + if (debug > 2) + { + data = solver->column; + for (j = 0; j <= k; j++, data++) + printf(" % 4d(% 2d % 2d)\n", + data->v, data->i, data->w); + printf("\n"); + } + } + + if (debug == 2) + { + 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); + } + + if (debug > 0) + printf("loops count: %u\n", counter); +} + +static int check(Solver *solver, int excpected_value) +{ + const SolverItem *data; + + if (excpected_value == NONE) + return EXIT_SUCCESS; + + data = solver->column + solver->k; + if (data->v != excpected_value) + { + fprintf(stderr,"*** ERROR found %d != %d excpected !", + data->v, excpected_value); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +int main(int argc, char** argv, char** env) +{ + FILE *fp; + + int ret; + int opt; + int i; + int excpected_value; + uint64_t dt; + struct timespec t0; + struct timespec t1; + + Solver solver; + InputItem *item; + + debug = 0; + excpected_value = NONE; + while ((opt = getopt(argc, argv, "d:e:")) != -1) { + switch (opt) { + case 'd': + debug = atoi(optarg); + break; + case 'e': + excpected_value = atoi(optarg); + break; + default: /* '?' */ + fprintf(stderr, "Usage: %s [-d level] input\n", + argv[0]); + return EXIT_FAILURE; + } + } + + if (optind >= argc) { + fprintf(stderr,"input file missing\n"); + return EXIT_FAILURE; + } + + if (debug > 0) printf("%s\n", argv[optind]); + fp = fopen(argv[optind], "r"); + if (fp == NULL) + { + fprintf(stderr, "I couldn't open results.dat for reading.\n"); + return EXIT_FAILURE; + } + + /* read k and n */ + if (fscanf(fp, "%d %d\n", &solver.n, &solver.k) != 2) + { + fprintf(stderr, "ERROR: read first line\n"); + return EXIT_FAILURE; + } + if (debug > 0) printf(" K:%d N:%d\n", solver.k, solver.n); + + /* allocate */ + solver.items = calloc(solver.n, sizeof(InputItem)); + if (!solver.items) + { + fprintf(stderr, "ERROR: items calloc\n"); + return EXIT_FAILURE; + } + + solver.column = calloc((solver.k + 1), sizeof(SolverItem)); + if (!solver.column) + { + free(solver.items); + fprintf(stderr, "ERROR: column calloc\n"); + return EXIT_FAILURE; + } + for (i = 0; i < (solver.k + 1); i++) + { + solver.column[i].i = NONE; + } + + /* read items */ + item = solver.items; + for (i = 0; i < solver.n; i++, item++) + { + item->i = i; + fscanf(fp, "%d %d\n", &item->v, &item->w); + } + fclose(fp); + + if (debug > 1) + { + item = solver.items; + printf(" index Value Weight\n"); + for (i = 0; i < solver.n; i++, item++) + printf(" % 8d % 8d % 8d\n", item->i, item->v, item->w); + } + + clock_gettime(CLOCK_MONOTONIC, &t0); + solve(&solver); + clock_gettime(CLOCK_MONOTONIC, &t1); + + ret = check(&solver, excpected_value); + + if (debug > 0) + { + dt = ((t1.tv_sec * 1000000000) + t1.tv_nsec) - + ((t0.tv_sec * 1000000000) + t0.tv_nsec); + printf(" time %7u [ms]\n", (unsigned int)(dt/1000000)); + } + + free(solver.items); + free(solver.column); + + return ret; +} + diff --git a/01-knapsack/run b/01-knapsack/run new file mode 100755 index 0000000..df6db5e --- /dev/null +++ b/01-knapsack/run @@ -0,0 +1,18 @@ +#! /bin/bash + +RESET="\033[0m" +RED="\033[0;31m" + +BIN=${BIN:-ks_dp-ng} +${CC:-clang} -O2 -pedantic -Wall -o $BIN $BIN.c || exit 1 + +DATAS=(ks_4_0 ks_19_0 ks_30_0 ks_40_0 ks_45_0 ks_50_0 ks_50_1 ks_60_0 ks_100_0 ks_100_1 ks_100_2 ks_200_0 ks_200_1 ks_300_0 ks_400_0 ks_500_0 ks_1000_0 ks_10000_0) +VALUES=(19 12248 99798 99924 23974 142156 5345 99837 99837 1333930 10892 100236 1103604 1688692 3967180 54939 109899 1099893) + +for((i=0;i<${#DATAS[@]};i++)) +do + data="./data/${DATAS[$i]}" + value="${VALUES[$i]}" + echo -e "$RED *** $data -e $value $@ $RESET" + ./$BIN $data -e $value $@ +done |