Ejemplo n.º 1
0
int solver2(
    int m,		/* number of constraints */
    int N,		/* number of variables */
    int nz,		/* number of nonzeros in sparse constraint matrix */
    int *ia, 		/* array row indices */
    int *ka, 		/* array of indices into ia and a */
    double *a,		/* array of nonzeros in the constraint matrix */
    double *b, 		/* right-hand side */
    double *c,          /* objective coefficients */
    double *c2,         /* objective coefficients */
    double  f, 		/* objective function shift */
    int *basics,
    int *nonbasics,
    int *basicflag,
    int *freevars,
    int d1,
    int d2,
    double **BETAhat
    )
{

    double  *x_B;	/* primal basics */
    double  *y_N;	/* dual nonbasics */

    double  *xbar_B;	/* primal basic perturbation */
    double  *ybar_N;	/* dual nonbasic perturbation */

    double  *dy_N;	/*  dual  basics step direction - values (sparse) */
    int    *idy_N;	/*  dual  basics step direction - row indices */
    int     ndy_N;	/* number of nonz in dy_N */

    double  *dx_B;	/* primal basics step direction - values (sparse) */
    int    *idx_B;	/* primal basics step direction - row indices */
    int     ndx_B;	/* number of nonz in dx_B */

    double  *at;	/* sparse data structure for A^T */
    int    *iat;
    int    *kat;

    int     col_in;	/* entering column; index in 'nonbasics' */
    int     col_out;	/* leaving column; index in 'basics' */

    int     iter = 0;	/* number of iterations */
    int     i,j,k,n,v=0, j1,j2,ii;

    double  s, t, sbar, tbar, mu=HUGE_VAL, old_mu, primal_obj;

    double  *vec;
    int    *ivec;
    int     nvec;

    int	    status=0;

    int     from_scratch;

    /*******************************************************************
    * For convenience, we put...
    *******************************************************************/

    int n0 = d1*d2;
    n = N-m;

    /*******************************************************************
    * Read in the Data and initialize the common memory sites.
    *******************************************************************/

    CALLOC(    x_B, m,   double );      
    CALLOC( xbar_B, m,   double );      
    CALLOC(   dx_B, m,   double );      
    CALLOC(    y_N, n,   double );      
    CALLOC( ybar_N, n,   double );      
    CALLOC(   dy_N, n,   double );      
    CALLOC(    vec, N,   double );
    CALLOC(  idx_B, m,    int );      
    CALLOC(  idy_N, n,    int );      
    CALLOC(   ivec, N,    int );
    CALLOC(     at, nz,  double );
    CALLOC(    iat, nz,   int );
    CALLOC(    kat, m+1,  int );

    /**************************************************************** 
    *  Initialization.              				    *
    ****************************************************************/

    atnum(m,N,ka,ia,a,kat,iat,at);

    lufac( m, ka, ia, a, basics, 0);

    for (j=0; j<n; j++) {
	  y_N[j] = 0;
    }
    nvec = 0;
    for (i=0; i<m; i++) {
       	if (c[basics[i]] != 0.0) {
 	    vec[nvec] = c[basics[i]];
 	    ivec[nvec] = i;
	    nvec++;
	}
    }

    

    btsolve( m, vec, ivec, &nvec );  		
    Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );
    for (k=0; k<ndy_N; k++) {
	y_N[idy_N[k]] = dy_N[k];
    }
    for (j=0; j<n; j++) {
	y_N[j] -= c[nonbasics[j]];
    }

    for (j=0; j<n; j++) {
	   ybar_N[j] = 0;
    }
    nvec = 0;
    for (i=0; i<m; i++) {
	if (c2[basics[i]] != 0.0) {
	    vec[nvec] = c2[basics[i]];
	    ivec[nvec] = i;
	    nvec++;
	}
    }
    btsolve( m, vec, ivec, &nvec );  		
    Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );
    for (k=0; k<ndy_N; k++) {
	ybar_N[idy_N[k]] = dy_N[k];
    }
    for (j=0; j<n; j++) {
	ybar_N[j] -= c2[nonbasics[j]];
	if (ybar_N[j] < 0) printf("error: ybar_N[%d] = %e \n", j, ybar_N[j]);
    }

    for (i=0; i<m; i++) {
	       x_B[i] = 0;
	    xbar_B[i] = 0;
    }
    nvec = 0;
    for (i=0; i<m; i++) {
      if ( b[i] != 0.0 ) {
	 vec[nvec] = b[i];
	ivec[nvec] = i;
	nvec++;
      }
    }

    bsolve( m, vec, ivec, &nvec );
    for (i=0; i<nvec; i++) {
	x_B[ivec[i]] = vec[i];
           if (vec[i] < 0) printf("error: x_B[%d] = %e \n", i, vec[i]);
    }
