//----------------------------------------------------------------------------------------// // This is a slightly modified version of main() in lpdemo.c int lp_solve (lpp *lp) { lrs_dic *P; /* structure for holding current dictionary and indices */ lrs_dat *Q; /* structure for holding static problem data */ lrs_mp_vector output; /* one line of output:ray,vertex,facet,linearity */ long col; /* output column index for dictionary */ // allocate and init structure for static problem data Q = lrs_alloc_dat ("LRS globals"); if (Q == NULL) return 1; Q->m = lp->dim[ROW]-1; // Rows, excluding the objective function Q->n = 1+lp->dim[COL]; // Columns, including RHS which goes in column 0 Q->lponly = TRUE; // we do not want all vertices generated! Q->maximize = TRUE; output = lrs_alloc_mp_vector (Q->n); P = lrs_alloc_dic (Q); // allocate and initialize lrs_dic if (P == NULL) return 1; // Build the LP representation in the format required by lrs buildLP(P,Q,lp); // Solve the LP if (!lrs_solve_lp(P,Q)) return 1; // Print output prat ("\nObjective value = ", P->objnum, P->objden); for (col = 0; col < Q->n; col++) if (lrs_getsolution (P, Q, output, col)) lrs_printoutput (Q, output); /* free space : do not change order of next lines! */ lrs_clear_mp_vector (output, Q->n); lrs_free_dic (P,Q); /* deallocate lrs_dic */ lrs_free_dat (Q); /* deallocate lrs_dat */ return 0; }
int main (int argc, char *argv[]) { lrs_dic *P1,*P2; /* structure for holding current dictionary and indices */ lrs_dat *Q1,*Q2; /* structure for holding static problem data */ lrs_mp_vector output1; /* holds one line of output; ray,vertex,facet,linearity */ lrs_mp_vector output2; /* holds one line of output; ray,vertex,facet,linearity */ lrs_mp_matrix Lin; /* holds input linearities if any are found */ lrs_dic *P2orig; /* we will save player 2's dictionary in getabasis */ long col; /* output column index for dictionary */ long startcol = 0; long prune = FALSE; /* if TRUE, getnextbasis will prune tree and backtrack */ long numequilib=0; /* number of nash equilibria found */ long oldnum=0; /* global variables lrs_ifp and lrs_ofp are file pointers for input and output */ /* they default to stdin and stdout, but may be overidden by command line parms. */ if(argc <= 2 ) { printf("Usage: nash input1 input2 [outputfile] \n"); return 1; } /*************************************************** Step 0: Do some global initialization that should only be done once, no matter how many lrs_dat records are allocated. db ***************************************************/ if ( !lrs_init ("\n*nash:")) return 1; printf(AUTHOR); /*********************************************************************************/ /* Step 1: Allocate lrs_dat, lrs_dic and set up the problem */ /*********************************************************************************/ Q1 = lrs_alloc_dat ("LRS globals"); /* allocate and init structure for static problem data */ if (Q1 == NULL) return 1; Q1->nash=TRUE; if (!lrs_read_dat (Q1, argc, argv)) /* read first part of problem data to get dimensions */ return 1; /* and problem type: H- or V- input representation */ P1 = lrs_alloc_dic (Q1); /* allocate and initialize lrs_dic */ if (P1 == NULL) return 1; if (!lrs_read_dic (P1, Q1)) /* read remainder of input to setup P1 and Q1 */ return 1; output1 = lrs_alloc_mp_vector (Q1->n + Q1->m); /* output holds one line of output from dictionary */ fclose(lrs_ifp); /* allocate and init structure for player 2's problem data */ printf ("\n*Second input taken from file %s\n", argv[2]); Q2 = lrs_alloc_dat ("LRS globals"); if (Q2 == NULL) return 1; Q2->nash=TRUE; if (!lrs_read_dat (Q2, 2, argv)) /* read first part of problem data to get dimensions */ return 1; /* and problem type: H- or V- input representation */ if (Q2->nlinearity > 0) free(Q2->linearity); /* we will start again */ Q2->linearity = CALLOC ((Q2->m + 2), sizeof (long)); P2 = lrs_alloc_dic (Q2); /* allocate and initialize lrs_dic */ if (P2 == NULL) return 1; if (!lrs_read_dic (P2, Q2)) /* read remainder of input to setup P2 and Q2 */ return 1; output2 = lrs_alloc_mp_vector (Q1->n + Q1->m); /* output holds one line of output from dictionary */ P2orig = lrs_getdic(Q2); /* allocate and initialize lrs_dic */ if (P2orig == NULL) return 1; copy_dict(Q2,P2orig,P2); fprintf (lrs_ofp, "\n***** %ld %ld rational", Q1->n, Q2->n); /*********************************************************************************/ /* Step 2: Find a starting cobasis from default of specified order */ /* P1 is created to hold active dictionary data and may be cached */ /* Lin is created if necessary to hold linearity space */ /* Print linearity space if any, and retrieve output from first dict. */ /*********************************************************************************/ if (!lrs_getfirstbasis (&P1, Q1, &Lin, TRUE)) return 1; if (Q1->dualdeg) { printf("\n*Warning! Dual degenerate, ouput may be incomplete"); printf("\n*Recommendation: Add dualperturb option before maximize in first input file\n"); } if (Q1->unbounded) { printf("\n*Warning! Unbounded starting dictionary for p1, output may be incomplete"); printf("\n*Recommendation: Change/remove maximize option, or include bounds \n"); } /* Pivot to a starting dictionary */ /* There may have been column redundancy */ /* If so the linearity space is obtained and redundant */ /* columns are removed. User can access linearity space */ /* from lrs_mp_matrix Lin dimensions nredundcol x d+1 */ if (Q1->homogeneous && Q1->hull) startcol++; /* col zero not treated as redundant */ for (col = startcol; col < Q1->nredundcol; col++) /* print linearity space */ lrs_printoutput (Q1, Lin[col]); /* Array Lin[][] holds the coeffs. */ /*********************************************************************************/ /* Step 3: Terminate if lponly option set, otherwise initiate a reverse */ /* search from the starting dictionary. Get output for each new dict. */ /*********************************************************************************/ /* We initiate reverse search from this dictionary */ /* getting new dictionaries until the search is complete */ /* User can access each output line from output which is */ /* vertex/ray/facet from the lrs_mp_vector output */ /* prune is TRUE if tree should be pruned at current node */ do { prune=lrs_checkbound(P1,Q1); if (!prune && lrs_getsolution (P1, Q1, output1, col)) { oldnum=numequilib; nash2_main(argc,argv,P1,Q1,P2orig,Q2,&numequilib,output2); if (numequilib > oldnum || Q1->verbose) { if(Q1->verbose) prat(" \np2's obj value: ",P1->objnum,P1->objden); lrs_nashoutput (Q1, output1, 1L); fprintf (lrs_ofp, "\n"); } } } while (lrs_getnextbasis (&P1, Q1, prune)); fprintf(lrs_ofp,"\n*Number of equilibria found: %ld",numequilib); fprintf (lrs_ofp,"\n*Player 1: vertices=%ld bases=%ld pivots=%ld", Q1->count[1], Q1->count[2],Q1->count[3]); fprintf (lrs_ofp,"\n*Player 2: vertices=%ld bases=%ld pivots=%ld", Q2->count[1], Q2->count[2],Q2->count[3]); lrs_clear_mp_vector(output1, Q1->m + Q1->n); lrs_clear_mp_vector(output2, Q1->m + Q1->n); lrs_free_dic (P1,Q1); /* deallocate lrs_dic */ lrs_free_dat (Q1); /* deallocate lrs_dat */ /* 2006.10.10 not sure what is going on with three lines below - sometimes crashes */ /* Q2->Qhead = P2; */ /* reset this or you crash free_dic */ /* lrs_free_dic (P2,Q2); */ /* deallocate lrs_dic */ /* lrs_free_dat (Q2); */ /* deallocate lrs_dat */ lrs_close ("nash:"); return 0; }
struct GMPmat *reducevertices(struct GMPmat *inp) { lrs_dic *P; lrs_dat *Q; lrs_mp_vector output; lrs_mp_matrix Lin; long i; long col; size_t m = GMPmat_Rows(inp); size_t *redRows; redRows = malloc( m*sizeof(*redRows) ); assert( redRows != NULL ); assert( my_lrs_init () == 0 ); Q = lrs_alloc_dat ("LRS globals"); assert ( Q != NULL ); Q->m = m; Q->n = GMPmat_Cols(inp); Q->hull = TRUE; Q->polytope = TRUE; output = lrs_alloc_mp_vector (Q->n); lrs_mp_vector num, den; num = lrs_alloc_mp_vector(GMPmat_Cols(inp)); den = lrs_alloc_mp_vector(GMPmat_Cols(inp)); P = lrs_alloc_dic (Q); assert ( P != NULL ); struct GMPmat *retMat; retMat = GMPmat_create(0, GMPmat_Cols(inp), 1); for (i = 1; i <= m; ++i) { GMPmat_getRow(num, den, inp, i-1); lrs_set_row_mp(P ,Q ,i ,num ,den , GE); } assert ( lrs_getfirstbasis (&P, Q, &Lin, TRUE) ); size_t lastdv = Q->lastdv; size_t d = P->d; size_t ineq; m = P->m_A; for (i = lastdv + 1; i <= m + d; ++i) { ineq = Q->inequality[i - lastdv] - 1; if (!checkindex(P, Q, i)) { retMat = GMPmat_appendRow(retMat, mpq_row_extract(inp, ineq)); GMPmal_everyNrows(retMat, pN, "irredundant vertices/rays"); } } lrs_clear_mp_vector ( output, Q->n); lrs_free_dic ( P , Q); lrs_free_dat ( Q ); GMPmat_destroy(inp); return retMat; }
struct GMPmat *V2H(struct GMPmat *inp) /* This function is untested */ { lrs_dic *P; lrs_dat *Q; lrs_mp_vector output; lrs_mp_matrix Lin; long i; long col; assert( my_lrs_init () == 0 ); Q = lrs_alloc_dat ("LRS globals"); assert ( Q != NULL ); Q->m = GMPmat_Rows(inp); Q->n = GMPmat_Cols(inp); Q->hull = TRUE; Q->polytope = TRUE; output = lrs_alloc_mp_vector (Q->n); lrs_mp_vector num, den; num = lrs_alloc_mp_vector(GMPmat_Cols(inp)); den = lrs_alloc_mp_vector(GMPmat_Cols(inp)); P = lrs_alloc_dic (Q); assert ( P != NULL ); struct GMPmat *retMat; retMat = GMPmat_create(0, GMPmat_Cols(inp), 1); mpq_t *curRow; curRow = calloc(GMPmat_Cols(inp), sizeof(mpq_t)); assert( curRow != NULL ); mpq_row_init(curRow, GMPmat_Cols(inp)); for (i = 1; i <= GMPmat_Rows(inp); ++i) { GMPmat_getRow(num, den, inp, i-1); lrs_set_row_mp(P ,Q ,i ,num ,den , GE); } assert ( lrs_getfirstbasis (&P, Q, &Lin, TRUE) ); for (col = 0L; col < Q->nredundcol; col++) lrs_printoutput (Q, Lin[col]); do { for (col = 0; col <= P->d; col++) if (lrs_getsolution (P, Q, output, col)){ mpz_to_mpq(curRow, output, GMPmat_Cols(retMat)); retMat = GMPmat_appendRow(retMat, curRow); GMPmal_everyNrows(retMat, pN, "inequalities"); } } while (lrs_getnextbasis (&P, Q, FALSE)); mpq_row_clean( curRow, GMPmat_Cols(retMat) ); lrs_clear_mp_vector ( output, Q->n); lrs_clear_mp_vector ( num, Q->n); lrs_clear_mp_vector ( den, Q->n); lrs_free_dic ( P , Q); lrs_free_dat ( Q ); GMPmat_destroy(inp); return retMat; }
struct GMPmat *H2V(struct GMPmat *inp) { lrs_dic *Pv, *Ph; /* structure for holding current dictionary and indices */ lrs_dat *Qv, *Qh; /* structure for holding static problem data */ lrs_mp_vector output; /* one line of output:ray,vertex,facet,linearity */ lrs_mp_matrix Lin; /* holds input linearities if any are found */ size_t i, j, cols, rows; long col; /* output column index for dictionary */ /* Global initialization - done once */ assert( my_lrs_init () == 0 ); Qv = lrs_alloc_dat ("LRS globals"); assert( Qv!= NULL ); Qv->m = GMPmat_Rows(inp); Qv->n = GMPmat_Cols(inp); output = lrs_alloc_mp_vector (Qv->n); lrs_mp_vector num, den; num = lrs_alloc_mp_vector(GMPmat_Cols(inp)); den = lrs_alloc_mp_vector(GMPmat_Cols(inp)); Pv = lrs_alloc_dic (Qv); /* allocate and initialize lrs_dic */ assert( Pv != NULL ); struct GMPmat *Helper; Helper = GMPmat_create(0, GMPmat_Cols(inp), 1); mpq_t *curRow; curRow = calloc(GMPmat_Cols(inp), sizeof(mpq_t)); assert( curRow != NULL ); mpq_row_init(curRow, GMPmat_Cols(inp)); for (i = 1; i <= GMPmat_Rows(inp); ++i) { GMPmat_getRow(num, den, inp, i-1); lrs_set_row_mp(Pv,Qv,i,num,den,GE); } assert( lrs_getfirstbasis (&Pv, Qv, &Lin, TRUE) ); for (col = 0L; col < Qv->nredundcol; col++) /* print linearity space */ lrs_printoutput (Qv, Lin[col]); do { for (col = 0L; col <= Pv->d; col++) if (lrs_getsolution (Pv, Qv, output, col)) { mpz_to_mpq(curRow, output, GMPmat_Cols(Helper)); Helper = GMPmat_appendRow(Helper, curRow); GMPmal_everyNrows(Helper, pN, "vertices/rays"); } } while (lrs_getnextbasis (&Pv, Qv, FALSE)); mpq_row_clean(curRow, GMPmat_Cols(Helper)); lrs_clear_mp_vector (output, Qv->n); lrs_clear_mp_vector (num, Qv->n); lrs_clear_mp_vector (den, Qv->n); lrs_free_dic (Pv,Qv); /* deallocate lrs_dic */ lrs_free_dat (Qv); /* deallocate lrs_dat */ // lrs_close ("lrsTrial:"); GMPmat_destroy(inp); return Helper; }
struct GMPmat *projection(struct GMPmat *inp, int d) { lrs_dic *Pv, *Ph; /* structure for holding current dictionary and indices */ lrs_dat *Qv, *Qh; /* structure for holding static problem data */ lrs_mp_vector output; /* one line of output:ray,vertex,facet,linearity */ lrs_mp_matrix Lin; /* holds input linearities if any are found */ size_t i, j, cols, rows; long col; /* output column index for dictionary */ /* Global initialization - done once */ assert( my_lrs_init () == 0 ); Qv = lrs_alloc_dat ("LRS globals"); assert( Qv!= NULL ); Qv->m = GMPmat_Rows(inp); Qv->n = GMPmat_Cols(inp); output = lrs_alloc_mp_vector (Qv->n); lrs_mp_vector num, den; num = lrs_alloc_mp_vector(GMPmat_Cols(inp)); den = lrs_alloc_mp_vector(GMPmat_Cols(inp)); Pv = lrs_alloc_dic (Qv); /* allocate and initialize lrs_dic */ assert( Pv != NULL ); struct GMPmat *Helper; Helper = GMPmat_create(0, GMPmat_Cols(inp), 1); mpq_t *curRow; curRow = calloc(GMPmat_Cols(inp), sizeof(mpq_t)); assert( curRow != NULL ); mpq_row_init(curRow, GMPmat_Cols(inp)); for (i = 1; i <= GMPmat_Rows(inp); ++i) { GMPmat_getRow(num, den, inp, i-1); lrs_set_row_mp(Pv,Qv,i,num,den,GE); } assert( lrs_getfirstbasis (&Pv, Qv, &Lin, TRUE) ); for (col = 0L; col < Qv->nredundcol; col++) /* print linearity space */ lrs_printoutput (Qv, Lin[col]); do { for (col = 0L; col <= Pv->d; col++) if (lrs_getsolution (Pv, Qv, output, col)) { mpz_to_mpq(curRow, output, GMPmat_Cols(Helper)); Helper = GMPmat_appendRow(Helper, curRow); GMPmal_everyNrows(Helper, pN, "vertices/rays"); } } while (lrs_getnextbasis (&Pv, Qv, FALSE)); mpq_row_clean(curRow, GMPmat_Cols(Helper)); lrs_clear_mp_vector (output, Qv->n); lrs_clear_mp_vector (num, Qv->n); lrs_clear_mp_vector (den, Qv->n); lrs_free_dic (Pv,Qv); /* deallocate lrs_dic */ lrs_free_dat (Qv); /* deallocate lrs_dat */ Helper = reducevertices(Helper); Qh = lrs_alloc_dat ("LRS globals"); assert( Qh != NULL ); Qh->m = GMPmat_Rows(Helper); Qh->n = GMPmat_Cols(Helper) - d; Qh->hull = TRUE; /* convex hull problem: facet enumeration */ Qh->polytope = TRUE; /* input is a polytope */ output = lrs_alloc_mp_vector (Qh->n); num = lrs_alloc_mp_vector (Qh->n); den = lrs_alloc_mp_vector (Qh->n); Ph = lrs_alloc_dic (Qh); assert( Ph != NULL ); struct GMPmat *retVal; retVal = GMPmat_create(0, Qh->n, 0); rows = GMPmat_Rows (Helper); cols = GMPmat_Cols (retVal); curRow = calloc(cols, sizeof(mpq_t)); assert( curRow != NULL ); mpq_row_init(curRow, cols); mpq_t curVal; mpq_init(curVal); for (i = 0; i < rows; ++i) { for (j = 0; j < cols; ++j) { GMPmat_getValue (curVal, Helper, i, j); mpz_set (num[j], mpq_numref(curVal)); mpz_set (den[j], mpq_denref(curVal)); } lrs_set_row_mp (Ph, Qh, i+1 ,num, den, GE); } mpq_clear(curVal); assert( lrs_getfirstbasis (&Ph, Qh, &Lin, TRUE) ); for (col = 0L; col < Qh->nredundcol; col++) /* print linearity space */ lrs_printoutput (Qh, Lin[col]); do { for (col = 0L; col <= Ph->d; col++) if (lrs_getsolution (Ph, Qh, output, col)){ mpz_to_mpq(curRow, output, GMPmat_Cols(retVal)); retVal = GMPmat_appendRow(retVal, curRow); GMPmal_everyNrows(retVal, pN, "inequalities"); } } while (lrs_getnextbasis (&Ph, Qh, FALSE)); GMPmat_destroy(Helper); mpq_row_clean(curRow, GMPmat_Cols(retVal)); lrs_clear_mp_vector (output, Qh->n); lrs_clear_mp_vector (num, Qh->n); lrs_clear_mp_vector (den, Qh->n); lrs_free_dic (Ph,Qh); lrs_free_dat (Qh); // lrs_close ("lrsTrial:"); printf ("\n"); GMPmat_destroy(inp); return retVal; }