Beispiel #1
0
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 can’t be improved,
		return;       //hence no feasible solution exists.
	}
	else if (bmax <= EPS && a[m + 2][1] <= EPS)
	{
		//Auxiliary objective function is zero and can’t be improved; we have a feasible starting vector.
		//Clean out the artificial variables corresponding to any remaining equality constraints by
		//goto 1’s 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.
Beispiel #2
0
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;
			}