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; }
151template <
typename T,
typename P,
class C,
class M >
152DynamicHeap<T, P, C, M>::DynamicHeap(
size_t count)
157template <
typename T,
typename P,
class C,
class M >
159DynamicHeap<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));
173template <
typename T,
typename P,
class C,
class M >
175DynamicHeap<T, P, C, M>::update(T data, P priority)
177 unsigned int i =
index[data];
178 heap[i].priority = priority;
183template <
typename T,
typename P,
class C,
class M >
185DynamicHeap<T, P, C, M>::top(T& data)
198template <
typename T,
typename P,
class C,
class M >
200DynamicHeap<T, P, C, M>::top(T& data, P& priority)
205 priority = heap[0].priority;
214template <
typename T,
typename P,
class C,
class M >
216DynamicHeap<T, P, C, M>::pop()
220 T data = heap[0].data;
221 swap(0, (
unsigned int)heap.size() - 1);
236template <
typename T,
typename P,
class C,
class M >
238DynamicHeap<T, P, C, M>::extract(T& data)
251template <
typename T,
typename P,
class C,
class M >
253DynamicHeap<T, P, C, M>::extract(T& data, P& priority)
258 priority = heap[0].priority;
267template <
typename T,
typename P,
class C,
class M >
269DynamicHeap<T, P, C, M>::erase(T data)
275 unsigned int i =
index[data];
276 swap(i, heap.size() - 1);
287template <
typename T,
typename P,
class C,
class M >
289DynamicHeap<T, P, C, M>::find(T data)
const
294template <
typename T,
typename P,
class C,
class M >
296DynamicHeap<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;
308template <
typename T,
typename P,
class C,
class M >
310DynamicHeap<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;
319template <
typename T,
typename P,
class C,
class M >
321DynamicHeap<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;
333template <
typename T,
typename P,
class C,
class M >
335DynamicHeap<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];
388using namespace Gecko;
391Subgraph::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];
402Subgraph::cost(
uint k)
const
404 Subnode::Index i = perm[k];
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];
436Subgraph::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);
529 for (
uint j = 0; j < n; j++)
544Subgraph::optimize(
uint p)
550 for (Subnode::Index k = 0; (
uint) k < n; k++)
552 best[k] = perm[k] = k;
557#if GECKO_WITH_ADJLIST
562 std::vector<Arc::Index> external;
567 for (l = 0; (
uint) l < n && g->perm[
p + l] != j; l++);
570 external.push_back(
a);
575#if GECKO_WITH_ADJLIST
585#if GECKO_WITH_ADJLIST
601 node[k] = cache + (k << n);
602 for (
uint m = 0; m < (1u << n); m++)
603 if (!(m & (1u << k)))
605 Subnode*
s = cache + (k << n) + m;
606 s->pos = q + g->
node[i].hlen;
607 for (Subnode::Index l = 0; (
uint) l < n; l++)
608 if (l != k && !(m & (1u << l)))
612 s->cost = g->
cost(external,
s->pos);
618 node[k] += (1u << n) - (2u << k);
625 for (
uint i = 0; i < n; i++)
627 g->swap(
p + i,
p + best[i]);
628 for (
uint j = i + 1; j < n; j++)
639using namespace Gecko;
643Graph::init(
uint nodes)
666std::vector<Node::Index>
669 std::vector<Node::Index> neighbor;
672 neighbor.push_back(
adj[
a]);
681 if (!i || !j || i == j || !(last_node <= i && i <=
nodes()))
761 throw std::runtime_error(
"internal data structure corrupted");
829 g->update(
p, q, w * part[
b], m * part[
b]);
835 g->update(
p, q, w, m);
844 for (
Arc::ConstPtr ap = subset.begin(); ap != subset.end(); ap++)
904 vector<WeightedValue> v;
926 DynamicHeap<Node::Index, Float> heap;
941 while (!heap.empty())
959 heap.update(j, w - 2 *
bond[
a]);
965 vector<Float> part =
bond;
988 max /= GECKO_PART_FRAC;
992 if (0 < part[
a] && part[
a] < max)
1015 transfer(g, part,
p,
a);
1026 transfer(g, part,
p, c, part[
b]);
1036 throw runtime_error(
"directed edge found");
1041 vector<Float>
t =
bond;
1056 DynamicHeap<Node::Index, Float> heap;
1080 while (!heap.empty())
1084 node[i].pos = optimal(i);
1089 if (heap.find(j, w))
1091 heap.update(j, w +
weight[
a]);
1111 node[i].pos = optimal(i);
1122 if (n >
perm.size())
1126 ostringstream count;
1127 count << setw(2) << n;
1129 Subgraph* subgraph =
new Subgraph(
this, n);
1132 subgraph->optimize(k);
1152 stable_sort(
perm.begin() + k,
perm.begin() + k + n,
1184 relax(
true, GECKO_CR_SWEEPS);
1185 relax(
false, GECKO_GS_SWEEPS);
1186 for (
uint w =
edges(); w * (n + 1) < work; w *= ++n);
1187 n = std::min(n,
uint(GECKO_WINDOW_MAX));
1198Graph::random(
uint seed)
1200 static uint state = 1;
1201 state = (seed ? seed : 0x1ed0675 * state + 0xa14f);
1210 for (
uint k = 0; k <
perm.size(); k++)
1212 uint r = random() >> 8;
1238 for (level = 0; (1u << level) <
nodes(); level++);
1241 vector<Node::Index> minperm =
perm;
1263 if (period && !(k % period))
std::vector< Index >::const_iterator ConstPtr
virtual bool less(const WeightedSum &s, const WeightedSum &t) const
virtual Float optimum(const std::vector< WeightedValue > &v) const =0
virtual void accumulate(WeightedSum &s, const WeightedValue &t) const
virtual Float bond(Float w, Float l, uint k) const =0
virtual WeightedSum sum(const WeightedSum &s, const WeightedValue &t) const
virtual Float mean(const WeightedSum &sum) const =0
void vcycle(uint n, uint work=0)
bool placed(Node::Index i) const
void order(Functional *functional, uint iterations=1, uint window=2, uint period=2, uint seed=0, Progress *progress=0)
Arc::Index node_begin(Node::Index i) const
Node::Index arc_target(Arc::Index a) const
Arc::Index reverse_arc(Arc::Index a) const
Arc::Index node_end(Node::Index i) const
Arc::Index directed() const
std::vector< Node::Index > perm
Arc::Index arc_index(Node::Index i, Node::Index j) const
Node::Index insert_node(Float length=1)
std::vector< Float > weight
bool persistent(Node::Index i) const
void refine(const Graph *graph)
bool remove_arc(Arc::Index a)
std::vector< Float > bond
bool remove_edge(Node::Index i, Node::Index j)
Arc::Index insert_arc(Node::Index i, Node::Index j, Float w=1, Float b=1)
std::vector< Node::Index > adj
void relax(bool compatible, uint m=1)
std::vector< Node::Index > node_neighbors(Node::Index i) const
void place(bool sort=false)
Node::Index arc_source(Arc::Index a) const
void shuffle(uint seed=0)
Float length(Node::Index i, Node::Index j) const
virtual void beginorder(const Graph *, Float) const
virtual bool quit() const
virtual void endorder(const Graph *, Float) const
virtual void beginiter(const Graph *, uint, uint, uint) const
virtual void endphase(const Graph *, bool) const
virtual void beginphase(const Graph *, std::string) const
virtual void enditer(const Graph *, Float, Float) const
int index(int i, int j, int nx, int ny)
real_t f(const Vector &p)
real_t p(const Vector &x, real_t t)