source: trunk/Bonmin/experimental/Bcp/BM_pack.cpp @ 1

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

imported initial code

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Revision"
File size: 7.4 KB
Line 
1// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2006
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// Authors :
6// Laszlo Ladanyi, International Business Machines Corporation
7//
8
9#include "BM.hpp"
10
11//#############################################################################
12
13void
14BM_lp::pack_feasible_solution(BCP_buffer& buf, const BCP_solution* sol)
15{
16    const BM_solution* bs = dynamic_cast<const BM_solution*>(sol);
17    if (!bs) {
18        throw BCP_fatal_error("Trying to pack non-BM_solution.\n");
19    }
20    buf.pack(bs->_objective);
21    buf.pack(bs->_ind);
22    buf.pack(bs->_values);
23}
24
25/****************************************************************************/
26
27BCP_solution*
28BM_tm::unpack_feasible_solution(BCP_buffer& buf)
29{
30    BM_solution* bs = new BM_solution;
31    buf.unpack(bs->_objective);
32    buf.unpack(bs->_ind);
33    buf.unpack(bs->_values);
34    return bs;
35}
36
37//#############################################################################
38
39void
40BM_tm::pack_module_data(BCP_buffer& buf, BCP_process_t ptype)
41{
42    // possible process types looked up in BCP_enum_process_t.hpp
43    switch (ptype) {
44    case BCP_ProcessType_LP:
45        par.pack(buf);
46        buf.pack(nl_file_content);
47        buf.pack(ipopt_file_content);
48        break;
49    default:
50        abort();
51    }
52}
53
54/****************************************************************************/
55
56void
57BM_lp::unpack_module_data(BCP_buffer& buf)
58{
59    par.unpack(buf);
60    buf.unpack(nl_file_content);
61    buf.unpack(ipopt_file_content);
62
63    char* argv_[3];
64    char** argv = argv_;
65    argv[0] = NULL;
66    argv[1] = strdup("dont_even_try_to_open_it.nl");
67    argv[2] = NULL;
68    std::string ipopt_content(ipopt_file_content.c_str());
69    std::string nl_content(nl_file_content.c_str());
70    nlp.readAmplNlFile(argv, &ipopt_content, &nl_content);
71    free(argv[1]);
72
73    nlp.extractInterfaceParams();
74
75    /* synchronize bonmin & BCP parameters */
76    Ipopt::SmartPtr<Ipopt::OptionsList> options = nlp.retrieve_options();
77    double bm_intTol;
78    double bm_cutoffIncr; // could be negative
79    options->GetNumericValue("integer_tolerance",bm_intTol,"bonmin.");
80    options->GetNumericValue("cutoff_incr",bm_cutoffIncr,"bonmin.");
81
82    BCP_lp_prob* bcp_lp = getLpProblemPointer();
83    const double bcp_intTol = bcp_lp->par.entry(BCP_lp_par::IntegerTolerance);
84    const double bcp_cutoffIncr = bcp_lp->par.entry(BCP_lp_par::Granularity);
85
86    if (fabs(bm_intTol - bcp_intTol) > 1e-10) {
87        printf("WARNING!\n");
88        printf("   The integrality tolerance parameters are different for\n");
89        printf("   BCP (%f) and bonmin (%f). They should be identical.\n",
90               bcp_intTol, bm_intTol);
91        printf("   For now both will be set to that of bonmin.\n");
92    }
93    if (fabs(bm_cutoffIncr - bcp_cutoffIncr) > 1e-10) {
94        printf("WARNING!\n");
95        printf("   The granularity (cutoff increment) parameters are different\n");
96        printf("   BCP (%f) and bonmin (%f). They should be identical.\n",
97               bcp_cutoffIncr, bm_cutoffIncr);
98        printf("   For now both will be set to that of bonmin.\n");
99    }
100    bcp_lp->par.set_entry(BCP_lp_par::IntegerTolerance, bm_intTol);
101    bcp_lp->par.set_entry(BCP_lp_par::Granularity, bm_cutoffIncr);
102
103    /* If pure BB is selected then a number of BCP parameters are changed */
104    if (par.entry(BM_par::PureBranchAndBound)) {
105        /* disable strong branching */
106        bcp_lp->par.set_entry(BCP_lp_par::MaxPresolveIter, -1);
107        /* disable a bunch of printing, all of which are meaningless, since the
108           LP relaxation is meaningless */
109        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_LpSolutionValue, false);
110        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_FinalRelaxedSolution, false);
111        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_RelaxedSolution, false);
112        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_ReportLocalCutPoolSize, false);
113        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_ReportLocalVarPoolSize, false);
114        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_GeneratedCutCount, false);
115        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_GeneratedVarCount, false);
116        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_IterationCount, false);
117        bcp_lp->par.set_entry(BCP_lp_par::LpVerb_RowEffectivenessCount, false);
118        //  bcp_lp->par.set_entry(BCP_lp_par::LpVerb_FathomInfo, false);
119    }
120
121    /* SOS constraints */
122    if (par.entry(BM_par::BranchOnSos)) {
123        sos.setFrom(nlp.model()->sosConstraints());
124    }
125
126    /* just to be on the safe side... always allocate */
127    primal_solution_ = new double[nlp.getNumCols()];
128    branching_priority_ = new double[nlp.getNumCols()];
129
130    /* Priorities... Let's see whether the user has set them up. */
131    const int* prio = nlp.getPriorities();
132    const int numCols = nlp.getNumCols();
133    int i;
134    if (prio == NULL) {
135        // No. Just sett all of them uniformly to 1.0
136        for (i = 0; i < numCols; ++i)
137            {
138                branching_priority_[i] = 1.0;
139            }
140    }
141    else {
142        /* Yes! the lower the number the earlier we want to branch on it.
143           Let's see how many different numbers there are */
144        std::set<int> numbers;
145        for (i = 0; i < numCols; ++i)
146            {
147                numbers.insert(prio[i]);
148            }
149        if (numbers.size() > 15) {
150            /* Sigh... too many... We just have to trust the user's knowledge */
151            if (par.entry(BM_par::CombinedDistanceAndPriority) == true) {
152                printf("WARNING!\n");
153                printf("   There are too many (>15) different branching priorities\n");
154                printf("   defined. Switching off CombinedDistanceAndPriority and\n");
155                printf("   will branch on considering only the specified priority\n");
156                printf("   order.\n");
157                par.set_entry(BM_par::CombinedDistanceAndPriority, false);
158            }
159        }
160        if (par.entry(BM_par::CombinedDistanceAndPriority) == true) {
161            /* vars with the lowest prio will have their branching_priority_
162               set to 1.0, the next set to 10.0, etc. */
163            const double powerup[15] = {1e14, 1e13, 1e12, 1e11, 1e10, 1e9, 1e8, 1e7,
164                                        1e6, 1e5, 1e4, 1e3, 1e2, 1e1, 1e0};
165            const double powerdo[15] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
166                                        1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14};
167            const double* powers =
168                par.entry(BM_par::LowPriorityImportant) ? powerup : powerdo;
169            for (i = 0; i < numCols; ++i)
170                {
171                    const int pos = coinDistance(numbers.begin(), numbers.find(prio[i]));
172                    assert (pos >= 0 && pos < 15);
173                    branching_priority_[i] = powers[pos];
174                }
175        }
176        else {
177            if (par.entry(BM_par::LowPriorityImportant)) {
178                const double maxprio = *numbers.rbegin();
179                for (i = 0; i < numCols; ++i)
180                    {
181                        branching_priority_[i] = maxprio - prio[i];
182                    }
183            }
184            else {
185                for (i = 0; i < numCols; ++i)
186                    {
187                        branching_priority_[i] = prio[i];
188                    }
189            }
190        }
191    }
192}
193
194//#############################################################################
195
196void
197BM_tm::pack_user_data(const BCP_user_data* ud, BCP_buffer& buf)
198{
199    const BM_node* data = dynamic_cast<const BM_node*>(ud);
200    data->pack(buf);
201}
202
203/*---------------------------------------------------------------------------*/
204
205BCP_user_data*
206BM_tm::unpack_user_data(BCP_buffer& buf)
207{
208    return new BM_node(buf);
209}
210
211/*****************************************************************************/
212
213void
214BM_lp::pack_user_data(const BCP_user_data* ud, BCP_buffer& buf)
215{
216    const BM_node* data = dynamic_cast<const BM_node*>(ud);
217    data->pack(buf);
218}
219
220/*---------------------------------------------------------------------------*/
221
222BCP_user_data*
223BM_lp::unpack_user_data(BCP_buffer& buf)
224{
225    BM_node* data = new BM_node(buf);
226    numNlpFailed_ = data->numNlpFailed_;
227    return data;
228}
229
230//#############################################################################
Note: See TracBrowser for help on using the repository browser.