示例#1
0
LPPRoblemStatus lpengine::DualSimplexStep() {
  // Step1: Check if Dual is feasible then dictionary is optimal

  if (IsSemiPositive(p_.x_b_hat_)) {
    // current dictionary is optimal
    return LPPRoblemStatus::STATUS_OPTIMAL;
  }

  // Step2: Select Entring Variable
  p_.entering_var_ = ChooseEnteringVar(p_.x_b_hat_);

  // Step3: compute Dual step direction delta(z_n_)
  Eigen::MatrixXd tmp(p_.dim_m_, p_.dim_n_);
  tmp = p_.a_b_.inverse() * p_.a_n_;

  Eigen::VectorXd ei(p_.dim_m_);
  ei.setZero(ei.rows());
  ei[p_.entering_var_] = 1;
  p_.delta_z_n_ = -tmp.transpose() * ei;

  // Step4&5: Compute primal step length and leaving var
  ChooseLeavingVar(p_.delta_z_n_, p_.z_n_hat_, &p_.leaving_var_, &p_.s_);

  // if s_ is not positive then dual is unbounded (primal is infeasible)
  if (p_.s_ <= 0) {
    return LPPRoblemStatus::STATUS_UNBOUNDED;
  }

  // Step6: choose primal step direction. dual_enteringvar=dual_leavingvar
  Eigen::VectorXd ej(p_.dim_n_);
  ej.setZero(ej.rows());
  ej[p_.leaving_var_] = 1;
  p_.delta_x_b_ = tmp * ej;

  // Step7: Compute primal step length dual_leavingvar=primal_enteringvar
  p_.t_ = p_.x_b_hat_[p_.entering_var_] / p_.delta_x_b_[p_.entering_var_];

  // Step8: Update current primal and dual solutions
  p_.x_b_hat_ = p_.x_b_hat_ - p_.t_ * p_.delta_x_b_;
  p_.z_n_hat_ = p_.z_n_hat_ - p_.s_ * p_.delta_z_n_;

  // Step9: Update Basis
  SwapCols(p_.a_b_, p_.entering_var_,p_.a_n_ , p_.leaving_var_);

  p_.x_b_hat_[p_.entering_var_] = p_.t_;
  p_.z_n_hat_[p_.leaving_var_] = p_.s_;

  // Calc Objective Function Value
 // p_.obj_value_ = TODO: c_b_.transpose * a_b_.inverse() * b_;

  p_.dic_number_++;
  return LPPRoblemStatus::STATUS_ITTERATING;
}
示例#2
0
bool ON_Matrix::Invert( double zero_tolerance )
{
  ON_Workspace ws;
  int i, j, k, ix, jx, rank;
  double x;
  const int n = MinCount();
  if ( n < 1 )
    return false;

  ON_Matrix I(m_col_count, m_row_count);

  int* col = ws.GetIntMemory(n);

  I.SetDiagonal(1.0);
  rank = 0;

  double** this_m = ThisM();

  for ( k = 0; k < n; k++ ) {
    // find largest value in sub matrix
    ix = jx = k;
    x = fabs(this_m[ix][jx]);
    for ( i = k; i < n; i++ ) {
      for ( j = k; j < n; j++ ) {
        if ( fabs(this_m[i][j]) > x ) {
          ix = i;
          jx = j;
          x = fabs(this_m[ix][jx]);
        }
      }
    }

    SwapRows( k, ix );
    I.SwapRows( k, ix );

    SwapCols( k, jx );
    col[k] = jx;

    if ( x <= zero_tolerance ) {
      break;
    }
    x = 1.0/this_m[k][k];
    this_m[k][k] = 1.0;
    ON_ArrayScale( m_col_count-k-1, x, &this_m[k][k+1], &this_m[k][k+1] );
    I.RowScale( k, x );

    // zero this_m[!=k][k]'s 
    for ( i = 0; i < n; i++ ) {
      if ( i != k ) {
        x = -this_m[i][k];
        this_m[i][k] = 0.0;
        if ( fabs(x) > zero_tolerance ) {
          ON_Array_aA_plus_B( m_col_count-k-1, x, &this_m[k][k+1], &this_m[i][k+1], &this_m[i][k+1] );
          I.RowOp( i, x, k );
        }
      }
    }
  }

  // take care of column swaps
  for ( i = k-1; i >= 0; i-- ) {
    if ( i != col[i] )
      I.SwapRows(i,col[i]);
  }

  *this = I;

  return (k == n) ? true : false;
}