diff --git a/res/instance1.txt b/res/instance1.txt index e165c6b..16c5336 100644 --- a/res/instance1.txt +++ b/res/instance1.txt @@ -1,5 +1,14 @@ -100 -45 97 -36 610 -31 395 -14 211 +5600 +1380 22 +1520 25 +1560 12 +1710 14 +1820 18 +1880 18 +1930 20 +2000 10 +2050 12 +2100 14 +2140 16 +2150 18 +2200 20 diff --git a/src/column.c b/src/column.c index 8048ae6..ef891a9 100644 --- a/src/column.c +++ b/src/column.c @@ -29,12 +29,12 @@ #include #include -double *column_create(int column_count, double value, int index) { +double *column_create(int column_count, int count, int index) { double *column; column = (double *)malloc(column_count * sizeof(double)); memset(column, 0, column_count * sizeof(double)); - column[index] = value; + column[index] = count; return column; } @@ -80,7 +80,11 @@ double **columns_matrix_compute(order **orders, int order_count, int max_width) return NULL; } - columns_matrix[i] = column_create(order_count, max_width / orders[i]->width, i); + /* For each order width, create a column with only that width */ + int count = max_width / orders[i]->width; + if (count > orders[i]->demand) + count = orders[i]->demand; + columns_matrix[i] = column_create(order_count, count, i); } return columns_matrix; diff --git a/src/column.h b/src/column.h index 51d5531..70ee4e0 100644 --- a/src/column.h +++ b/src/column.h @@ -31,7 +31,7 @@ #include -double *column_create(int column_count, double value, int index); +double *column_create(int column_count, int count, int index); void column_print(double *columns, int column_count, FILE *fd); diff --git a/src/cutting_stock.c b/src/cutting_stock.c index 12e123e..5b8b7dd 100644 --- a/src/cutting_stock.c +++ b/src/cutting_stock.c @@ -99,7 +99,7 @@ void cutting_stock_branch_and_cut(order **orders, int order_count, double *dual_ glp_add_cols(lp, col_number); for (i = 0, col = 1; col <= col_number; col++, i++) { - glp_set_col_bnds(lp, col, GLP_LO, 0.0, 0.0); + glp_set_col_bnds(lp, col, GLP_DB, 0.0, orders[i]->demand); glp_set_col_kind(lp, col, GLP_IV ); glp_set_obj_coef(lp, col, dual_column[i]); } @@ -135,8 +135,6 @@ double **cutting_stock_compute_best_patterns(order **orders, int order_count, in columns_matrix = columns_matrix_compute(orders, order_count, max_width); column_size = order_count; columns_matrix_number = order_count; - best_patterns = NULL; - temp_best_patterns_number = 0; while (true) { dual_column = cutting_stock_compute_dual(orders, order_count, columns_matrix, columns_matrix_number); @@ -144,12 +142,6 @@ double **cutting_stock_compute_best_patterns(order **orders, int order_count, in new_pattern = (double *)malloc(column_size * sizeof(double)); cutting_stock_branch_and_cut(orders, order_count, dual_column, column_size, max_width, &obj_value, new_pattern); - if (obj_value <= 1.00000999999) { - free((void *)dual_column); - free((void *)new_pattern); - break; - } - /* Add the new pattern */ if (columns_matrix) { columns_matrix = (double **)realloc(columns_matrix, (columns_matrix_number + 1) * sizeof(double *)); @@ -160,6 +152,9 @@ double **cutting_stock_compute_best_patterns(order **orders, int order_count, in columns_matrix_number++; free((void *)dual_column); + + if (obj_value <= 1.00000000001) + break; } if (columns_matrix_number == 0) { @@ -167,18 +162,14 @@ double **cutting_stock_compute_best_patterns(order **orders, int order_count, in return NULL; } + best_patterns = (double **)malloc(columns_matrix_number * sizeof(double *)); + temp_best_patterns_number = 0; for (i = 0; i < columns_matrix_number; i++) { - if (best_patterns) { - if (!double_matrix_contains_array(best_patterns, temp_best_patterns_number, columns_matrix[i], column_size)) { - best_patterns = (double **)realloc(best_patterns, (temp_best_patterns_number + 1) * sizeof(double *)); - best_patterns[temp_best_patterns_number] = columns_matrix[i]; - temp_best_patterns_number++; - } - } else { - best_patterns = (double **)malloc(sizeof(double *)); - best_patterns[0] = columns_matrix[i]; - temp_best_patterns_number++; - } + if (double_matrix_contains_array(best_patterns, temp_best_patterns_number, columns_matrix[i], column_size)) + continue; + + best_patterns[temp_best_patterns_number] = columns_matrix[i]; + temp_best_patterns_number++; } *best_patterns_number = temp_best_patterns_number; @@ -208,6 +199,7 @@ double *cutting_stock_compute(double **best_patterns, int best_patterns_number, for (col = 1; col <= best_patterns_number; col++) { glp_set_col_bnds(lp, col, GLP_LO, 0.0, 0.0); + glp_set_col_kind(lp, col, GLP_IV); glp_set_obj_coef(lp, col, 1.0); } @@ -221,12 +213,13 @@ double *cutting_stock_compute(double **best_patterns, int best_patterns_number, glp_load_matrix(lp, mat->count, mat->ia, mat->ja, mat->ar); assert(glp_simplex(lp, NULL) == 0); + assert(glp_intopt(lp, NULL) == 0); - *obj_value = glp_get_obj_val(lp); + *obj_value = glp_mip_obj_val(lp); pattern_demand_repartition = (double *)malloc(best_patterns_number * sizeof(double)); for (i = 0, col = 1; col <= best_patterns_number; col++, i++) { - pattern_demand_repartition[i] = glp_get_col_prim(lp, col); + pattern_demand_repartition[i] = glp_mip_col_val(lp, col); } glp_delete_prob(lp); diff --git a/src/main.c b/src/main.c index 604902f..92b594c 100644 --- a/src/main.c +++ b/src/main.c @@ -38,7 +38,8 @@ #include #include -void compute_problem_from_file(char *file_name) { +int compute_problem_from_file(char *file_name) { + int ret = 0; order **orders; int order_count, max_width, best_patterns_number; double **best_patterns, *pattern_demand_repartition, obj_value; @@ -51,24 +52,26 @@ void compute_problem_from_file(char *file_name) { if (!(is_file_exists(file_name))) { printf("[ERROR] The specified file '%s' doesn't exists.\n", file_name); - goto clean_up; + return -1; } if (!(orders = orders_read_from_file(file_name, &order_count, &max_width))) { printf("[ERROR] Failed to load orders from the file '%s'.\n", file_name); - goto clean_up; + return -1; } begin_clock = clock(); if (!(best_patterns = cutting_stock_compute_best_patterns(orders, order_count, max_width, &best_patterns_number))) { printf("[ERROR] The computation of the best patterns failed.\n"); - goto clean_up; + ret = -1; + goto err_compute_best_patterns; } if (!(pattern_demand_repartition = cutting_stock_compute(best_patterns, best_patterns_number, orders, order_count, &obj_value))) { printf("[ERROR] The resolution of the problem failed.\n"); - goto clean_up; + ret = -1; + goto err_compute; } end_clock = clock(); @@ -77,23 +80,29 @@ void compute_problem_from_file(char *file_name) { cutting_stock_print_solution(best_patterns, best_patterns_number, order_count, pattern_demand_repartition, obj_value, orders, order_count, stdout); -clean_up: - free((void *)pattern_demand_repartition); + free(pattern_demand_repartition); + +err_compute: columns_matrix_destroy(best_patterns, best_patterns_number); +err_compute_best_patterns: orders_destroy(orders, order_count); + return ret; } int main(int argc, char **argv) { + int exit_code = 0; + glp_term_out(GLP_OFF); if (argc != 2) { printf("%s \n", argv[0]); - return 0; + return 1; } - compute_problem_from_file(argv[1]); + if (compute_problem_from_file(argv[1]) < 0) + exit_code = 1; glp_free_env(); - return 0; + return exit_code; }