void simplex(Tableau *tab) { int loop=0; add_slack_variables(tab); check_b_positive(tab); print_tableau(tab,"Padded with slack variables"); while( ++loop ) { int pivot_col, pivot_row; pivot_col = find_pivot_column(tab); if( pivot_col < 0 ) { printf("Found optimal value=A[0,0]=%3.2lf (no negatives in row 0).\n", tab->mat[0][0]); print_optimal_vector(tab, "Optimal vector"); break; } printf("Entering variable x%d to be made basic, so pivot_col=%d.\n", pivot_col, pivot_col); pivot_row = find_pivot_row(tab, pivot_col); if (pivot_row < 0) { printf("unbounded (no pivot_row).\n"); break; } printf("Leaving variable x%d, so pivot_row=%d\n", pivot_row, pivot_row); pivot_on(tab, pivot_row, pivot_col); print_tableau(tab,"After pivoting"); print_optimal_vector(tab, "Basic feasible solution"); if(loop > 20) { printf("Too many iterations > %d.\n", loop); break; } } }
unsigned int simplex(const int m, const int n, lp_t * p) { // init DFE max_file_t * maxfile = Simplex_init(); max_engine_t * engine = max_load(maxfile, "*"); // align for streaming int align_m, align_n; lp_t * align_p = copy_aligned(m, n, p, &align_m, &align_n); if (trace > 0) printf("aligned: %dx%d -> %dx%d\n", m, n, align_m, align_n); // reserve buffers lp_t * pivcol = (lp_t *) malloc(align_m * sizeof(lp_t)); lp_t * pivrow = (lp_t *) malloc(align_n * sizeof(lp_t)); // Simplex action to call DFE Simplex_actions_t act; act.param_m = align_m; act.param_n = align_n; act.instream_pivcol = pivcol; act.instream_pivrow = pivrow; act.instream_x = align_p; act.outstream_y = align_p; // main loop unsigned int count = 0; while (count < max_iterations || max_iterations == 0) { // column int col = pivot_rule == 0 ? find_pivot_column_first(align_n, align_p) : find_pivot_column_max(align_n, align_p); if (col < 0) break; // optimum found // row int row = find_pivot_row(align_m, align_n, align_p, col); if (row < 0) { align_p[0] = NAN; break; } // unbounded // pivoting count++; lp_t pivot = align_p[row * align_n + col]; if (trace > 0) printf("%d: pivoting on %d, %d: %"lp_t_fmt1"\n", count, row, col, pivot); // store pivcol & pivrow for DFE streaming for (int i = 0; i < align_m; i++) pivcol[i] = align_p[i * align_n + col]; for (int j = 0; j < align_n; j++) pivrow[j] = align_p[row * align_n + j]; // call DFE for pivoting act.param_row = row; act.param_col = col; act.param_pivot = 1 / pivot; Simplex_run(engine, &act); // tracing if (trace >= 9) write_bg(stdout, m, n, p); if (trace >= 2) print_obj(n, p); if (trace >= 3) print_bounds(m, n, p); } // unload DFE max_unload(engine); // free buffers free(pivcol); free(pivrow); p[0] = align_p[0]; return count; }
static void perform_partial_pivot(matrix_t * A, vector_t * b, int k) { int pivot_row = find_pivot_row(A, k, k); double * tmp, tmp_d; if (pivot_row == k) { return; /* no need to pivot */ } /* swap the pivot row and the current */ tmp = A->data[pivot_row]; A->data[pivot_row] = A->data[k]; A->data[k] = tmp; tmp_d = b->data[pivot_row]; b->data[pivot_row] = b->data[k]; b->data[k] = tmp_d; }
unsigned int simplex(const int m, const int n, lp_t * p) { // init DFE max_file_t * maxfile = Simplex_init(); max_engine_t * engine = max_load(maxfile, "*"); // align for streaming int align_m, align_n; lp_t * align_p = copy_aligned(m, n, p, &align_m, &align_n); if (trace > 0) printf("aligned: %dx%d -> %dx%d\n", m, n, align_m, align_n); // reserve buffers lp_t * c = malloc(align_n * sizeof(lp_t)); lp_t * ratio = malloc(align_m * sizeof(lp_t)); lp_t * pivcol = malloc(align_m * sizeof(lp_t)); lp_t * pivrow = malloc(align_n * sizeof(lp_t)); // init buffers: c, ratio, pivcol, pivrow for (int j = 0; j < n; j++) c[j] = p[j]; uint64_t col = find_pivot_column_max(n, c); for (int i = 0; i < align_m; ++i) { pivcol[i] = align_p[i * align_n + col]; ratio[i] = align_p[i * align_n] / pivcol[i]; } int row = find_pivot_row(m, ratio); for (int i = 0; i < align_n; i++) pivrow[i] = align_p[row * align_n + i]; // write LP to LMem Simplex_writeLMem_actions_t writeact; writeact.param_address = 0; writeact.param_count = align_m * align_n; writeact.instream_tolmem = align_p; Simplex_writeLMem_run(engine, &writeact); // simplex action to call DFE Simplex_actions_t act; act.param_m = align_m; act.param_n = align_n; act.instream_pivcol = pivcol; act.instream_pivrow = pivrow; act.outscalar_MaxKernel_maxcol_out = &col; act.outstream_ratio_out = ratio; act.outstream_pivcol_out = pivcol; act.outstream_c_out = c; // main loop unsigned int count = 0; while (count < max_iterations || max_iterations == 0) { // read pivot row from lmem Simplex_readLMem_actions_t readact; readact.param_address = row * align_n; readact.param_count = align_n; readact.outstream_fromlmem = pivrow; Simplex_readLMem_run(engine, &readact); // pivoting,max,filter count++; lp_t pivot = pivrow[col]; if (trace > 0) printf("%u: pivoting on %d, %lu: %g\n", count, row, col, pivot); act.param_pivot = 1 / pivot; act.param_col = col; act.param_row = row; Simplex_run(engine, &act); ratio[0] = -1; pivcol[0] = c[col]; //if (trace >= 9) write_bg(stdout, m, n, p); if (col <= 0) break; // optimum found // row row = find_pivot_row(m, ratio); if (row < 0) { p[0] = NAN; break; } // unbounded } // unload DFE max_unload(engine); // return results (TODO: copy full lp from lmem to p) p[0] = c[0]; // free buffers free(c); free(ratio); free(pivcol); free(pivrow); return count; }