// // Calculate a cut as // g_omega = -Transp( T_omega ) * pi // where // g_omega is the cutting plane, // Transp( T_omega ) is technology matrix transpose, // pi is either a row of basis inverse, or a dual // vector of the first stage problem. // void RD_SubproblemSolver::CalculateGradient( Real_T *grad, Int_T n, // ) Array<Real_T> &pi, const Scenario &Scen ) const { Ptr<Real_T> a; Ptr<Int_T> row; Int_T j, len; //-------------------------------------------------------------------------- // First calculate the basis part of the gradient vector. // for( j = 0; j < n; j++ ) { Real_T &g = grad[j]; g = 0.0; for( LP.T_base.GetColumn( j, a, row, len ); len; --len, ++a, ++row ) g -= *a * pi[*row]; } //-------------------------------------------------------------------------- // Then calculate the scenario-dependent part. // Int_T l = Scen.GetLength(); for( j = 0; j < l; j++ ) for( Int_T i = 0, bl = Scen[j].Len(); i < bl; i++ ) { const Delta &d = Scen[j][i]; if( d.type == Delta::MATRIX ) { assert( d.col >= 0 && d.col < n ); grad[ d.col ] -= pi[ d.row ] * d.value; } } }
void RD_SubproblemLP::ApplyScenario( const Scenario &Sc, // ) Bool_T NewTrialPoint, #ifndef NDEBUG Int_T nn, #else Int_T, #endif const Real_T *TrialPoint ) { assert( nn == n1st && TrialPoint != NULL ); //-------------------------------------------------------------------------- // Compute the new right hand side and cost to match the current scenario. // // Algorithm: // 1. h <- d_base; q <- q_base // 2. h += Delta_d; h -= Delta_T * y; q += Delta_q // 3. if( y changed ) // T_base_y <- T_base * y // 4. h -= T_base_y // // Step 2 is performed as one because Delta_d, Delta_T and Delta_q are // stored together on the same list corresponding to one scenario. // h.Copy( d_base, m2st, m2st ); q.Copy( q_base, n, n ); // // Now add the scenario-specific modifications. // for( Int_T l = Sc.GetLength(), j = 0; j < l; j++ ) { for( Int_T i = 0, bl = Sc[j].Len(); i < bl; i++ ) { const Delta &d = Sc[j][i]; switch( d.type ) { case Delta::RHS: h[d.row] += d.value; break; case Delta::MATRIX: assert( d.col >= 0 && d.col <= nn ); h[d.row] -= d.value * TrialPoint[d.col]; break; case Delta::COST: q[d.col] = d.value; break; default: #ifndef NDEBUG abort(); #endif break; } } } //-------------------------------------------------------------------------- // Check if 'TrialPoint' has changed. If so - recompute 'T_base_y'. // if( NewTrialPoint ) { T_base_y.Fill( 0.0, m2st ); Ptr<Real_T> a; Ptr<Int_T> row; Int_T len; for( Int_T j = 0; j < n1st; j++ ) for( T_base.GetColumn( j, a, row, len ); len; --len, ++a, ++row ) T_base_y[*row] += *a * TrialPoint[j]; } for( Int_T i = 0; i < m2st; i++ ) h[i] -= T_base_y[i]; //-------------------------------------------------------------------------- // Replace the right hand side and cost of the LP with computed ones. // SetRHS( h ); c.Copy( q, n, n ); }