/*
    printf ("m = %d,n = %d,nz = %d\n",m,N,nz);
    printf(
"---------------------------------------------------------------------------\n"
"          |   Primal      |        |                           arithmetic  \n"
"  Iter    |  Obj Value    |   mu   |   nonz(L)     nonz(U)     operations  \n"
"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n"
);*/

    /****************************************************************
    * 	Main loop                                                   *
    ****************************************************************/

    for (iter=0; iter<MAX_ITER; iter++) {


      /*************************************************************
      * STEP 1: Find mu                                            *
      *************************************************************/

      old_mu = mu;
      mu = -HUGE_VAL;
      col_in  = -1;
      for (j=0; j<n; j++) {
		if (ybar_N[j] > EPS2) { 
			if ( mu < -y_N[j]/ybar_N[j] ) {
			     mu = -y_N[j]/ybar_N[j];
			     col_in  = j;
			}
		}
      }
      col_out = -1;
      for (i=0; i<m; i++) {
         if (freevars[basics[i]] == 0) {
		if (xbar_B[i] > EPS2) { 
			if ( mu < -x_B[i]/xbar_B[i] ) {
			     mu = -x_B[i]/xbar_B[i];
			     col_out = i;
			     col_in  = -1;
			}
		}
         }
      }

      /*************************************************************
      * STEP 0: Record current portfolio                           *
      *************************************************************/

      primal_obj = sdotprod(c,x_B,basics,m) + f;
      if ( mu <= EPS3 || primal_obj > -EPS0) {	/* OPTIMAL */
          for (j1=0; j1<d1; j1++) {
	      for (j2=0; j2<d2; j2++) {
		  BETAhat[j1][j2] = 0;
	      }
	  }
	  for (i=0; i<m; i++) {
	    if (basics[i] < n0 && x_B[i] > EPS0) {
	      ii = basics[i];
	      j1 = ii%d1;
	      j2 = ii/d1;
	      BETAhat[j1][j2] = x_B[i];
	    }
	    else if (basics[i] < 2*n0 && x_B[i] > EPS0) {
	      ii = basics[i]-n0;
	      j1 = ii%d1;
	      j2 = ii/d1;
	      BETAhat[j1][j2] = -x_B[i];
	    }
	  }
          for (j1=0; j1<d1; j1++) {
            for (j2=0; j2<d2; j2++) {
	      if (ABS(BETAhat[j1][j2]) > 1e-5) {
	      }
            }
          }
	  status = 0;
	  break;
      }

      if ( col_out >= 0 ) {

        /*************************************************************
	*                          -1  T                             *
	* STEP 2: Compute dy  = -(B  N) e                            * 
	*                   N            i			     *
	*         where i = col_out                                  *
        *************************************************************/

	vec[0] = -1.0;
	ivec[0] = col_out;
	nvec = 1;

	btsolve( m, vec, ivec, &nvec );  		

	Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );

        /*************************************************************
	* STEP 3: Ratio test to find entering column                 * 
        *************************************************************/

	col_in = ratio_test2( dy_N, idy_N, ndy_N, y_N, ybar_N, mu );

	if (col_in == -1) { 	/* INFEASIBLE*/
	    status = 2;
	    printf("infeasible \n");
	    break;
	}

        /*************************************************************
	*                        -1                                  *
	* STEP 4: Compute dx  = B  N e                               * 
	*                   B         j                              *
	*                                                            *
        *************************************************************/

	j = nonbasics[col_in];
	for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) {
	     dx_B[i] =  a[k];
	    idx_B[i] = ia[k];
	}
	ndx_B = i;

	bsolve( m, dx_B, idx_B, &ndx_B );

      } else {

        /*************************************************************
	*                        -1                                  *
	* STEP 2: Compute dx  = B  N e                               * 
	*                   B         j                              *
        *************************************************************/

	j = nonbasics[col_in];
	for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) {
	     dx_B[i] =  a[k];
	    idx_B[i] = ia[k];
	}
	ndx_B = i;

	bsolve( m, dx_B, idx_B, &ndx_B );

        /*************************************************************
	* STEP 3: Ratio test to find leaving column                  * 
        *************************************************************/

	col_out = ratio_test( dx_B, idx_B, ndx_B, x_B, xbar_B, basics, freevars, mu );

	if (col_out == -1) {	/* UNBOUNDED */
	    status = 1;
	    printf("unbounded \n");
	    break;
	}

        /*************************************************************
	*                          -1  T                             *
	* STEP 4: Compute dy  = -(B  N) e                            * 
	*                   N            i			     *
	*                                                            *
        *************************************************************/

	 vec[0] = -1.0;
	ivec[0] = col_out;
	nvec = 1;

	btsolve( m, vec, ivec, &nvec );  		

	Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );

      }

      /*************************************************************
      *                                                            *
      * STEP 5: Put       t = x /dx                                *
      *                        i   i                               *
      *                   _   _                                    *
      *                   t = x /dx                                *
      *                        i   i                               *
      *                   s = y /dy                                *
      *                        j   j                               *
      *                   _   _                                    *
      *                   s = y /dy                                *
      *                        j   j                               *
      *************************************************************/

      for (k=0; k<ndx_B; k++) if (idx_B[k] == col_out) break;

      t    =    x_B[col_out]/dx_B[k];
      tbar = xbar_B[col_out]/dx_B[k];

      for (k=0; k<ndy_N; k++) if (idy_N[k] == col_in) break;

      s    =    y_N[col_in]/dy_N[k];
      sbar = ybar_N[col_in]/dy_N[k];

      /*************************************************************
      *                                _    _    _                 *
      * STEP 7: Set y  = y  - s dy     y  = y  - s dy              *
      *              N    N       N     N    N       N             *
      *                                _    _                      *
      *             y  = s             y  = s                      *
      *              i                  i                          *
      *             _    _    _                                    *
      *             x  = x  - t dx     x  = x  - t dx              *
      *              B    B       B     B    B       B             *
      *             _    _                                         *
      *             x  = t             x  = t                      *
      *              j                  j                          *
      *************************************************************/

      for (k=0; k<ndy_N; k++) {
		j = idy_N[k];
		y_N[j]    -= s   *dy_N[k];
		ybar_N[j] -= sbar*dy_N[k];
      }

      y_N[col_in]    = s;
      ybar_N[col_in] = sbar;

      for (k=0; k<ndx_B; k++) {
		i = idx_B[k];
		x_B[i]    -= t   *dx_B[k];
		xbar_B[i] -= tbar*dx_B[k];

      }

      x_B[col_out]     = t;
      xbar_B[col_out]  = tbar;

      /*************************************************************
      * STEP 8: Update basis                                       * 
      *************************************************************/

      i =    basics[col_out];
      j = nonbasics[col_in];
      basics[col_out]   = j;
      nonbasics[col_in] = i;
      basicflag[i] = -col_in-1;
      basicflag[j] = col_out;

      /*************************************************************
      * STEP 9: Refactor basis and print statistics                *
      *************************************************************/

      from_scratch = refactor( m, ka, ia, a, basics, col_out, v);

      if (from_scratch) {
          primal_obj = sdotprod(c,x_B,basics,m) + f;
/*          printf("%8d %14.7e %9.2e \n", iter, high(primal_obj), high(mu));
            fflush(stdout);*/
      }
    } 

    primal_obj = sdotprod(c,x_B,basics,m) + f;

    /****************************************************************
    * 	Transcribe solution to x vector and dual solution to y      *
    ****************************************************************/

    /****************************************************************
    * 	Split out slack variables and shift dual variables.
    ****************************************************************/

    /****************************************************************
    * 	Free work space                                             *
    ****************************************************************/
 
    Nt_times_y(-1, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N);

    FREE(at);
    FREE(iat);

    FREE(xbar_B);
    FREE(kat);
    FREE(ybar_N);

    lu_clo();
    btsolve(0, vec, ivec, &nvec);
    bsolve(0, vec, ivec, &nvec);

    FREE(  vec );
    FREE( ivec );
    FREE(  x_B );
    FREE(  y_N );
    FREE( dx_B );
    FREE(idx_B );
    FREE( dy_N );
    FREE(idy_N );
    FREE( nonbasics );
    FREE( basics );

    
    return status;
}   /* End of solver */
Ejemplo n.º 2
0
void solver20(
    int m,		/* number of constraints */
    int n,		/* number of variables */
    int nz,		/* number of nonzeros in sparse constraint matrix */
    int *ia, 		/* array row indices */
    int *ka, 		/* array of indices into ia and a */
    double *a,		/* array of nonzeros in the constraint matrix */
    double *b, 		/* right-hand side */
    double *c          /* objective coefficients */
    )
{

	/*structure of the solver*/

    int *basics;
    int *nonbasics;
    int *basicflag;
    double  *x_B;	/* primal basics */
    double  *y_N;	/* dual nonbasics */
    double  *xbar_B;	/* primal basic perturbation */
    double  *ybar_N;    /* dual nonbasic perturbation*/
    double  *dy_N;	/*  dual  basics step direction - values (sparse) */
    int    *idy_N;	/*  dual  basics step direction - row indices */
    int     ndy_N=0;	/* number of nonz in dy_N */
    double  *dx_B;	/* primal basics step direction - values (sparse) */
    int    *idx_B;	/* primal basics step direction - row indices */
    int     ndx_B;	/* number of nonz in dx_B */
    double  *at;	/* sparse data structure for a^t */
    int    *iat;
    int    *kat;
    int     col_in;	/* entering column; index in 'nonbasics' */
    int     col_out;	/* leaving column; index in 'basics' */
    int     iter = 0;	/* number of iterations */
    int     i,j,k,v=0;
    double  s, t, sbar, tbar, mu=HUGE_VAL;
    double  *vec;
    int    *ivec;
    int     nvec;
    int     N;

    N=m+n;

	 /*******************************************************************
    * read in the data and initialize the common memory sites.
    *******************************************************************/

	//add the slack variables

    i = 0;
    k = ka[n];
    for (j=n; j<N; j++) {	
	a[k] = 1.0;
	ia[k] = i;
	i++;
	k++;
	ka[j+1] = k;
    }
    nz = k;

    MALLOC(    x_B, m,   double );      
    MALLOC( xbar_B, m,   double );      
    MALLOC(   dx_B, m,   double );  
    MALLOC(    y_N, n,   double );
    MALLOC( ybar_N, n,   double );           
    MALLOC(   dy_N, n,   double );  
    MALLOC(    vec, N,   double );
    MALLOC(   ivec, N,    int );
    MALLOC(  idx_B, m,    int );      
    MALLOC(  idy_N, n,    int );      
    MALLOC(     at, nz,  double );
    MALLOC(    iat, nz,   int );
    MALLOC(    kat, m+1,  int );
    MALLOC(   basics,    m,   int );      
    MALLOC(   nonbasics, n,   int );      
    MALLOC(   basicflag, N,   int );
    CALLOC(   x, N, double );

    /**************************************************************** 
    *  initialization.              				    *
    ****************************************************************/

    atnum(m,N,ka,ia,a,kat,iat,at);

    for (j=0; j<n; j++) {
	nonbasics[j] = j;
	basicflag[j] = -j-1;
	      y_N[j] = -c[j];
           ybar_N[j] = 1;
    }

    for (i=0; i<m; i++) {
	    basics[i] = n+i;
       basicflag[n+i] = i;
	       x_B[i] = b[i];
	    xbar_B[i] = 1;
    }

    lufac( m, ka, ia, a, basics, 0 );

 for (iter=0; iter<MAX_ITER; iter++) {

      /*************************************************************
      * step 1: find mu                                            *
      *************************************************************/
      mu = -HUGE_VAL;
      col_in  = -1;
      for (j=0; j<n; j++) {
		if (ybar_N[j] > EPS2) { 
			if ( mu < -y_N[j]/ybar_N[j] ) {
			     mu = -y_N[j]/ybar_N[j];
			     col_in  = j;
			}
		}
      }
      col_out = -1;

     for (i=0; i<m; i++) {
		if (xbar_B[i] > EPS2) { 
			if ( mu < -x_B[i]/xbar_B[i] ) {
			     mu = -x_B[i]/xbar_B[i];
			     col_out = i;
			     col_in  = -1;
			}
		}
      }
     
       if ( mu <= lambda0 ) {	/* optimal */
          status0=0;       
	  break;

      }

        /*************************************************************
	*                          -1  t                             *
	* step 2: compute dy  = -(b  n) e                            * 
	*                   n            i			     *
	*         where i = col_out                                  *
        *************************************************************/
     if ( col_out >= 0 ) {
	vec[0] = -1.0;
	ivec[0] = col_out;
	nvec = 1;

	btsolve( m, vec, ivec, &nvec );  
	Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );

	col_in = ratio_test0( dy_N, idy_N, ndy_N, y_N, ybar_N,mu );

        /*************************************************************
	* STEP 3: Ratio test to find entering column                 * 
        *************************************************************/

	if (col_in == -1) { 	/* infeasible */
	    status0 = 1;
	    break;
	}

        /*************************************************************
	*                        -1                                  *
	* step 4: compute dx  = b  n e                               * 
	*                   b         j                              *
	*                                                            *
        *************************************************************/

	j = nonbasics[col_in];
	for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) {
	     dx_B[i] =  a[k];
	    idx_B[i] = ia[k];
	}
	ndx_B = i;
	bsolve( m, dx_B, idx_B, &ndx_B );

        }

        else {

        /*************************************************************
	*                        -1                                  *
	* STEP 2: Compute dx  = B  N e                               * 
	*                   B         j                              *
        *************************************************************/

	j = nonbasics[col_in];
	for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) {
	     dx_B[i] =  a[k];
	    idx_B[i] = ia[k];
	}
	ndx_B = i;
	bsolve( m, dx_B, idx_B, &ndx_B );

        /*************************************************************
	* STEP 3: Ratio test to find leaving column                  * 
        *************************************************************/

	col_out = ratio_test0( dx_B, idx_B, ndx_B, x_B, xbar_B, mu );

	if (col_out == -1) {	/* UNBOUNDED */
	    status0 = 2;
	    break;
	}

        /*************************************************************
	*                          -1  T                             *
	* STEP 4: Compute dy  = -(B  N) e                            * 
	*                   N            i			     *
	*                                                            *
        *************************************************************/

	 vec[0] = -1.0;
	ivec[0] = col_out;
	nvec = 1;

	btsolve( m, vec, ivec, &nvec );  		
	Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );

      }

      /*************************************************************
      *                                                            *
      * step 5: put       t = x /dx                                *
      *                        i   i                               *
      *                   _   _                                    *
      *                   t = x /dx                                *
      *                        i   i                               *
      *                   s = y /dy                                *
      *                        j   j                               *
      *                   _   _                                    *
      *                   s = y /dy                                *
      *                        j   j                               *
      *************************************************************/

      for (k=0; k<ndx_B; k++) if (idx_B[k] == col_out) break;

      t    =    x_B[col_out]/dx_B[k];
      tbar = xbar_B[col_out]/dx_B[k];

      for (k=0; k<ndy_N; k++) if (idy_N[k] == col_in) break;

      s    =    y_N[col_in]/dy_N[k];
      sbar = ybar_N[col_in]/dy_N[k];


      /*************************************************************
      *                                _    _    _                 *
      * step 7: set y  = y  - s dy     y  = y  - s dy              *
      *              n    n       n     n    n       n             *
      *                                _    _                      *
      *             y  = s             y  = s                      *
      *              i                  i                          *
      *             _    _    _                                    *
      *             x  = x  - t dx     x  = x  - t dx              *
      *              b    b       b     b    b       b             *
      *             _    _                                         *
      *             x  = t             x  = t                      *
      *              j                  j                          *
      *************************************************************/


      for (k=0; k<ndy_N; k++) {
		j = idy_N[k];
		y_N[j]    -= s   *dy_N[k];
                ybar_N[j] -= sbar*dy_N[k];
      }
      
      y_N[col_in]    = s;
      ybar_N[col_in] = sbar;

      for (k=0; k<ndx_B; k++) {
		i = idx_B[k];
		x_B[i]    -= t   *dx_B[k];
		xbar_B[i] -= tbar*dx_B[k];

      }

      x_B[col_out]     = t;
      xbar_B[col_out]  = tbar;

      /*************************************************************
      * step 8: update basis                                       * 
      *************************************************************/

      i =    basics[col_out];
      j = nonbasics[col_in];
      basics[col_out]   = j;
      nonbasics[col_in] = i;
      basicflag[i] = -col_in-1;
      basicflag[j] = col_out;


      /*************************************************************
      * step 9: refactor basis and print statistics                *
      *************************************************************/

      refactor( m, ka, ia, a, basics, col_out, v );

  } 

   

      for (i=0; i<m; i++) {
	  x[basics[i]] = x_B[i];
      }


      if(iter>=1){
          Nt_times_y( -1, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );
      }


    /****************************************************************
    * 	free work space                                             *
    ****************************************************************/

    FREE(  vec );
    FREE( ivec );
    FREE(  x_B );
    FREE(  y_N );
    FREE( dx_B );
    FREE(idx_B );
    FREE( dy_N );
    FREE(idy_N );
    FREE(xbar_B);
    FREE(ybar_N);
    FREE( nonbasics );
    FREE( basics );
    FREE(at);
    FREE(iat);
    FREE(basicflag);
    FREE(kat);

    if(iter>=1){
       lu_clo();
       btsolve(0, vec, ivec, &nvec);
       bsolve(0, vec, ivec, &nvec);
    }


}