7 #include "CoinSort.hpp"
22 int * itmp,
double * dtmp)
26 int* negedges = itmp +
n;
28 int i = sp_tree_root +
n;
31 parent = bp_nodes[i].
parent;
32 if ((parent < n && i < n) || (parent >= n && i >= n)) {
40 }
while (parent != sp_tree_root);
44 const int len = pos + neg;
45 CoinDisjointCopyN(negedges, neg, posedges + pos);
47 CoinFillN(dtmp, pos, 1.0);
48 CoinFillN(dtmp + pos, neg, -1.0);
49 CoinSort_2(posedges, posedges + len, dtmp);
60 int* node_stack =
new int[nodenum];
64 for (i = 0; i < nodenum; ++i) {
65 if (component[i] >= 0)
67 node_stack[stack_size++] = i;
69 while (stack_size > 0) {
70 const int node = node_stack[--stack_size];
73 for (j = bp_nodes[node].degree - 1; j >= 0; --
j) {
75 if (component[other] == -1) {
77 node_stack[stack_size++] = other;
90 const bool generate_all_cuts,
95 const double minviol1 = 1.0 - minviol;
99 double* dtmp =
new double[
n];
100 int* itmp =
new int[4 * n +
m];
103 int* component = itmp + (2 *
n);
104 int* edges_to_create = itmp + (4 *
n);
112 for (i = 0; i <
n; ++i)
113 bp_nodes[i].degree = 0;
116 for (i = 0; i <
m; ++i) {
117 const double xi = x[i];
118 const int t = edges[i].tail;
119 const int h = edges[i].head;
120 edges_to_create[i] = 0;
124 edges_to_create[i] |= 1;
131 edges_to_create[i] |= 2;
137 int total_degree = 0;
138 for (i = 0; i <
n; ++i) {
139 bp_nodes[i].
adj_list = bp_all_adj_list + total_degree;
140 total_degree += bp_nodes[i].
degree;
141 bp_nodes[i +
n].
adj_list = bp_all_adj_list + total_degree;
142 total_degree += bp_nodes[i].
degree;
145 for (i = 0; i <
n; ++i)
146 bp_nodes[i].degree = 0;
148 for (i = 0; i <
m; ++i) {
149 const double xi = CoinMax(x[i], 0.0);
150 const double xi1 = CoinMax(1 - xi, 0.0);
151 const int t = edges[i].tail;
152 const int h = edges[i].head;
153 const int nt = n +
t;
154 const int nh = n + h;
155 if ((edges_to_create[i] & 1) != 0) {
156 const int degt = bp_nodes[
t].
degree;
157 const int degh = bp_nodes[h].
degree;
181 if ((edges_to_create[i] & 2) != 0) {
182 const int degt = bp_nodes[
t].
degree;
183 const int degh = bp_nodes[h].
degree;
208 for (i = 0; i <
n; ++i)
209 bp_nodes[n+i].degree = bp_nodes[i].degree;
213 std::vector<MC_path_node*>,
216 CoinFillN(component, 2 * n, -1);
219 printf(
"MC: sp based exact: there are %i components in the graph\n",
228 for (i = new_cuts.
size() - 1; i >= 0; --i) {
242 const int t = edges[cut->
edges[
j]].tail;
243 const int h = edges[cut->
edges[
j]].head;
244 if (component[t] == component[n + t]) {
248 if (component[h] == component[n + h]) {
254 printf(
"MC: sp based exact: skipping %i sp computations\n", skip);
255 printf(
" because of already found cycles\n");
258 for (i = 0; i <
n; ++i) {
259 if (component[i] != component[n + i]) {
264 double limit = minviol1;
272 for (j = 2*n - 1; j >= 0; --
j) {
278 pqueue.push(bp_nodes + i);
280 while (! pqueue.empty()) {
281 MC_path_node* this_node_nonconst = pqueue.top();
282 const MC_path_node* this_node = this_node_nonconst;
286 const int this_node_index = this_node - bp_nodes;
287 if (this_node_index == n+i) {
289 if (! generate_all_cuts) {
292 new_cuts, new_rows, itmp, dtmp);
297 const double this_dist = this_node->
distance;
299 for (j = this_node->
degree - 1; j >= 0; --j) {
300 const double neighborcost = this_dist + this_alist[
j].
cost;
301 if (neighborcost >= limit)
303 const int neighbor = this_alist[
j].
neighbor;
304 if (bp_nodes[neighbor].
distance > neighborcost) {
305 MC_path_node* neighbor_node = bp_nodes + neighbor;
306 pqueue.push(neighbor_node);
307 neighbor_node->
distance = neighborcost;
308 neighbor_node->
parent = this_node_index;
310 if (neighbor == n+i) {
312 limit = neighborcost;
313 if (generate_all_cuts) {
315 new_cuts, new_rows, itmp, dtmp);
323 printf(
"MC: sp based exact: computed %i sp out of %i\n", n - split_num, n);
325 delete[] bp_all_adj_list;
pos
position where the operator should be printed when printing the expression
void MC_create_shortest_path_cut(const int n, const int sp_tree_root, const MC_graph_edge *edges, const MC_path_node *bp_nodes, BCP_vec< BCP_cut * > &new_cuts, BCP_vec< BCP_row * > &new_rows, int *itmp, double *dtmp)
void MC_generate_shortest_path_cycles(const MC_problem &mc, const double *x, const bool generate_all_cuts, const double minviol, BCP_vec< BCP_cut * > &new_cuts, BCP_vec< BCP_row * > &new_rows)
void push_back(const_reference x)
Append x to the end of the vector.
int MC_find_components(const int nodenum, const MC_path_node *bp_nodes, int *component)
size_t size() const
Return the current number of entries.
MC_path_adj_entry * adj_list
double distance(const double *p1, const double *p2, int size, double k=2.)
compute Euclidean distance between two points (most likely LP solutions) l_2 norm by default...
void fint fint fint real fint real * x
This class holds a row in a compressed form.