00001
00007 #ifdef COIN_USE_DYLP
00008
00009 #ifdef _MSC_VER
00010
00011
00012
00013 # pragma warning(disable:4786)
00014
00015 #endif // _MSC_VER
00016
00017
00018
00019 #define ODWSB OsiDylpWarmStartBasis
00020 #define CWSB CoinWarmStartBasis
00021
00041 namespace {
00042 char sccsid[] = "%W% %G%" ;
00043 char cvsid[] = "$Id: OsiDylpWarmStartBasis.cpp,v 1.2 2003/10/23 17:32:22 lou-oss Exp $" ;
00044 }
00045
00046 #include <vector>
00047 #include <cassert>
00048 #include <iostream>
00049 #include "OsiDylpWarmStartBasis.hpp"
00050
00051 using std::vector ;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 #define STATPERBYTE 4
00062 #define STATALLOCUNIT sizeof(int)
00063 #define STATBYTES(zz_ns_zz) \
00064 (((zz_ns_zz+STATALLOCUNIT*STATPERBYTE-1)/(STATALLOCUNIT*STATPERBYTE))* \
00065 STATALLOCUNIT)
00066
00067
00076
00079 ODWSB::OsiDylpWarmStartBasis ()
00080
00081 : CWSB(),
00082 phase_(dyINV),
00083 constraintStatus_(0)
00084
00085 { }
00086
00087
00092 ODWSB::OsiDylpWarmStartBasis (const OsiDylpWarmStartBasis &ws)
00093
00094 : CWSB(ws),
00095 phase_(ws.phase_),
00096 constraintStatus_(0)
00097
00098 { int constatsze = STATBYTES(getNumArtificial()) ;
00099 constraintStatus_ = new char[constatsze] ;
00100 memcpy(constraintStatus_,ws.constraintStatus_,constatsze) ; }
00101
00102
00108 CoinWarmStart *ODWSB::clone () const
00109
00110 { const ODWSB *odwsb_orig = dynamic_cast<const ODWSB *>(this) ;
00111 ODWSB *odwsb_new = 0 ;
00112 if (odwsb_orig)
00113 { odwsb_new = new OsiDylpWarmStartBasis(*odwsb_orig) ; }
00114 return (dynamic_cast<CoinWarmStart *>(odwsb_new)) ; }
00115
00125 ODWSB::OsiDylpWarmStartBasis
00126 (int ns, int na, const char *sStat, const char *aStat, const char *cStat)
00127
00128 : CWSB(ns,na,sStat,aStat),
00129 phase_(dyPRIMAL1),
00130 constraintStatus_(0)
00131
00132 { int constatsze = STATBYTES(na) ;
00133 constraintStatus_ = new char[constatsze] ;
00134
00135
00136
00137
00138
00139 if (cStat)
00140 { memcpy(constraintStatus_,cStat,constatsze) ; }
00141 else
00142 { char byteActive = 0 ;
00143 int i ;
00144 for (i = 0 ; i <= 3 ; i++) setStatus(&byteActive,i,CWSB::atLowerBound) ;
00145 memset(constraintStatus_,byteActive,constatsze) ; } }
00146
00151 OsiDylpWarmStartBasis& ODWSB::operator= (const OsiDylpWarmStartBasis &rhs)
00152
00153 { if (this != &rhs)
00154 { CWSB::operator=(rhs) ;
00155 phase_ = rhs.phase_ ;
00156 delete[] constraintStatus_ ;
00157 int constatsze = STATBYTES(getNumArtificial()) ;
00158 constraintStatus_ = new char[constatsze] ;
00159 memcpy(constraintStatus_,rhs.constraintStatus_,constatsze) ; }
00160
00161 return *this ; }
00162
00163
00182 void ODWSB::assignBasisStatus
00183 (int ns, int na, char *&sStat, char *&aStat, char *&cStat)
00184
00185 { CWSB::assignBasisStatus(ns,na,sStat,aStat) ;
00186 phase_ = dyPRIMAL1 ;
00187 delete[] constraintStatus_ ;
00188 constraintStatus_ = cStat ;
00189 cStat = 0 ; }
00190
00210 void ODWSB::assignBasisStatus (int ns, int na, char *&sStat, char *&aStat)
00211
00212 { int constatsze = STATBYTES(na) ;
00213 char byteActive = 0 ;
00214 int i ;
00215
00216 CWSB::assignBasisStatus(ns,na,sStat,aStat) ;
00217 phase_ = dyPRIMAL1 ;
00218
00219 delete[] constraintStatus_ ;
00220 constraintStatus_ = new char[constatsze] ;
00221 for (i = 0 ; i <= 3 ; i++) setStatus(&byteActive,i,CWSB::atLowerBound) ;
00222 memset(constraintStatus_,byteActive,constatsze) ; }
00223
00224 ODWSB::~OsiDylpWarmStartBasis () { delete[] constraintStatus_ ; }
00225
00231 void ODWSB::setSize (int ns, int na)
00232
00233 { CWSB::setSize(ns,na) ;
00234 phase_ = dyINV ;
00235 delete[] constraintStatus_ ;
00236 int constatsze = STATBYTES(na) ;
00237 constraintStatus_ = new char[constatsze] ;
00238 assert(((int) CWSB::isFree == 0)) ;
00239 memset(constraintStatus_,0,constatsze) ; }
00240
00251 void ODWSB::resize (int numRows, int numCols)
00252
00253 { int concnt = getNumArtificial() ;
00254
00255 CWSB::resize(numRows,numCols) ;
00256
00257 if (numRows != concnt)
00258 { int oldsze = STATBYTES(concnt) ;
00259 int newsze = STATBYTES(numRows) ;
00260 char *newStat = new char[newsze] ;
00261
00262
00263
00264 if (oldsze > newsze)
00265 { memcpy(newStat,constraintStatus_,newsze) ; }
00266
00267
00268
00269
00270
00271
00272 else
00273 { char byteActive = 0 ;
00274 int i,actualBytes ;
00275 actualBytes = concnt/STATPERBYTE ;
00276 for (i = 0 ; i <= 3 ; i++) setStatus(&byteActive,i,CWSB::atLowerBound) ;
00277 memcpy(newStat,constraintStatus_,oldsze) ;
00278 memset(newStat+actualBytes,byteActive,newsze-actualBytes) ;
00279 for (i = 0 ; i < concnt%STATPERBYTE ; i++)
00280 setStatus(newStat+actualBytes,i,
00281 getStatus(constraintStatus_+actualBytes,i)) ; }
00282
00283 delete [] constraintStatus_ ;
00284 constraintStatus_ = newStat ; } }
00285
00286
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 void ODWSB::deleteRows (int number, const int *which)
00303
00304 { int oldconcnt = getNumArtificial() ;
00305 int i,k ;
00306
00307 CWSB::deleteRows(number,which) ;
00308
00309 int delcnt = 0 ;
00310 vector<bool> deleted = vector<bool>(oldconcnt) ;
00311 for (k = 0 ; k < number ; k++)
00312 { i = which[k] ;
00313 if (i >= 0 && i < oldconcnt && !deleted[i])
00314 { delcnt++ ;
00315 deleted[i] = true ; } }
00316
00317 int newsze = STATBYTES(oldconcnt-delcnt) ;
00318 char *newStat = new char[newsze] ;
00319
00320 k = 0 ;
00321 for (i = 0 ; i < oldconcnt ; i++)
00322 { Status status = getConStatus(i);
00323 if (!deleted[i])
00324 { setStatus(newStat,k,status) ;
00325 k++ ; } }
00326
00327 delete [] constraintStatus_ ;
00328 constraintStatus_ = newStat ; }
00329
00330
00331
00332
00333
00335
00341
00347 int ODWSB::numberActiveConstraints () const
00348
00349 { int i ;
00350 int concnt = getNumArtificial() ;
00351 int actcnt = 0 ;
00352
00353 for (i = 0 ; i < concnt ; i++)
00354 if (getStatus(constraintStatus_,i) == CWSB::atLowerBound) actcnt++ ;
00355
00356 return (actcnt) ; }
00357
00363
00373 CoinWarmStartDiff *ODWSB::generateDiff
00374 (const CoinWarmStart *const oldCWS) const
00375 {
00376
00377
00378
00379 const OsiDylpWarmStartBasis *oldBasis =
00380 dynamic_cast<const OsiDylpWarmStartBasis *>(oldCWS) ;
00381 if (!oldBasis)
00382 { throw CoinError("Old basis not OsiDylpWarmStartBasis.",
00383 "generateDiff","OsiDylpWarmStartBasis") ; }
00384 const OsiDylpWarmStartBasis *newBasis = this ;
00385
00386
00387
00388
00389 const int oldArtifCnt = oldBasis->getNumArtificial() ;
00390 const int newArtifCnt = newBasis->getNumArtificial() ;
00391
00392 assert(newArtifCnt >= oldArtifCnt) ;
00393
00394
00395
00396
00397 const CoinWarmStartBasisDiff *cwsbDiff =
00398 dynamic_cast<const CoinWarmStartBasisDiff *>(CWSB::generateDiff(oldCWS)) ;
00399
00400
00401
00402
00403 int sizeOldArtif = (oldArtifCnt+15)>>4 ;
00404 int sizeNewArtif = (newArtifCnt+15)>>4 ;
00405 int maxBasisLength = sizeNewArtif ;
00406
00407 unsigned int *diffNdx = new unsigned int [maxBasisLength];
00408 unsigned int *diffVal = new unsigned int [maxBasisLength];
00409
00410
00411
00412
00413
00414 const unsigned int *oldStatus =
00415 reinterpret_cast<const unsigned int *>(oldBasis->getConstraintStatus()) ;
00416 const unsigned int *newStatus =
00417 reinterpret_cast<const unsigned int *>(newBasis->getConstraintStatus()) ;
00418 int numberChanged = 0 ;
00419 int i ;
00420 for (i = 0 ; i < sizeOldArtif ; i++)
00421 { if (oldStatus[i] != newStatus[i])
00422 { diffNdx[numberChanged] = i ;
00423 diffVal[numberChanged++] = newStatus[i] ; } }
00424 for ( ; i < sizeNewArtif ; i++)
00425 { diffNdx[numberChanged] = i ;
00426 diffVal[numberChanged++] = newStatus[i] ; }
00427
00428
00429
00430 OsiDylpWarmStartBasisDiff *diff =
00431 new OsiDylpWarmStartBasisDiff(numberChanged,diffNdx,diffVal,cwsbDiff) ;
00432
00433
00434
00435 delete[] diffNdx ;
00436 delete[] diffVal ;
00437
00438 return (dynamic_cast<CoinWarmStartDiff *>(diff)) ; }
00439
00448 void ODWSB::applyDiff (const CoinWarmStartDiff *const cwsdDiff)
00449 {
00450
00451
00452
00453 const OsiDylpWarmStartBasisDiff *diff =
00454 dynamic_cast<const OsiDylpWarmStartBasisDiff *>(cwsdDiff) ;
00455 if (!diff)
00456 { throw CoinError("Diff not OsiDylpWarmStartBasisDiff.",
00457 "applyDiff","OsiDylpWarmStartBasis") ; }
00458
00459
00460
00461 CWSB::applyDiff(cwsdDiff) ;
00462
00463
00464
00465
00466 const int numberChanges = diff->consze_ ;
00467 const unsigned int *diffNdxs = diff->condiffNdxs_ ;
00468 const unsigned int *diffVals = diff->condiffVals_ ;
00469 unsigned int *constraintStatus =
00470 reinterpret_cast<unsigned int *>(this->getConstraintStatus()) ;
00471
00472 for (int i = 0 ; i < numberChanges ; i++)
00473 { unsigned int diffNdx = diffNdxs[i] ;
00474 unsigned int diffVal = diffVals[i] ;
00475 constraintStatus[diffNdx] = diffVal ; }
00476
00477 return ; }
00478
00480
00481
00487
00493 void ODWSB::print () const
00494
00495 { char conlett[] = {'I','?','?','A'} ;
00496 char statlett[] = {'F','B','U','L'} ;
00497 int i,basic_logicals,basic_structurals ;
00498
00499 std::cout << "ODWSB: " ;
00500 std::cout << getNumArtificial() << " constraints (" <<
00501 numberActiveConstraints() << " active), " ;
00502 std::cout << getNumStructural() << " variables." << std::endl ;
00503
00504 std::cout << "Rows: " ;
00505 for (i = 0 ; i < getNumArtificial() ; i++)
00506 { std::cout << conlett[getConStatus(i)] ; }
00507 std::cout << std::endl ;
00508
00509 std::cout << " " ;
00510 basic_logicals = 0 ;
00511 for (i = 0 ; i < getNumArtificial() ; i++)
00512 { std::cout << statlett[getArtifStatus(i)] ;
00513 if (getArtifStatus(i) == CWSB::basic) basic_logicals++ ; }
00514 std::cout << std::endl ;
00515
00516 std::cout << "Cols: " ;
00517 basic_structurals = 0 ;
00518 for (i = 0 ; i < getNumStructural() ; i++)
00519 { std::cout << statlett[getStructStatus(i)] ;
00520 if (getStructStatus(i) == CWSB::basic) basic_structurals++ ; }
00521
00522 std::cout << std::endl << " basic: ("
00523 << basic_structurals << " + " << basic_logicals << ")" ;
00524 std::cout << std::endl ;
00525
00526 return ; }
00527
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 OsiDylpWarmStartBasisDiff::OsiDylpWarmStartBasisDiff (int sze,
00540 const unsigned int *const diffNdxs, const unsigned int *const diffVals,
00541 const CoinWarmStartBasisDiff *const cwsbd)
00542
00543 : CoinWarmStartBasisDiff(*cwsbd),
00544 consze_(sze),
00545 condiffNdxs_(0),
00546 condiffVals_(0)
00547
00548 { if (sze > 0)
00549 { condiffNdxs_ = new unsigned int[sze] ;
00550 memcpy(condiffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ;
00551 condiffVals_ = new unsigned int[sze] ;
00552 memcpy(condiffVals_,diffVals,sze*sizeof(unsigned int)) ; }
00553
00554 return ; }
00555
00556
00557
00558
00559 OsiDylpWarmStartBasisDiff::OsiDylpWarmStartBasisDiff
00560 (const OsiDylpWarmStartBasisDiff &odwsbd)
00561 : CoinWarmStartBasisDiff(odwsbd),
00562 consze_(odwsbd.consze_),
00563 condiffNdxs_(0),
00564 condiffVals_(0)
00565 { if (odwsbd.consze_ > 0)
00566 { condiffNdxs_ = new unsigned int[odwsbd.consze_] ;
00567 memcpy(condiffNdxs_,odwsbd.condiffNdxs_,
00568 odwsbd.consze_*sizeof(unsigned int)) ;
00569 condiffVals_ = new unsigned int[odwsbd.consze_] ;
00570 memcpy(condiffVals_,odwsbd.condiffVals_,
00571 odwsbd.consze_*sizeof(unsigned int)) ; }
00572
00573 return ; }
00574
00575
00576
00577
00578
00579 OsiDylpWarmStartBasisDiff&
00580 OsiDylpWarmStartBasisDiff::operator= (const OsiDylpWarmStartBasisDiff &rhs)
00581
00582 { if (this != &rhs)
00583 { CoinWarmStartBasisDiff::operator=(rhs) ;
00584 if (consze_ > 0)
00585 { delete[] condiffNdxs_ ;
00586 delete[] condiffVals_ ; }
00587 consze_ = rhs.consze_ ;
00588 if (consze_ > 0)
00589 { condiffNdxs_ = new unsigned int[consze_] ;
00590 memcpy(condiffNdxs_,rhs.condiffNdxs_,consze_*sizeof(unsigned int)) ;
00591 condiffVals_ = new unsigned int[consze_] ;
00592 memcpy(condiffVals_,rhs.condiffVals_,consze_*sizeof(unsigned int)) ; }
00593 else
00594 { condiffNdxs_ = 0 ;
00595 condiffVals_ = 0 ; } }
00596
00597 return (*this) ; }
00598
00599
00600 #endif // COIN_USE_DYLP
00601