Scippy

SCIP

Solving Constraint Integer Programs

prob_data_objectives.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program PolySCIP */
4 /* */
5 /* Copyright (C) 2012-2020 Konrad-Zuse-Zentrum */
6 /* fuer Informationstechnik Berlin */
7 /* */
8 /* PolySCIP is distributed under the terms of the ZIB Academic License. */
9 /* */
10 /* You should have received a copy of the ZIB Academic License */
11 /* along with PolySCIP; see the file LICENCE. */
12 /* */
13 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
14 
15 /**
16  * @file prob_data_objectives.cpp
17  * @brief Implements class storing multiple objectives of given problem instance
18  * @author Sebastian Schenker
19  *
20  */
21 
22 #include "prob_data_objectives.h"
23 
24 #include <algorithm> // std::transform, std::find
25 #include <cstddef>
26 #include <functional> // std::negate, std::plus
27 #include <numeric> // std::inner_product
28 #include <stack>
29 #include <stdexcept>
30 #include <string>
31 
32 #include "objscip/objscip.h"
33 #include "polyscip_types.h"
34 
35 using std::size_t;
36 using std::string;
37 using std::vector;
41 
42 
43 /**
44  * Add identifier of objective
45  * @param name Objective identifier
46  */
47 void ProbDataObjectives::addObjName(const char* name) {
48  string obj_name(name);
49  if (name_to_no_.count(obj_name) != 0)
50  throw std::runtime_error("Name of objective already encountered: " + obj_name);
51  name_to_no_.emplace(obj_name, getNoObjs());
52  name_to_nonzero_coeffs_.emplace(obj_name, vector<SCIP_VAR*>{});
53  no_to_name_.push_back(obj_name);
54  non_ignored_objs_.push_back(getNoObjs());
55 }
56 
57 
58 /**
59  * Add objective coefficient
60  * @param var Corresponding variable
61  * @param obj_name Corresponding objective identifier
62  * @param val Corresponding coefficient
63  */
64 void ProbDataObjectives::addObjCoeff(SCIP_VAR *var, const char* obj_name, ValueType val) {
65  if (val != 0) {
66  if (var_to_coeffs_.count(var) == 0)
67  var_to_coeffs_.emplace(var, OutcomeType(getNoObjs(), 0));
68  auto obj_no = name_to_no_.at(obj_name);
69  var_to_coeffs_[var].at(obj_no) = val;
70  name_to_nonzero_coeffs_.at(obj_name).push_back(var);
71  }
72  else
73  std::cout << "addObjCoeff with zero value\n";
74 }
75 
76 
77 /**
78  * Get objective coefficient
79  * @param var Corresponding variable
80  * @param obj_no Corresponding number of objective
81  * @todo Const qualification
82  */
84  if (var_to_coeffs_.count(var))
85  return (var_to_coeffs_[var]).at(non_ignored_objs_.at(obj));
86  else
87  return 0.;
88 }
89 
90 
91 /**
92  * Number of non-zero coefficients of objective
93  * @param obj_no Corresponding objective number
94  */
96  auto obj_name = no_to_name_.at(non_ignored_objs_.at(obj));
97  return name_to_nonzero_coeffs_.at(obj_name).size();
98 }
99 
100 
101 /**
102  * Scalar product of given weight and objectives w.r.t. given variable;
103  * if given variable is unknown, return 0.0 (since var can only have zero objective
104  * coefficients in given problem)
105  * @param var Corresponding variable
106  * @param weight Corresponding weight vector
107  * @todo Const qualification
108  */
110  assert (weight.size() == non_ignored_objs_.size());
111  if (var_to_coeffs_.count(var)) {
112  auto& coeffs = var_to_coeffs_[var];
113  return std::inner_product(begin(weight),
114  end(weight),
115  begin(non_ignored_objs_),
116  0.,
117  std::plus<ValueType>(),
118  [&coeffs](ValueType w, size_t obj){return w*coeffs[obj];});
119  }
120  else {
121  return 0.;
122  }
123 }
124 
125 
126 /**
127  * Variables corresponding to non-zero objective coefficients
128  * @param obj_no Corresponding objective number
129  */
130 vector<SCIP_VAR*> ProbDataObjectives::getNonZeroCoeffVars(size_t obj) const {
131  auto obj_name = no_to_name_.at(non_ignored_objs_.at(obj));
132  return name_to_nonzero_coeffs_.at(obj_name);
133 }
134 
135 
136 /**
137  * Product of given solution value and objective coefficient w.r.t. given
138  * variable and objective number
139  * @param var Corresponding variable
140  * @param obj_no Corresponding objective number
141  * @param sol_val Corresponding solution value
142  * @todo Const qualification
143  */
145  if (var_to_coeffs_.count(var))
146  return var_to_coeffs_[var].at(non_ignored_objs_.at(obj)) * sol_val;
147  else
148  return 0.;
149 }
150 
151 
152 /**
153  * Negate all objective coefficients of all variables in all objectives
154  */
156  for (auto it=begin(var_to_coeffs_); it!=end(var_to_coeffs_); ++it) {
157  std::transform(begin(it->second), end(it->second),
158  begin(it->second), std::negate<ValueType>());
159  }
160 }
161 
162 /**
163  * Ignore two objectives
164  * @param obj_1 First objective to ignore
165  * @param obj_2 Second objective to ignore
166  */
167 void ProbDataObjectives::ignoreObjectives(size_t obj_1, size_t obj_2) {
168  auto obj_ind_1 = non_ignored_objs_.at(obj_1);
169  auto obj_ind_2 = non_ignored_objs_.at(obj_2);
170  auto it = std::find(begin(non_ignored_objs_), end(non_ignored_objs_), obj_ind_1);
171  assert (it != end(non_ignored_objs_));
172  non_ignored_objs_.erase(it);
173  it = std::find(begin(non_ignored_objs_), end(non_ignored_objs_), obj_ind_2);
174  assert (it != end(non_ignored_objs_));
175  non_ignored_objs_.erase(it);
176  ignored_obj_.push(obj_ind_1);
177  ignored_obj_.push(obj_ind_2);
178 }
179 
180 /**
181  * Unignore latest two objectives that were ignored previously
182  */
184  auto obj = ignored_obj_.top();
185  ignored_obj_.pop();
186  non_ignored_objs_.push_back(obj);
187  obj = ignored_obj_.top();
188  ignored_obj_.pop();
189  non_ignored_objs_.push_back(obj);
190  std::sort(begin(non_ignored_objs_), end(non_ignored_objs_));
191 }
std::vector< ValueType > WeightType
Type for weight vectors.
Class storing multiple objectives of given problem instance.
SCIP_Real ValueType
Type for computed values.
void addObjCoeff(SCIP_VAR *var, const char *obj_name, polyscip::ValueType val)
polyscip::ValueType getObjVal(SCIP_VAR *var, std::size_t obj_no, polyscip::ValueType sol_val)
void addObjName(const char *name)
General types used for PolySCIP.
std::vector< ValueType > OutcomeType
Type for points, rays in objective space.
SCIP_VAR * w
Definition: circlepacking.c:58
std::vector< SCIP_VAR * > getNonZeroCoeffVars(std::size_t obj_no) const
std::size_t getNumberNonzeroCoeffs(std::size_t obj_no) const
C++ wrapper classes for SCIP.
void ignoreObjectives(std::size_t obj_1, std::size_t obj_2)
polyscip::ValueType getObjCoeff(SCIP_VAR *var, std::size_t obj_no)
polyscip::ValueType getWeightedObjVal(SCIP_VAR *var, const polyscip::WeightType &weight)
std::size_t getNoObjs() const