source: trunk/Alps/examples/Abc/AbcCutGenerator.cpp @ 277

Last change on this file since 277 was 277, checked in by andreasw, 13 years ago

first working version with autotools

File size: 5.6 KB
Line 
1/*===========================================================================*
2 * This file is part of the Abstract Library for Parallel Search (ALPS).     *
3 *                                                                           *
4 * ALPS is distributed under the Common Public License as part of the        *
5 * COIN-OR repository (http://www.coin-or.org).                              *
6 *                                                                           *
7 * Authors: Yan Xu, SAS Institute Inc.                                       *
8 *          Ted Ralphs, Lehigh University                                    *
9 *          Laszlo Ladanyi, IBM T.J. Watson Research Center                  *
10 *          Matthew Saltzman, Clemson University                             *
11 *                                                                           *
12 *                                                                           *
13 * Copyright (C) 2001-2004, International Business Machines                  *
14 * Corporation, Lehigh University, Yan Xu, Ted Ralphs, Matthew Salzman and   *
15 * others. All Rights Reserved.                                              *
16 *===========================================================================*/
17
18//#############################################################################
19// This file is modified from SbbCutGenerator.cpp
20//#############################################################################
21
22#if defined(_MSC_VER)
23// Turn off compiler warning about long names
24#  pragma warning(disable:4786)
25#endif
26#include <cassert>
27#include <cmath>
28#include <cfloat>
29
30#include "OsiSolverInterface.hpp"
31#include "CglProbing.hpp"
32
33#include "AbcModel.h"
34#include "AbcMessage.h"
35#include "AbcCutGenerator.h"
36
37
38// Default Constructor
39AbcCutGenerator::AbcCutGenerator ()
40    : model_(NULL),
41      generator_(NULL),
42      whenCutGenerator_(-1),
43      generatorName_(NULL),
44      normal_(true),
45      atSolution_(false),
46      whenInfeasible_(false)
47{
48}
49// Normal constructor
50AbcCutGenerator::AbcCutGenerator(AbcModel * model,CglCutGenerator * generator,
51                                 int howOften, const char * name,
52                                 bool normal, bool atSolution, 
53                                 bool infeasible)
54{
55    model_ = model;
56    generator_ = generator;
57    generator_->refreshSolver(model_->solver());
58    whenCutGenerator_ = howOften;
59    if (name)
60        generatorName_ = strdup(name);
61    else
62        generatorName_ = strdup("Unknown");
63    normal_ = normal;
64    atSolution_ = atSolution;
65    whenInfeasible_ = infeasible;
66}
67
68// Copy constructor
69AbcCutGenerator::AbcCutGenerator ( const AbcCutGenerator & rhs)
70{
71    model_ = rhs.model_;
72    generator_ = rhs.generator_;
73    generator_->refreshSolver(model_->solver());
74    whenCutGenerator_ = rhs.whenCutGenerator_;
75    generatorName_ = strdup(rhs.generatorName_);
76    normal_ = rhs.normal_;
77    atSolution_ = rhs.atSolution_;
78    whenInfeasible_ = rhs.whenInfeasible_;
79}
80
81// Assignment operator
82AbcCutGenerator & 
83AbcCutGenerator::operator=( const AbcCutGenerator& rhs)
84{
85    if (this != &rhs) {
86        delete generator_;
87        free(generatorName_);
88        model_ = rhs.model_;
89        generator_ = rhs.generator_;
90        generator_->refreshSolver(model_->solver());
91        whenCutGenerator_ = rhs.whenCutGenerator_;
92        generatorName_ = strdup(rhs.generatorName_);
93        normal_ = rhs.normal_;
94        atSolution_ = rhs.atSolution_;
95        whenInfeasible_ = rhs.whenInfeasible_;
96    }
97    return *this;
98}
99
100// Destructor
101AbcCutGenerator::~AbcCutGenerator ()
102{
103    free(generatorName_);
104}
105
106/* This is used to refresh any inforamtion.
107   It also refreshes the solver in the cut generator
108   in case generator wants to do some work
109*/
110void 
111AbcCutGenerator::refreshModel(AbcModel * model)
112{
113    model_ = model;
114    generator_->refreshSolver(model_->solver());
115}
116/* Generate cuts for the model data contained in si.
117   The generated cuts are inserted into and returned in the
118   collection of cuts cs.
119*/
120bool
121AbcCutGenerator::generateCuts( OsiCuts & cs , bool fullScan)
122{
123    int howOften = whenCutGenerator_;
124    if (howOften == -100)
125        return false;
126    if (howOften > 0)
127        howOften = howOften % 1000000;
128    else 
129        howOften = 1;
130    if (!howOften)
131        howOften = 1;
132    bool returnCode = false;
133    OsiSolverInterface * solver = model_->solver();
134
135#if defined(ABC_DEBUG_MORE)
136    std::cout << "model_->getNodeCount() = " << model_->getNodeCount()
137              << std::endl;
138#endif
139
140
141    if (fullScan || (model_->getNodeCount() % howOften) == 0 ) {
142        CglProbing* generator =
143            dynamic_cast<CglProbing*>(generator_);
144        if (!generator) {
145            generator_->generateCuts(*solver,cs);
146        } else {
147            // Probing - return tight column bounds
148            generator->generateCutsAndModify(*solver,cs);
149            const double * tightLower = generator->tightLower();
150            const double * lower = solver->getColLower();
151            const double * tightUpper = generator->tightUpper();
152            const double * upper = solver->getColUpper();
153            const double * solution = solver->getColSolution();
154            int j;
155            int numberColumns = solver->getNumCols();
156            double primalTolerance = 1.0e-8;
157            for (j=0; j<numberColumns; j++) {
158                if (tightUpper[j] == tightLower[j] &&
159                    upper[j] > lower[j]) {
160                    // fix
161                    solver->setColLower(j, tightLower[j]);
162                    solver->setColUpper(j, tightUpper[j]);
163                    if (tightLower[j] > solution[j] + primalTolerance ||
164                        tightUpper[j] < solution[j] - primalTolerance)
165                        returnCode = true;
166                }
167            }
168        }
169    }
170    return returnCode;
171}
172
173void 
174AbcCutGenerator::setHowOften(int howOften) 
175{
176    if (howOften >= 1000000) {
177        // leave Probing every 10
178        howOften = howOften % 1000000;
179        CglProbing* generator =
180            dynamic_cast<CglProbing*>(generator_);
181       
182        if (generator && howOften > 10) 
183            howOften = 10 + 1000000;
184    }
185    whenCutGenerator_ = howOften;
186}
Note: See TracBrowser for help on using the repository browser.