void simplx(GMatrix& a, int m, int n, int m1, int m2, int* icase, int* izrov, int* iposv) { int m3 = m - (m1 + m2); int i, ip, ir, is, k, kh, kp, m12, nl1, nl2; GTEMPBUF(int, l1, n + 2); GTEMPBUF(int, l2, m + 2); GTEMPBUF(int, l3, m + 2); double bmax, q1, EPS = 1e-6; // EPS is the absolute precision, which should be adjusted to the scale of your variables. nl1 = n; for(k = 1; k<=n; k++) { l1[k] = k; //Initialize index list of columns admissible for exchange. izrov[k] = k; //Initially make all variables right-hand. } nl2 = m; for(i = 1; i <= m; i++) { if (a[i + 1][1] < 0.0) { printf(" Bad input tableau in simplx, Constants bi must be nonnegative.\n"); return; } l2[i] = i; iposv[i] = n + i; // ------------------------------------------------------------------------------------------------ // Initial left-hand variables. m1 type constraints are represented by having their slackv ariable // initially left-hand, with no artificial variable. m2 type constraints have their slack // variable initially left-hand, with a minus sign, and their artificial variable handled implicitly // during their first exchange. m3 type constraints have their artificial variable initially // left-hand. // ------------------------------------------------------------------------------------------------ } for(i = 1; i <= m2; i++) l3[i] = 1; ir = 0; if(m2 + m3 == 0) goto e30; //The origin is a feasible starting solution. Go to phase two. ir = 1; for(k = 1; k <= n + 1; k++) { //Compute the auxiliary objective function. q1 = 0.0; for(i = m1 + 1; i <= m; i++) q1 += a[i + 1][k]; a[m + 2][k] = -q1; } e10: simp1(a,m+1,l1,nl1,0,&kp,&bmax); //Find max. coeff. of auxiliary objective fn if(bmax <= EPS && a[m + 2][1] < -EPS) { *icase=-1; //Auxiliary objective function is still negative and cant be improved, return; //hence no feasible solution exists. } else if (bmax <= EPS && a[m + 2][1] <= EPS) { //Auxiliary objective function is zero and cant be improved; we have a feasible starting vector. //Clean out the artificial variables corresponding to any remaining equality constraints by //goto 1s and then move on to phase two by goto 30. m12 = m1 + m2 + 1; if(m12 <= m) for (ip=m12; ip<=m; ip++) if(iposv[ip] == ip+n) { //Found an artificial variable for an equalityconstraint. simp1(a,ip,l1,nl1,1,&kp,&bmax); if(bmax > EPS) goto e1; //Exchange with column corresponding to maximum } //pivot element in row. ir=0; m12=m12-1; if (m1+1 > m12) goto e30; for (i=m1+1; i<=m1+m2; i++) //Change sign of row for any m2 constraints if(l3[i-m1] == 1) //still present from the initial basis. for (k=1; k<=n+1; k++) a[i + 1][k] *= -1.0; goto e30; //Go to phase two. } simp2(a,m,n,l2,nl2,&ip,kp,&q1); //Locate a pivot element (phase one). if(ip == 0) { //Maximum of auxiliary objective function is *icase=-1; //unbounded, so no feasible solution exists return; } e1: simp3(a, m + 1, n, ip, kp); //Exchange a left- and a right-hand variable (phase one), then update lists. if(iposv[ip] >= n + m1 + m2 + 1) { //Exchanged out an artificial variable for an equality constraint. Make sure it stays out by removing it from the l1 list. for (k=1; k<=nl1; k++) if(l1[k] == kp) break; nl1 = nl1 - 1; for(is = k; is <= nl1; is++) l1[is] = l1[is+1]; } else { if(iposv[ip] < n+m1+1) goto e20; kh=iposv[ip]-m1-n; if(l3[kh] == 0) goto e20; //Exchanged out an m2 type constraint. l3[kh]=0; //If it's the first time, correct the pivot column //or the minus sign and the implicit //artificial variable. } a[m + 2][kp + 1] += 1.0; for (i=1; i<=m+2; i++) a[i][kp + 1] *= -1.0; e20: is=izrov[kp]; //Update lists of left- and right-hand variables. izrov[kp]=iposv[ip]; iposv[ip]=is; if (ir != 0) goto e10; //if still in phase one, go back to 10. //End of phase one code for finding an initial feasible solution. Now, in phase two, optimize it. e30: simp1(a,0,l1,nl1,0,&kp,&bmax); //Test the z-row for doneness. if(bmax <= EPS) { //Done. Solution found. Return with the good news. *icase=0; return; } simp2(a,m,n,l2,nl2,&ip,kp,&q1); //Locate a pivot element (phase two). if(ip == 0) { //Objective function is unbounded. Report and return. *icase=1; return; } simp3(a,m,n,ip,kp); //Exchange a left- and a right-hand variable (phase two), goto e20; //update lists of left- and right-hand variables and } //return for another iteration.
void simplx(float **a, int m, int n, int m1, int m2, int m3, int *icase, int izrov[], int iposv[]) { void simp1(float **a, int mm, int ll[], int nll, int iabf, int *kp, float *bmax); void simp2(float **a, int n, int l2[], int nl2, int *ip, int kp, float *q1); void simp3(float **a, int i1, int k1, int ip, int kp); int i,ip,ir,is,k,kh,kp,m12,nl1,nl2; int *l1,*l2,*l3; float q1,bmax; if (m != (m1+m2+m3)) nrerror("Bad input constraint counts in simplx"); l1=ivector(1,n+1); l2=ivector(1,m); l3=ivector(1,m); nl1=n; for (k=1;k<=n;k++) l1[k]=izrov[k]=k; nl2=m; for (i=1;i<=m;i++) { if (a[i+1][1] < 0.0) nrerror("Bad input tableau in simplx"); l2[i]=i; iposv[i]=n+i; } for (i=1;i<=m2;i++) l3[i]=1; ir=0; if (m2+m3) { ir=1; for (k=1;k<=(n+1);k++) { q1=0.0; for (i=m1+1;i<=m;i++) q1 += a[i+1][k]; a[m+2][k] = -q1; } do { simp1(a,m+1,l1,nl1,0,&kp,&bmax); if (bmax <= EPS && a[m+2][1] < -EPS) { *icase = -1; FREEALL return; } else if (bmax <= EPS && a[m+2][1] <= EPS) { m12=m1+m2+1; if (m12 <= m) { for (ip=m12;ip<=m;ip++) { if (iposv[ip] == (ip+n)) { simp1(a,ip,l1, nl1,1,&kp,&bmax); if (bmax > 0.0) goto one; } } } ir=0; --m12; if (m1+1 <= m12) for (i=m1+1;i<=m12;i++) if (l3[i-m1] == 1) for (k=1;k<=n+1;k++) a[i+1][k] = -a[i+1][k]; break; } simp2(a,n,l2,nl2,&ip,kp,&q1); if (ip == 0) { *icase = -1; FREEALL return; }