source: branches/Couenne/Couenne/src/convex/createCuts.cpp @ 558

Last change on this file since 558 was 558, checked in by pbelotti, 12 years ago

fixed bug in setting branching point

File size: 3.3 KB
Line 
1/*
2 * Name:   createCuts.cpp
3 * Author: Pietro Belotti
4 * Purpose: a standard cut creator for use with convexification
5 *
6 *
7 * (C) 2006 Pietro Belotti, all rights reserved.
8 * This file is distributed under the Common Public License
9 */
10
11#include <OsiRowCut.hpp>
12
13#include <CouenneTypes.h>
14#include <CouennePrecisions.h>
15#include <CouenneCutGenerator.h>
16#include <CouenneProblem.h>
17
18
19/// general procedure for inserting a linear cut with up to three
20/// variables. Return 1 if cut inserted, 0 if none, <0 if error
21
22int CouenneCutGenerator::createCut (OsiCuts &cs,
23                                    CouNumber rhs, int sign, 
24                                    int i1, CouNumber c1,
25                                    int i2, CouNumber c2,
26                                    int i3, CouNumber c3,
27                                    bool is_global)       const {
28  bool numerics = false;
29
30  // a maximum of three terms are allowed here. If index -1 (default)
31  // the term is not considered
32
33  int nterms = 0;
34
35  if (i1 >= 0) {if (fabs (c1) > COU_MAX_COEFF) numerics = true; nterms++;} else c1 = 0;
36  if (i2 >= 0) {if (fabs (c2) > COU_MAX_COEFF) numerics = true; nterms++;} else c2 = 0;
37  if (i3 >= 0) {if (fabs (c3) > COU_MAX_COEFF) numerics = true; nterms++;} else c3 = 0;
38
39  if (!nterms) // nonsense cut
40    return 0;
41
42  // cut has large coefficients/rhs, bail out
43  if (numerics || (fabs (rhs) > COU_MAX_COEFF)) {
44    printf ("### Discarding cut, large coeff/rhs: %g (%d), %g (%d), %g (%d); %g\n", 
45            c1, i1, c2, i2, c3, i3, rhs);
46    return 0;
47  }
48
49  if (!firstcall_ && addviolated_) { // need to check violation
50
51    CouNumber *x = const_cast <CouNumber *> (problem_ -> X ());
52
53    // compute violation
54    CouNumber violation = - rhs;
55
56    if (i1 >= 0) violation += c1 * x [i1];
57    if (i2 >= 0) violation += c2 * x [i2];
58    if (i3 >= 0) violation += c3 * x [i3];
59
60    // return 0 if not violated
61
62    if (((violation <   COUENNE_EPS) || (sign > 0)) &&
63        ((violation > - COUENNE_EPS) || (sign < 0)))
64      return 0;
65  }
66
67  // You are here if:
68  //
69  // 1) this is the first call to CouenneCutGenerator::generateCuts()
70  // 2) we also want unviolated cuts
71  // 3) the cut is violated
72
73  // two cases: cut is of the form w1 [<|>]= alpha, hence a column
74  // cut, or it is of the form (a w1 + b w2 + c w3 [<|>]= alpha), a
75  // row cut
76
77  if ((i2 < 0) && (i3 < 0)) { // column cut
78
79    if ((fabs (c1) < COUENNE_EPS) && (fabs (rhs) > 1e10*COUENNE_EPS)) {
80      printf ("nonsense column cut: %e w_%d <>= %e\n", c1, i1, rhs);
81      return 0;
82    }
83
84    OsiColCut *cut = new OsiColCut;
85
86    CouNumber bound = rhs/c1;
87
88    if (c1 < 0) sign = -sign;
89
90    if (sign <= 0) {cut -> setUbs (1, &i1, &bound); problem_ -> Ub (i1) = bound;}
91    if (sign >= 0) {cut -> setLbs (1, &i1, &bound); problem_ -> Lb (i1) = bound;}
92
93    cut -> setGloballyValid (is_global); // global?
94    cs.insert (cut);
95    delete cut;
96
97  } else { // row cut
98
99    CouNumber *coeff = new CouNumber [nterms]; 
100    int       *index = new int       [nterms];
101    OsiRowCut *cut   = new OsiRowCut;
102
103    if (i1 >= 0) {coeff [0] = c1; index [0] = i1;}
104    if (i2 >= 0) {coeff [1] = c2; index [1] = i2;}
105    if (i3 >= 0) {coeff [2] = c3; index [2] = i3;}
106
107    if (sign <= 0) cut -> setUb (rhs);
108    if (sign >= 0) cut -> setLb (rhs);
109
110    cut -> setRow (nterms, index, coeff);
111
112    delete [] coeff;
113    delete [] index;
114
115    cut -> setGloballyValid (is_global); // global?
116    cs.insert (cut);
117    delete cut;
118  }
119
120  return 1;
121}
Note: See TracBrowser for help on using the repository browser.