00001
00002
00003 #include <stdio.h>
00004 #include <math.h>
00005
00006 #include "CoinPresolveMatrix.hpp"
00007 #include "CoinPresolveEmpty.hpp"
00008 #include "CoinPresolveFixed.hpp"
00009 #include "CoinPresolveSubst.hpp"
00010 #include "CoinPresolveUseless.hpp"
00011 #include "CoinPresolveForcing.hpp"
00012 #include "CoinMessage.hpp"
00013
00014 #if 0
00015 inline double max(double x, double y)
00016 {
00017 return (x < y) ? y : x;
00018 }
00019
00020 inline double min(double x, double y)
00021 {
00022 return (x < y) ? x : y;
00023 }
00024 #endif
00025
00026 void implied_bounds(const double *els,
00027 const double *clo, const double *cup,
00028 const int *hcol,
00029 CoinBigIndex krs, CoinBigIndex kre,
00030 double *maxupp, double *maxdownp,
00031 int jcol,
00032 double rlo, double rup,
00033 double *iclb, double *icub)
00034 {
00035 if (rlo<=-PRESOLVE_INF&&rup>=PRESOLVE_INF) {
00036 *iclb = -PRESOLVE_INF;
00037 *icub = PRESOLVE_INF;
00038 return;
00039 }
00040 bool posinf = false;
00041 bool neginf = false;
00042 double maxup = 0.0;
00043 double maxdown = 0.0;
00044
00045 int jcolk = -1;
00046
00047
00048 CoinBigIndex kk;
00049 for (kk=krs; kk<kre; kk++) {
00050 if (hcol[kk] == jcol)
00051 jcolk = kk;
00052
00053
00054
00055
00056 CoinBigIndex k = (hcol[kk] == jcol
00057 ? kre-1
00058 : kk == kre-1
00059 ? jcolk
00060 : kk);
00061
00062 PRESOLVEASSERT(k != -1);
00063
00064 int col = hcol[k];
00065 double coeff = els[k];
00066 double lb = clo[col];
00067 double ub = cup[col];
00068
00069
00070 if (kk == kre-1) {
00071 PRESOLVEASSERT(fabs(coeff) > ZTOLDP);
00072
00073 double ilb = (rlo - maxup) / coeff;
00074 bool finite_ilb = (-PRESOLVE_INF < rlo && !posinf && PRESOLVEFINITE(maxup));
00075
00076 double iub = (rup - maxdown) / coeff;
00077 bool finite_iub = ( rup < PRESOLVE_INF && !neginf && PRESOLVEFINITE(maxdown));
00078
00079 if (coeff > 0.0) {
00080 *iclb = (finite_ilb ? ilb : -PRESOLVE_INF);
00081 *icub = (finite_iub ? iub : PRESOLVE_INF);
00082 } else {
00083 *iclb = (finite_iub ? iub : -PRESOLVE_INF);
00084 *icub = (finite_ilb ? ilb : PRESOLVE_INF);
00085 }
00086 }
00087
00088 if (coeff > 0.0) {
00089 if (PRESOLVE_INF <= ub) {
00090 posinf = true;
00091 if (neginf)
00092 break;
00093 } else
00094 maxup += ub * coeff;
00095
00096 if (lb <= -PRESOLVE_INF) {
00097 neginf = true;
00098 if (posinf)
00099 break;
00100 } else
00101 maxdown += lb * coeff;
00102 } else {
00103 if (PRESOLVE_INF <= ub) {
00104 neginf = true;
00105 if (posinf)
00106 break;
00107 } else
00108 maxdown += ub * coeff;
00109
00110 if (lb <= -PRESOLVE_INF) {
00111 posinf = true;
00112 if (neginf)
00113 break;
00114 } else
00115 maxup += lb * coeff;
00116 }
00117 }
00118
00119
00120
00121
00122
00123 if (kk<kre-1) {
00124 *iclb = -PRESOLVE_INF;
00125 *icub = PRESOLVE_INF;
00126 } else
00127 PRESOLVEASSERT(jcolk != -1);
00128
00129
00130 *maxupp = (posinf) ? PRESOLVE_INF : maxup;
00131 *maxdownp = (neginf) ? -PRESOLVE_INF : maxdown;
00132 }
00133
00134 static void implied_row_bounds(const double *els,
00135 const double *clo, const double *cup,
00136 const int *hcol,
00137 CoinBigIndex krs, CoinBigIndex kre,
00138 double *maxupp, double *maxdownp)
00139 {
00140
00141 double iclb, icub;
00142
00143 implied_bounds(els, clo, cup, hcol, krs, kre, maxupp, maxdownp,
00144 hcol[krs], 0.0, 0.0, &iclb, &icub);
00145 }
00146
00147 const char *forcing_constraint_action::name() const
00148 {
00149 return ("forcing_constraint_action");
00150 }
00151
00152 static bool some_col_was_fixed(const int *hcol, CoinBigIndex krs, CoinBigIndex kre,
00153 const double *clo,
00154 const double *cup)
00155 {
00156 CoinBigIndex k;
00157 for (k=krs; k<kre; k++) {
00158 int jcol = hcol[k];
00159 if (clo[jcol] == cup[jcol])
00160 break;
00161 }
00162 return (k<kre);
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 const CoinPresolveAction *forcing_constraint_action::presolve(CoinPresolveMatrix *prob,
00196 const CoinPresolveAction *next)
00197 {
00198 double *clo = prob->clo_;
00199 double *cup = prob->cup_;
00200
00201 const double *rowels = prob->rowels_;
00202 const int *hcol = prob->hcol_;
00203 const CoinBigIndex *mrstrt = prob->mrstrt_;
00204 const int *hinrow = prob->hinrow_;
00205 const int nrows = prob->nrows_;
00206
00207 const double *rlo = prob->rlo_;
00208 const double *rup = prob->rup_;
00209
00210
00211
00212 const double tol = ZTOLDP;
00213 const double inftol = prob->feasibilityTolerance_;
00214 const int ncols = prob->ncols_;
00215
00216 int *fixed_cols = new int[ncols];
00217 int nfixed_cols = 0;
00218
00219 action *actions = new action [nrows];
00220 int nactions = 0;
00221
00222 int *useless_rows = new int[nrows];
00223 int nuseless_rows = 0;
00224
00225 int numberLook = prob->numberRowsToDo_;
00226 int iLook;
00227 int * look = prob->rowsToDo_;
00228
00229 for (iLook=0;iLook<numberLook;iLook++) {
00230 int irow = look[iLook];
00231 if (hinrow[irow] > 0) {
00232 CoinBigIndex krs = mrstrt[irow];
00233 CoinBigIndex kre = krs + hinrow[irow];
00234
00235 double maxup, maxdown;
00236 implied_row_bounds(rowels, clo, cup, hcol, krs, kre,
00237 &maxup, &maxdown);
00238
00239 if (maxup < PRESOLVE_INF && maxup + inftol < rlo[irow]) {
00240
00241 prob->status_|= 1;
00242 prob->messageHandler()->message(COIN_PRESOLVE_ROWINFEAS,
00243 prob->messages())
00244 <<irow
00245 <<rlo[irow]
00246 <<rup[irow]
00247 <<CoinMessageEol;
00248 break;
00249 } else if (-PRESOLVE_INF < maxdown && rup[irow] < maxdown - inftol) {
00250
00251 prob->status_|= 1;
00252 prob->messageHandler()->message(COIN_PRESOLVE_ROWINFEAS,
00253 prob->messages())
00254 <<irow
00255 <<rlo[irow]
00256 <<rup[irow]
00257 <<CoinMessageEol;
00258 break;
00259 }
00260
00261 else if ((rlo[irow] <= -PRESOLVE_INF ||
00262 (-PRESOLVE_INF < maxdown && rlo[irow] <= maxdown)) &&
00263 (rup[irow] >= PRESOLVE_INF ||
00264 (maxup < PRESOLVE_INF && rup[irow] >= maxup))) {
00265
00266
00267
00268 if (some_col_was_fixed(hcol, krs, kre, clo, cup)) {
00269
00270 prob->addRow(irow);
00271 continue;
00272 }
00273
00274
00275 useless_rows[nuseless_rows++] = irow;
00276
00277 } else if ((maxup < PRESOLVE_INF && fabs(rlo[irow] - maxup) < tol) ||
00278 (-PRESOLVE_INF < maxdown && fabs(rup[irow] - maxdown) < tol)) {
00279
00280
00281
00282
00283 const int lbound_tight = (maxup < PRESOLVE_INF &&
00284 fabs(rlo[irow] - maxup) < tol);
00285
00286
00287
00288 if (some_col_was_fixed(hcol, krs, kre, clo, cup)) {
00289
00290 prob->addRow(irow);
00291 continue;
00292 }
00293
00294
00295 if (nfixed_cols + (kre-krs) >= ncols)
00296 break;
00297
00298 double *bounds = new double[hinrow[irow]];
00299 int *rowcols = new int[hinrow[irow]];
00300 int lk = krs;
00301 int uk = kre;
00302 CoinBigIndex k;
00303 for ( k=krs; k<kre; k++) {
00304 int jcol = hcol[k];
00305 prob->addCol(jcol);
00306 double coeff = rowels[k];
00307
00308 PRESOLVEASSERT(fabs(coeff) > ZTOLDP);
00309
00310
00311 if (lbound_tight == (coeff > 0.0)) {
00312 --uk;
00313 bounds[uk-krs] = clo[jcol];
00314 rowcols[uk-krs] = jcol;
00315
00316 clo[jcol] = cup[jcol];
00317 } else {
00318 bounds[lk-krs] = cup[jcol];
00319 rowcols[lk-krs] = jcol;
00320 ++lk;
00321
00322 cup[jcol] = clo[jcol];
00323 }
00324
00325 fixed_cols[nfixed_cols++] = jcol;
00326 }
00327 PRESOLVEASSERT(uk == lk);
00328
00329 action *f = &actions[nactions];
00330 nactions++;
00331
00332 f->row = irow;
00333 f->nlo = lk-krs;
00334 f->nup = kre-uk;
00335 f->rowcols = rowcols;
00336 f->bounds = bounds;
00337 }
00338 }
00339 }
00340
00341
00342 if (nactions) {
00343 #if PRESOLVE_SUMMARY
00344 printf("NFORCED: %d\n", nactions);
00345 #endif
00346 next = new forcing_constraint_action(nactions,
00347 copyOfArray(actions,nactions), next);
00348 }
00349 deleteAction(actions,action*);
00350 if (nuseless_rows) {
00351 next = useless_constraint_action::presolve(prob,
00352 useless_rows, nuseless_rows,
00353 next);
00354 }
00355 delete[]useless_rows;
00356
00357 if (nfixed_cols) {
00358 next = remove_fixed_action::presolve(prob, fixed_cols, nfixed_cols, next);
00359 }
00360 delete[]fixed_cols;
00361
00362 return (next);
00363 }
00364
00365 void forcing_constraint_action::postsolve(CoinPostsolveMatrix *prob) const
00366 {
00367 const action *const actions = actions_;
00368 const int nactions = nactions_;
00369
00370 const double *colels = prob->colels_;
00371 const int *hrow = prob->hrow_;
00372 const CoinBigIndex *mcstrt = prob->mcstrt_;
00373 const int *hincol = prob->hincol_;
00374 const int *link = prob->link_;
00375
00376
00377
00378 double *clo = prob->clo_;
00379 double *cup = prob->cup_;
00380
00381 const double *sol = prob->sol_;
00382 double *rcosts = prob->rcosts_;
00383
00384
00385 double *rowduals = prob->rowduals_;
00386
00387 const double ztoldj = prob->ztoldj_;
00388 const double ztolzb = prob->ztolzb_;
00389
00390 for (const action *f = &actions[nactions-1]; actions<=f; f--) {
00391
00392 const int irow = f->row;
00393 const int nlo = f->nlo;
00394 const int nup = f->nup;
00395 const int ninrow = nlo + nup;
00396 const int *rowcols = f->rowcols;
00397 const double *bounds= f->bounds;
00398 int k;
00399
00400 for (k=0; k<nlo; k++) {
00401 int jcol = rowcols[k];
00402 cup[jcol] = bounds[k];
00403 PRESOLVEASSERT(prob->getColumnStatus(jcol)!=CoinPrePostsolveMatrix::basic);
00404 }
00405
00406 for (k=nlo; k<ninrow; k++) {
00407 int jcol = rowcols[k];
00408 clo[jcol] = bounds[k];
00409 PRESOLVEASSERT(prob->getColumnStatus(jcol)!=CoinPrePostsolveMatrix::basic);
00410 }
00411
00412 PRESOLVEASSERT(prob->getRowStatus(irow)==CoinPrePostsolveMatrix::basic);
00413 PRESOLVEASSERT(rowduals[irow] == 0.0);
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 int whacked = -1;
00425 double whack = 0.0;
00426 for (k=0; k<ninrow; k++) {
00427 int jcol = rowcols[k];
00428 CoinBigIndex kk = presolve_find_row2(irow, mcstrt[jcol], hincol[jcol], hrow, link);
00429
00430
00431 double whack0 = rcosts[jcol] / colels[kk];
00432
00433 if (((rcosts[jcol] > ztoldj && !(fabs(sol[jcol] - clo[jcol]) <= ztolzb)) ||
00434 (rcosts[jcol] < -ztoldj && !(fabs(sol[jcol] - cup[jcol]) <= ztolzb))) &&
00435 fabs(whack0) > fabs(whack)) {
00436 whacked = jcol;
00437 whack = whack0;
00438 }
00439 }
00440
00441 if (whacked != -1) {
00442 prob->setColumnStatus(whacked,CoinPrePostsolveMatrix::basic);
00443 prob->setRowStatus(irow,CoinPrePostsolveMatrix::atLowerBound);
00444 rowduals[irow] = whack;
00445
00446 for (k=0; k<ninrow; k++) {
00447 int jcol = rowcols[k];
00448 CoinBigIndex kk = presolve_find_row2(irow, mcstrt[jcol], hincol[jcol], hrow, link);
00449
00450 rcosts[jcol] -= (rowduals[irow] * colels[kk]);
00451 }
00452 }
00453 }
00454 }
00455
00456
00457
00458 #if 0
00459
00460
00461
00462
00463
00464
00465 static void implied_bounds1(CoinPresolveMatrix * prob, const double *rowels,
00466 const int *mrstrt,
00467 const int *hrow,
00468 const int *hinrow,
00469 const double *clo, const double *cup,
00470 const int *hcol,
00471 int ncols,
00472 const double *rlo, const double *rup,
00473 const char *integerType,
00474 int nrows,
00475 double *ilbound, double *iubound)
00476 {
00477 const double tol = prob->feasibilityTolerance_;
00478
00479 for (int irow=0; irow<nrows; irow++) {
00480 CoinBigIndex krs = mrstrt[irow];
00481 CoinBigIndex kre = krs + hinrow[irow];
00482
00483 double irlo = rlo[irow];
00484 double irup = rup[irow];
00485
00486
00487
00488
00489
00490
00491 int ub_inf_index = -1;
00492 int lb_inf_index = -1;
00493
00494 double maxup = 0.0;
00495 double maxdown = 0.0;
00496 CoinBigIndex k;
00497 for (k=krs; k<kre; k++) {
00498 int jcol = hcol[k];
00499 double coeff = rowels[k];
00500 double lb = clo[jcol];
00501 double ub = cup[jcol];
00502
00503
00504 if (coeff > 0.0) {
00505 if (PRESOLVE_INF <= ub) {
00506 if (ub_inf_index == -1) {
00507 ub_inf_index = k;
00508 } else {
00509 ub_inf_index = -2;
00510 if (lb_inf_index == -2)
00511 break;
00512 }
00513 } else
00514 maxup += ub * coeff;
00515
00516 if (lb <= -PRESOLVE_INF) {
00517 if (lb_inf_index == -1) {
00518 lb_inf_index = k;
00519 } else {
00520 lb_inf_index = -2;
00521 if (ub_inf_index == -2)
00522 break;
00523 }
00524 } else
00525 maxdown += lb * coeff;
00526 }
00527 else {
00528 if (PRESOLVE_INF <= ub) {
00529 if (lb_inf_index == -1) {
00530 lb_inf_index = k;
00531 } else {
00532 lb_inf_index = -2;
00533 if (ub_inf_index == -2)
00534 break;
00535 }
00536 } else
00537 maxdown += ub * coeff;
00538
00539 if (lb <= -PRESOLVE_INF) {
00540 if (ub_inf_index == -1) {
00541 ub_inf_index = k;
00542 } else {
00543 ub_inf_index = -2;
00544 if (lb_inf_index == -2)
00545 break;
00546 }
00547 } else
00548 maxup += lb * coeff;
00549 }
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559 if (ub_inf_index == -2)
00560 maxup = PRESOLVE_INF;
00561
00562 if (lb_inf_index == -2)
00563 maxdown = -PRESOLVE_INF;
00564
00565 const bool maxup_finite = PRESOLVEFINITE(maxup);
00566 const bool maxdown_finite = PRESOLVEFINITE(maxdown);
00567
00568 if (ub_inf_index == -1 && maxup_finite && maxup + tol < rlo[irow]) {
00569
00570 prob->status_|= 1;
00571 prob->messageHandler()->message(COIN_PRESOLVE_ROWINFEAS,
00572 prob->messages())
00573 <<irow
00574 <<rlo[irow]
00575 <<rup[irow]
00576 <<CoinMessageEol;
00577 break;
00578 } else if (lb_inf_index == -1 && maxdown_finite && rup[irow] < maxdown - tol) {
00579
00580 prob->status_|= 1;
00581 prob->messageHandler()->message(COIN_PRESOLVE_ROWINFEAS,
00582 prob->messages())
00583 <<irow
00584 <<rlo[irow]
00585 <<rup[irow]
00586 <<CoinMessageEol;
00587 break;
00588 }
00589
00590 for (k = krs; k<kre; ++k) {
00591 int jcol = hcol[k];
00592 double coeff = rowels[k];
00593
00594
00595 if (fabs(coeff) > ZTOLDP &&
00596 !integerType[jcol]) {
00597 double maxup1 = (ub_inf_index == -1 || ub_inf_index == k
00598 ? maxup
00599 : PRESOLVE_INF);
00600 bool maxup_finite1 = (ub_inf_index == -1 || ub_inf_index == k
00601 ? maxup_finite
00602 : false);
00603 double maxdown1 = (lb_inf_index == -1 || lb_inf_index == k
00604 ? maxdown
00605 : PRESOLVE_INF);
00606 bool maxdown_finite1 = (ub_inf_index == -1 || ub_inf_index == k
00607 ? maxdown_finite
00608 : false);
00609
00610 double ilb = (irlo - maxup1) / coeff;
00611 bool finite_ilb = (-PRESOLVE_INF < irlo && maxup_finite1);
00612
00613 double iub = (irup - maxdown1) / coeff;
00614 bool finite_iub = ( irup < PRESOLVE_INF && maxdown_finite1);
00615
00616 double ilb1 = (coeff > 0.0
00617 ? (finite_ilb ? ilb : -PRESOLVE_INF)
00618 : (finite_iub ? iub : -PRESOLVE_INF));
00619
00620 if (ilbound[jcol] < ilb1) {
00621 ilbound[jcol] = ilb1;
00622 if (jcol == 278001)
00623 printf("JCOL LB %g\n", ilb1);
00624 }
00625 }
00626 }
00627
00628 for (k = krs; k<kre; ++k) {
00629 int jcol = hcol[k];
00630 double coeff = rowels[k];
00631
00632
00633 if (fabs(coeff) > ZTOLDP &&
00634 !integerType[jcol]) {
00635 double maxup1 = (ub_inf_index == -1 || ub_inf_index == k
00636 ? maxup
00637 : PRESOLVE_INF);
00638 bool maxup_finite1 = (ub_inf_index == -1 || ub_inf_index == k
00639 ? maxup_finite
00640 : false);
00641 double maxdown1 = (lb_inf_index == -1 || lb_inf_index == k
00642 ? maxdown
00643 : PRESOLVE_INF);
00644 bool maxdown_finite1 = (ub_inf_index == -1 || ub_inf_index == k
00645 ? maxdown_finite
00646 : false);
00647
00648
00649 double ilb = (irlo - maxup1) / coeff;
00650 bool finite_ilb = (-PRESOLVE_INF < irlo && maxup_finite1);
00651
00652 double iub = (irup - maxdown1) / coeff;
00653 bool finite_iub = ( irup < PRESOLVE_INF && maxdown_finite1);
00654
00655 double iub1 = (coeff > 0.0
00656 ? (finite_iub ? iub : PRESOLVE_INF)
00657 : (finite_ilb ? ilb : PRESOLVE_INF));
00658
00659 if (iub1 < iubound[jcol]) {
00660 iubound[jcol] = iub1;
00661 if (jcol == 278001)
00662 printf("JCOL UB %g\n", iub1);
00663 }
00664 }
00665 }
00666 }
00667 }
00668
00669 #if 0
00670 postsolve for implied_bound
00671 {
00672 double lo0 = pa->clo;
00673 double up0 = pa->cup;
00674 int irow = pa->irow;
00675 int jcol = pa->icol;
00676 int *rowcols = pa->rowcols;
00677 int ninrow = pa->ninrow;
00678
00679 clo[jcol] = lo0;
00680 cup[jcol] = up0;
00681
00682 if ((colstat[jcol] & PRESOLVE_XBASIC) == 0 &&
00683 fabs(lo0 - sol[jcol]) > ztolzb &&
00684 fabs(up0 - sol[jcol]) > ztolzb) {
00685
00686
00687
00688
00689
00690
00691 if (rowstat[irow] & PRESOLVE_XBASIC)
00692 rowstat[irow] = 0;
00693 else {
00694 int k;
00695 for (k=0; k<ninrow; k++) {
00696 int col = rowcols[k];
00697 if (cdone[col] &&
00698 (colstat[col] & PRESOLVE_XBASIC) &&
00699 ((fabs(clo[col] - sol[col]) <= ztolzb && rcosts[col] >= -ztoldj) ||
00700 (fabs(cup[col] - sol[col]) <= ztolzb && rcosts[col] <= ztoldj)))
00701 break;
00702 }
00703 if (k<ninrow) {
00704 int col = rowcols[k];
00705
00706 #if DEBUG_PRESOLVE
00707 printf("PIVOTING ON COL: %d %d -> %d\n", irow, col, jcol);
00708 #endif
00709 colstat[col] = 0;
00710
00711
00712 PRESOLVEASSERT(fabs(acts[irow]) < ZTOLDP);
00713 rowstat[irow] = PRESOLVE_XBASIC;
00714 }
00715 else {
00716
00717 abort();
00718 }
00719
00720
00721
00722 abort();
00724 }
00725
00726 double rdual_adjust;
00727 {
00728 CoinBigIndex kk = presolve_find_row(irow, mcstrt[jcol], mcstrt[jcol] + hincol[jcol], hrow);
00729
00730
00731 rdual_adjust = (rcosts[jcol] / colels[kk]);
00732 rowduals[irow] += rdual_adjust;
00733 colstat[jcol] = PRESOLVE_XBASIC;
00734 }
00735
00736 for (k=0; k<ninrow; k++) {
00737 int jcol = rowcols[k];
00738 CoinBigIndex kk = presolve_find_row(irow, mcstrt[jcol], mcstrt[jcol] + hincol[jcol], hrow);
00739
00740 rcosts[jcol] -= (rdual_adjust * colels[kk]);
00741 }
00742
00743 {
00744 int k;
00745 int badbasic = -1;
00746
00747
00748 for (k=0; k<ninrow; k++) {
00749 int col = rowcols[k];
00750 if (col != jcol &&
00751 cdone[col] &&
00752 (colstat[col] & PRESOLVE_XBASIC) &&
00753 !(fabs(rcosts[col]) < ztoldj))
00754 if (badbasic == -1)
00755 badbasic = k;
00756 else
00757 abort();
00758 }
00759
00760 if (badbasic != -1) {
00761 int col = rowcols[badbasic];
00762
00763 if (fabs(acts[irow]) < ZTOLDP) {
00764 #if DEBUG_PRESOLVE
00765 printf("PIVOTING COL TO SLACK!: %d %d\n", irow, col);
00766 #endif
00767 colstat[col] = 0;
00768 rowstat[irow] = PRESOLVE_XBASIC;
00769 }
00770 else
00771 abort();
00772 }
00773 }
00774 }
00775 }
00776 #endif
00777 #endif
00778 forcing_constraint_action::~forcing_constraint_action()
00779 {
00780 int i;
00781 for (i=0;i<nactions_;i++) {
00782
00783
00784 deleteAction(actions_[i].rowcols,int *);
00785 deleteAction(actions_[i].bounds,double *);
00786 }
00787
00788 deleteAction(actions_,action *);
00789 }
00790
00791
00792