70 #ifndef GECKO_PART_FRAC
71 #define GECKO_PART_FRAC 4
75 #ifndef GECKO_CR_SWEEPS
76 #define GECKO_CR_SWEEPS 1
80 #ifndef GECKO_GS_SWEEPS
81 #define GECKO_GS_SWEEPS 1
85 #ifndef GECKO_WINDOW_MAX
86 #define GECKO_WINDOW_MAX 16
90 #ifndef GECKO_WITH_ADJLIST
91 #define GECKO_WITH_ADJLIST 0
95 #ifndef GECKO_WITH_NONRECURSIVE
96 #define GECKO_WITH_NONRECURSIVE 0
100 #ifndef GECKO_WITH_DOUBLE_PRECISION
101 #define GECKO_WITH_DOUBLE_PRECISION 0
109 class C = std::less<P>,
110 class M = std::map<T, unsigned int>
115 DynamicHeap(
size_t count = 0);
117 void insert(T data, P priority);
118 void update(T data, P priority);
120 bool top(T& data, P& priority);
122 bool extract(T& data);
123 bool extract(T& data, P& priority);
125 bool find(T data)
const;
126 bool find(T data, P& priority)
const;
127 bool empty()
const {
return heap.empty(); }
128 size_t size()
const {
return heap.size(); }
132 HeapEntry(P
p, T d) : priority(p), data(d) {}
136 std::vector<HeapEntry> heap;
139 void ascend(
unsigned int i);
140 void descend(
unsigned int i);
141 void swap(
unsigned int i,
unsigned int j);
142 bool ordered(
unsigned int i,
unsigned int j)
const
144 return !lower(heap[i].priority, heap[j].priority);
146 unsigned int parent(
unsigned int i)
const {
return (i - 1) / 2; }
147 unsigned int left(
unsigned int i)
const {
return 2 * i + 1; }
148 unsigned int right(
unsigned int i)
const {
return 2 * i + 2; }
151 template <
typename T,
typename P,
class C,
class M >
152 DynamicHeap<T, P, C, M>::DynamicHeap(
size_t count)
157 template <
typename T,
typename P,
class C,
class M >
159 DynamicHeap<T, P, C, M>::insert(T data, P priority)
163 update(data, priority);
167 unsigned int i = (
unsigned int)heap.size();
168 heap.push_back(HeapEntry(priority, data));
173 template <
typename T,
typename P,
class C,
class M >
175 DynamicHeap<T, P, C, M>::update(T data, P priority)
177 unsigned int i =
index[data];
178 heap[i].priority = priority;
183 template <
typename T,
typename P,
class C,
class M >
185 DynamicHeap<T, P, C, M>::top(T& data)
198 template <
typename T,
typename P,
class C,
class M >
200 DynamicHeap<T, P, C, M>::top(T& data, P& priority)
205 priority = heap[0].priority;
214 template <
typename T,
typename P,
class C,
class M >
216 DynamicHeap<T, P, C, M>::pop()
220 T data = heap[0].data;
221 swap(0, (
unsigned int)heap.size() - 1);
236 template <
typename T,
typename P,
class C,
class M >
238 DynamicHeap<T, P, C, M>::extract(T& data)
251 template <
typename T,
typename P,
class C,
class M >
253 DynamicHeap<T, P, C, M>::extract(T& data, P& priority)
258 priority = heap[0].priority;
267 template <
typename T,
typename P,
class C,
class M >
269 DynamicHeap<T, P, C, M>::erase(T data)
275 unsigned int i =
index[data];
276 swap(i, heap.size() - 1);
287 template <
typename T,
typename P,
class C,
class M >
289 DynamicHeap<T, P, C, M>::find(T data)
const
294 template <
typename T,
typename P,
class C,
class M >
296 DynamicHeap<T, P, C, M>::find(T data, P& priority)
const
298 typename M::const_iterator
p;
303 unsigned int i = p->second;
304 priority = heap[i].priority;
308 template <
typename T,
typename P,
class C,
class M >
310 DynamicHeap<T, P, C, M>::ascend(
unsigned int i)
312 for (
unsigned int j; i && !ordered(j = parent(i), i); i = j)
316 index[heap[i].data] = i;
319 template <
typename T,
typename P,
class C,
class M >
321 DynamicHeap<T, P, C, M>::descend(
unsigned int i)
323 for (
unsigned int j, k;
324 (j = ((k = left(i)) < heap.size() && !ordered(i, k) ? k : i),
325 j = ((k = right(i)) < heap.size() && !ordered(j, k) ? k : j)) != i;
330 index[heap[i].data] = i;
333 template <
typename T,
typename P,
class C,
class M >
335 DynamicHeap<T, P, C, M>::swap(
unsigned int i,
unsigned int j)
337 std::swap(heap[i], heap[j]);
338 index[heap[i].data] = i;
350 typedef unsigned char Index;
359 ~Subgraph() {
delete[] cache; }
360 void optimize(
uint k);
367 Subnode::Index best[GECKO_WINDOW_MAX];
368 Subnode::Index perm[GECKO_WINDOW_MAX];
369 const Subnode* node[GECKO_WINDOW_MAX];
371 #if GECKO_WITH_ADJLIST
373 adj[GECKO_WINDOW_MAX][GECKO_WINDOW_MAX];
375 uint adj[GECKO_WINDOW_MAX];
377 Float weight[GECKO_WINDOW_MAX][GECKO_WINDOW_MAX];
388 using namespace Gecko;
391 Subgraph::Subgraph(
Graph* g,
uint n) : g(g), n(n),
f(g->functional)
393 if (n > GECKO_WINDOW_MAX)
395 throw std::out_of_range(
"optimization window too large");
397 cache =
new Subnode[n << n];
402 Subgraph::cost(
uint k)
const
404 Subnode::Index i = perm[k];
406 Float p = node[i]->pos;
407 #if GECKO_WITH_ADJLIST
408 for (k = 0; adj[i][k] != i; k++)
410 Subnode::Index j = adj[i][k];
411 Float l = node[j]->pos -
p;
414 Float w = weight[i][k];
422 Subnode::Index j = perm[k];
425 Float l = node[j]->pos -
p;
426 Float w = weight[i][j];
436 Subgraph::swap(
uint k)
439 Subnode::Index i = perm[k];
440 Subnode::Index j = perm[l];
443 node[i] -= ptrdiff_t(1) << j;
444 node[j] += ptrdiff_t(1) << i;
451 Subnode::Index i = perm[k];
452 Subnode::Index j = perm[l];
459 Subnode::Index h = perm[k];
460 node[h] += ptrdiff_t(1) << i;
461 node[h] -= ptrdiff_t(1) << j;
464 node[i] -= (1u << j) + m;
465 node[j] += (1u << i) + m;
468 #if GECKO_WITH_NONRECURSIVE
474 uint j[GECKO_WINDOW_MAX + 1];
483 c[i] =
f->sum(c[i + 1], cost(i));
486 if (
f->less(c[0], min))
489 for (
uint k = 0; k < n; k++)
500 swap(i & 1 ? i - j[i] : 0, i);
518 optimize(
f->sum(c, cost(i)), i);
519 swap(i & 1 ? i - j : 0, i);
525 f->accumulate(c, cost(0));
529 for (
uint j = 0; j < n; j++)
544 Subgraph::optimize(
uint p)
549 for (Subnode::Index k = 0; k < n; k++)
551 best[k] = perm[k] = k;
556 #if GECKO_WITH_ADJLIST
561 std::vector<Arc::Index> external;
566 for (l = 0; l < n && g->
perm[p + l] != j; l++);
569 external.push_back(
a);
574 #if GECKO_WITH_ADJLIST
584 #if GECKO_WITH_ADJLIST
600 node[k] = cache + (k << n);
601 for (
uint m = 0; m < (1u << n); m++)
602 if (!(m & (1u << k)))
604 Subnode* s = cache + (k << n) + m;
605 s->pos = q + g->
node[i].hlen;
606 for (Subnode::Index l = 0; l < n; l++)
607 if (l != k && !(m & (1u << l)))
609 s->pos += 2 * g->
node[g->
perm[p + l]].hlen;
611 s->cost = g->
cost(external, s->pos);
617 node[k] += (1u << n) - (2u << k);
624 for (
uint i = 0; i < n; i++)
626 g->swap(p + i, p + best[i]);
627 for (
uint j = i + 1; j < n; j++)
638 using namespace Gecko;
642 Graph::init(
uint nodes)
644 node.push_back(
Node(-1, 0, 1, Node::null));
645 adj.push_back(Node::null);
660 node.push_back(
Node(-1, length));
665 std::vector<Node::Index>
668 std::vector<Node::Index> neighbor;
671 neighbor.push_back(adj[
a]);
680 if (!i || !j || i == j || !(last_node <= i && i <= nodes()))
685 for (
Node::Index k = i - 1; node[k].arc == Arc::null; k--)
705 adj.erase(adj.begin() +
a);
706 weight.erase(weight.begin() +
a);
707 bond.erase(bond.begin() +
a);
719 return remove_arc(arc_index(i, j));
726 bool success = remove_arc(i, j);
729 success = remove_arc(j, i);
754 if (node_begin(i) <= a && a < node_end(i))
760 throw std::runtime_error(
"internal data structure corrupted");
771 if (node_begin(i) <= a && a < node_end(i))
781 Graph::directed()
const
787 if (!arc_index(j, i))
802 insert_arc(i, j, w, b);
822 for (
Arc::Index b = node_begin(j); b < node_end(j); b++)
825 q = node[adj[
b]].parent;
828 g->update(p, q, w * part[b], m * part[b]);
834 g->update(p, q, w, m);
840 Graph::cost(
const vector<Arc::Index>& subset,
Float pos)
const
843 for (
Arc::ConstPtr ap = subset.begin(); ap != subset.end(); ap++)
847 Float l = fabs(node[j].pos - pos);
864 while (node_end(i) <=
a)
869 Float l = length(i, j);
873 return functional->mean(c);
888 Float p = node[i].pos - node[i].hlen;
903 vector<WeightedValue> v;
904 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
912 return v.empty() ? -1 : functional->optimum(v);
919 progress->beginphase(
this,
string(
"coarse"));
925 DynamicHeap<Node::Index, Float> heap;
928 node[i].parent = Node::null;
930 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
939 vector<Node::Index> child(1, Node::null);
940 while (!heap.empty())
953 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
958 heap.update(j, w - 2 * bond[a]);
964 vector<Float> part = bond;
971 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
987 max /= GECKO_PART_FRAC;
990 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
991 if (0 < part[a] && part[a] < max)
999 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
1004 g->
node[
p].hlen += part[
a] * node[i].hlen;
1012 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
1014 transfer(g, part, p, a);
1020 for (
Arc::Index c = node_begin(j); c < node_end(j); c++)
1025 transfer(g, part, p, c, part[b]);
1035 throw runtime_error(
"directed edge found");
1040 vector<Float> t = bond;
1043 progress->endphase(
this,
false);
1052 progress->beginphase(
this,
string(
"refine"));
1055 DynamicHeap<Node::Index, Float> heap;
1060 node[i].pos = graph->
node[
p].pos;
1066 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
1079 while (!heap.empty())
1083 node[i].pos = optimal(i);
1084 for (
Arc::Index a = node_begin(i); a < node_end(i); a++)
1088 if (heap.find(j, w))
1090 heap.update(j, w + weight[a]);
1096 progress->endphase(
this,
true);
1101 Graph::relax(
bool compatible,
uint m)
1103 progress->beginphase(
this, compatible ?
string(
"crelax") :
string(
"frelax"));
1105 for (
uint k = 0; k < perm.size() && !progress->quit(); k++)
1108 if (!compatible || !persistent(i))
1110 node[i].pos = optimal(i);
1114 progress->endphase(
this,
true);
1121 if (n > perm.size())
1123 n =
uint(perm.size());
1125 ostringstream count;
1126 count << setw(2) << n;
1127 progress->beginphase(
this,
string(
"perm") + count.str());
1128 Subgraph* subgraph =
new Subgraph(
this, n);
1129 for (
uint k = 0; k <= perm.size() - n && !progress->quit(); k++)
1131 subgraph->optimize(k);
1134 progress->endphase(
this,
true);
1139 Graph::place(
bool sort)
1141 place(sort, 0,
uint(perm.size()));
1151 stable_sort(perm.begin() + k, perm.begin() + k + n,
1156 for (
Float p = k ? node[perm[k - 1]].pos + node[perm[k - 1]].hlen : 0; n--;
1170 if (n < nodes() && nodes() < edges() && level && !progress->quit())
1172 Graph* graph = coarsen();
1173 graph->
vcycle(n, work + edges());
1183 relax(
true, GECKO_CR_SWEEPS);
1184 relax(
false, GECKO_GS_SWEEPS);
1185 for (
uint w = edges(); w * (n + 1) < work; w *= ++n);
1186 n = std::min(n,
uint(GECKO_WINDOW_MAX));
1197 Graph::random(
uint seed)
1199 static uint state = 1;
1200 state = (seed ? seed : 0x1ed0675 * state + 0xa14f);
1209 for (
uint k = 0; k < perm.size(); k++)
1211 uint r = random() >> 8;
1212 uint l = k + r % (
uint(perm.size()) - k);
1213 std::swap(perm[k], perm[l]);
1222 bond.resize(weight.size());
1225 bond[
a] = functional->bond(weight[a], length(a), k);
1235 this->functional = functional;
1236 progress = this->progress = progress ? progress :
new Progress;
1237 for (level = 0; (1u << level) < nodes(); level++);
1239 Float mincost = cost();
1240 vector<Node::Index> minperm = perm;
1250 for (
uint k = 1; k <= iterations && !progress->
quit(); k++)
1252 progress->
beginiter(
this, k, iterations, window);
1261 progress->
enditer(
this, mincost, c);
1262 if (period && !(k % period))
1274 delete this->progress;
Arc::Index node_begin(Node::Index i) const
std::vector< Index >::const_iterator ConstPtr
std::vector< Float > weight
virtual void beginiter(const Graph *, uint, uint, uint) const
std::vector< Node::Index > adj
Arc::Index node_end(Node::Index i) const
virtual void endorder(const Graph *, Float) const
virtual void enditer(const Graph *, Float, Float) const
std::vector< Node::Index > perm
Arc::Index directed() const
double p(const Vector &x, double t)
void vcycle(uint n, uint work=0)
virtual void beginorder(const Graph *, Float) const
int index(int i, int j, int nx, int ny)
Node::Index insert_node(Float length=1)
virtual bool quit() const
double f(const Vector &p)