Camargue
pricer.hpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
5 
6 #ifndef CMR_PRICER_H
7 #define CMR_PRICER_H
8 
9 #include "core_lp.hpp"
10 #include "dualgroup.hpp"
11 #include "datagroups.hpp"
12 #include "hypergraph.hpp"
13 #include "lp_util.hpp"
14 #include "util.hpp"
15 #include "price_util.hpp"
16 #include "err_util.hpp"
17 #include "fixed64.hpp"
18 #include "edgehash.hpp"
19 
20 #include <memory>
21 #include <queue>
22 #include <stdexcept>
23 #include <unordered_map>
24 #include <vector>
25 
26 namespace CMR {
27 
29 namespace Price {
30 
32 class Pricer {
33 public:
35  Pricer(LP::CoreLP &core, const Data::Instance &_inst,
36  Graph::CoreGraph &core_graph_);
37 
38  ~Pricer();
39 
41  bool try_elim);
42 
43  bool feas_recover();
44 
46  util::Fixed64 exact_lb(bool full);
47 
49  util::Fixed64 exact_lb(bool full,
50  std::vector<PrEdge<util::Fixed64>> &priced_edges);
51 
52  void elim_edges(bool make_opt);
53 
55  template <typename numtype>
56  void price_edges(std::vector<PrEdge<numtype>> &target_edges,
57  std::unique_ptr<LP::DualGroup<numtype>> &duals,
58  bool include_len);
59 
60  int verbose = 0;
61 
62 private:
63  std::vector<Graph::Edge> pool_chunk(std::vector<PrEdge<double>> &edge_q);
64 
65  bool scan_adjlist(std::vector<PrEdge<util::Fixed64>> &gen_edges,
66  int &node_index);
67 
68  bool scan_edges(std::vector<PrEdge<util::Fixed64>> &gen_edges,
69  int &loop1, int &loop2);
70 
71  bool feas_gen_edges(std::vector<PrEdge<double>> &price_elist,
72  int start_ind, int &end1, int &end2);
73 
74  // bool f64_gen_edges(const std::vector<util::Fixed64> &node_pi_est,
75  // std::vector<PrEdge<double>64> &gen_edges,
76  // int &loop1, int &loop2);
77 
81 
83 
84  const int gen_max;
85 
86  std::vector<int> gen_elist;
87  std::vector<int> gen_elen;
88 
89  std::unique_ptr<LP::DualGroup<double>> reg_duals;
90  std::unique_ptr<LP::DualGroup<util::Fixed64>> ex_duals;
91 
92  struct edgegen_impl;
93  std::unique_ptr<edgegen_impl> eg_inside;
94  std::unique_ptr<edgegen_impl> eg_full;
95 
97 };
98 
100 
110 template <typename numtype>
111 void Pricer::price_edges(std::vector<PrEdge<numtype>> &target_edges,
112  std::unique_ptr<LP::DualGroup<numtype>> &duals,
113  bool include_len)
114 {
115  using std::vector;
116  using std::unique_ptr;
117  using Dual = LP::DualGroup<numtype>;
119 
120  std::runtime_error err("Problem in Pricer::price_edges.");
121 
122  if (!duals)
123  try {
124  duals = util::make_unique<Dual>(false, core_lp,
125  core_lp.external_cuts());
126  } CMR_CATCH_PRINT_THROW("getting duals", err);
127 
128  vector<numtype> &node_pi = duals->node_pi;
129  vector<numtype> &cut_pi = duals->cut_pi;
130  std::unordered_map<Sep::Clique, numtype> &clique_pi = duals->clique_pi;
131 
132  if (include_len) {
133  for (auto &e : target_edges)
134  e.redcost = inst.edgelen(e.end[0], e.end[1]) - node_pi[e.end[0]]
135  - node_pi[e.end[1]];
136  } else {
137  for (auto &e : target_edges)
138  e.redcost = 0 - node_pi[e.end[0]] - node_pi[e.end[1]];
139  }
140 
141  Graph::AdjList price_adjlist;
142 
143  try {
144  price_adjlist = Graph::AdjList(inst.node_count(), target_edges);
145  } CMR_CATCH_PRINT_THROW("Couldn't build price adjlist.", err);
146 
147  vector<Graph::Node> &price_nodelist = price_adjlist.nodelist;
148 
149  const std::vector<int> &def_tour = ext_cuts.get_cbank().ref_tour();
150  int marker = 0;
151 
152  for (const std::pair<Sep::Clique, numtype> &kv : clique_pi) {
153  const Sep::Clique &clq = kv.first;
154  numtype pival = kv.second;
155 
156  if (pival != 0.0) {
157  numtype add_back = pival + pival;
158  ++marker;
159 
160  for (int j : clq.node_list(def_tour)) {
161  for (Graph::AdjObj &nbr : price_nodelist[j].neighbors)
162  if (price_nodelist[nbr.other_end].mark == marker)
163  target_edges[nbr.edge_index].redcost += add_back;
164 
165  price_nodelist[j].mark = marker;
166  }
167  }
168  }
169 
170  const vector<Sep::HyperGraph> &cutlist = ext_cuts.get_cuts();
171  vector<int> rmatind;
172  vector<double> rmatval;
173 
174  for (int i = 0; i < cutlist.size(); ++i) {
175  numtype pival = cut_pi[i];
176  const Sep::HyperGraph &H = cutlist[i];
177 
178  if (H.cut_type() == CutType::Non)
179  throw std::logic_error("Called pricing w Non HyperGraph present.");
180 
181  if (H.cut_type() != CutType::Domino)
182  continue;
183 
184  if (pival == 0)
185  continue;
186 
187  try {
188  H.get_coeffs(target_edges, rmatind, rmatval);
189  } CMR_CATCH_PRINT_THROW("geting domino price edge coeffs", err);
190 
191  for (int j = 0; j < rmatind.size(); ++j)
192  util::add_mult(target_edges[rmatind[j]].redcost,
193  pival, -rmatval[j]);
194  }
195 }
196 
197 }
198 }
199 
200 #endif
Miscellaneous functions, structs/enums, and constants for LPs.
Type
Enumeration for the types of HyperGraph inequalities.
Definition: hypergraph.hpp:65
int node_count() const
Number of nodes.
Definition: datagroups.hpp:71
const int gen_max
The max number of edges to generate at a time.
Definition: pricer.hpp:84
PivType
Enum class for categorizing lp solutions.
Definition: lp_util.hpp:34
double edgelen(int end0, int end1) const
Edge length between two nodes in an Instance.
Definition: datagroups.hpp:64
Representing cuts outside the LP solver.
bool feas_recover()
Generate/add edges to recover LP feasibility.
Definition: price_recover.cpp:40
void get_coeffs(const std::vector< EndPt_type > &edges, std::vector< int > &rmatind, std::vector< double > &rmatval) const
Get sparse coefficient row for a list of endpoints.
Definition: hypergraph.hpp:211
Get reduced costs for edges not in the core lp.
Definition: pricer.hpp:32
Hash map for node pairs representing edges.
Definition: edgehash.hpp:24
Wrapper/arithmetic operators for fixed precision arithmetic.
The external storage of a collection of HyperGraph cuts in a Relaxation.
Definition: hypergraph.hpp:126
LP dual solutions.
Data group structures.
const Sep::ExternalCuts & ext_cuts
For computing duals.
Definition: pricer.hpp:80
util::EdgeHash edge_hash
Hash table for tracking generated edges.
Definition: pricer.hpp:96
Definition: price_util.hpp:65
Graph structures for the edges currently in a CoreLP::Relaxation.
Definition: datagroups.hpp:100
Graph::CoreGraph & core_graph
Graph data for the core_lp.
Definition: pricer.hpp:82
std::vector< int > gen_elen
Unused dummy parameter to pass.
Definition: pricer.hpp:87
Storing TSP instance data.
Definition: datagroups.hpp:36
std::unique_ptr< edgegen_impl > eg_inside
The edge generator implementation.
Definition: pricer.hpp:92
ERROR HANDLING CLASSES AND ROUTINES.
void price_edges(std::vector< PrEdge< numtype >> &target_edges, std::unique_ptr< LP::DualGroup< numtype >> &duals, bool include_len)
Compute reduced costs for a set of edges.
Definition: pricer.hpp:111
LP::CoreLP & core_lp
The LP relaxation to query/modify.
Definition: pricer.hpp:78
Utility functions, macros, and structures.
Pricer(LP::CoreLP &core, const Data::Instance &_inst, Graph::CoreGraph &core_graph_)
Construct a Pricer using data from an ongoing solution process.
Definition: price_gen.cpp:86
Class for storing segment lists representing edges of a hypergraph.
Definition: cliq.hpp:34
void elim_edges(bool make_opt)
Eliminate edges from the core.
Definition: price_exact.cpp:115
util::Fixed64 exact_lb(bool full)
Compute a lower bound in Fixed64 arithmetic.
Definition: price_exact.cpp:34
ScanStat
Return type for edge pricing routines.
Definition: price_util.hpp:33
const Data::Instance & inst
To get lengths for edges not in core_lp.
Definition: pricer.hpp:79
External representation of a cut added to the lp relaxation.
Definition: hypergraph.hpp:31
The namespace for this project.
Definition: abc_nodesel.hpp:20
std::unique_ptr< edgegen_impl > eg_full
Complete graph generator.
Definition: pricer.hpp:94
Class template for storing dual LP solutions.
Definition: dualgroup.hpp:25
Hash map for graph edges.
ScanStat gen_edges(LP::PivType piv_stat, bool try_elim)
Generate/add edges to core.
Definition: price_gen.cpp:111
std::vector< int > gen_elist
Raw node-node list of generated edges.
Definition: pricer.hpp:86
#define CMR_CATCH_PRINT_THROW(msg, new_ex)
Macro for handling errors in function with multiple failure points.
Definition: err_util.hpp:25
Class for storing the core lp associated to a TSP instance and pivoting.
Definition: core_lp.hpp:33
Definition: price_gen.cpp:39
Representation of a graph as an adjacency list.
Definition: graph.hpp:80
std::vector< int > node_list(const std::vector< int > &saved_tour) const
A list of literal nodes represented by the Clique.
Definition: cliq.cpp:183
Managing Core LP relaxations of TSP instances.
Object used to represent adjacency in a Graph::AdjList.
Definition: graph.hpp:51
A 64-bit fixed precision number type "implemented" as a wrapper to CCbigguy.
Definition: fixed64.hpp:21
Constants and functions related to edge pricing.