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];
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] -= (1
u << j) + m;
465 node[j] += (1
u << 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)
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 < (1
u << n); m++)
603 if (!(m & (1
u << 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 & (1
u << l)))
612 s->cost = g->
cost(external,
s->pos);
618 node[k] += (1
u << n) - (2
u << 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++)
639 using namespace Gecko;
643 Graph::init(
uint nodes)
645 node.push_back(
Node(-1, 0, 1, Node::null));
646 adj.push_back(Node::null);
661 node.push_back(
Node(-1, length));
666 std::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()))
686 for (
Node::Index k = i - 1; node[k].arc == Arc::null; k--)
706 adj.erase(adj.begin() +
a);
707 weight.erase(weight.begin() +
a);
708 bond.erase(bond.begin() +
a);
720 return remove_arc(arc_index(i, j));
727 bool success = remove_arc(i, j);
730 success = remove_arc(j, i);
755 if (node_begin(i) <=
a &&
a < node_end(i))
761 throw std::runtime_error(
"internal data structure corrupted");
772 if (node_begin(i) <=
a &&
a < node_end(i))
782 Graph::directed()
const 788 if (!arc_index(j, i))
803 insert_arc(i, j, w,
b);
826 q = node[adj[
b]].parent;
829 g->update(
p, q, w * part[
b], m * part[
b]);
835 g->update(
p, q, w, m);
841 Graph::cost(
const vector<Arc::Index>& subset,
Float pos)
const 844 for (
Arc::ConstPtr ap = subset.begin(); ap != subset.end(); ap++)
848 Float l = fabs(node[j].pos - pos);
865 while (node_end(i) <=
a)
870 Float l = length(i, j);
874 return functional->mean(c);
889 Float p = node[i].pos - node[i].hlen;
904 vector<WeightedValue> v;
913 return v.empty() ? -1 : functional->optimum(v);
920 progress->beginphase(
this,
string(
"coarse"));
926 DynamicHeap<Node::Index, Float> heap;
929 node[i].parent = Node::null;
940 vector<Node::Index> child(1, Node::null);
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)
1005 g->
node[
p].hlen += part[
a] * node[i].hlen;
1015 transfer(g, part,
p,
a);
1021 for (
Arc::Index c = node_begin(j); c < node_end(j); c++)
1026 transfer(g, part,
p, c, part[
b]);
1036 throw runtime_error(
"directed edge found");
1041 vector<Float>
t = bond;
1044 progress->endphase(
this,
false);
1053 progress->beginphase(
this,
string(
"refine"));
1056 DynamicHeap<Node::Index, Float> heap;
1061 node[i].pos = graph->
node[
p].pos;
1080 while (!heap.empty())
1084 node[i].pos = optimal(i);
1089 if (heap.find(j, w))
1091 heap.update(j, w + weight[
a]);
1097 progress->endphase(
this,
true);
1102 Graph::relax(
bool compatible,
uint m)
1104 progress->beginphase(
this, compatible ?
string(
"crelax") :
string(
"frelax"));
1106 for (
uint k = 0; k < perm.size() && !progress->quit(); k++)
1109 if (!compatible || !persistent(i))
1111 node[i].pos = optimal(i);
1115 progress->endphase(
this,
true);
1122 if (n > perm.size())
1124 n =
uint(perm.size());
1126 ostringstream count;
1127 count << setw(2) << n;
1128 progress->beginphase(
this,
string(
"perm") + count.str());
1129 Subgraph* subgraph =
new Subgraph(
this, n);
1130 for (
uint k = 0; k <= perm.size() - n && !progress->quit(); k++)
1132 subgraph->optimize(k);
1135 progress->endphase(
this,
true);
1140 Graph::place(
bool sort)
1142 place(sort, 0,
uint(perm.size()));
1152 stable_sort(perm.begin() + k, perm.begin() + k + n,
1157 for (
Float p = k ? node[perm[k - 1]].pos + node[perm[k - 1]].hlen : 0; n--;
1171 if (n < nodes() && nodes() < edges() && level && !progress->quit())
1173 Graph* graph = coarsen();
1174 graph->
vcycle(n, work + edges());
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));
1198 Graph::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;
1213 uint l = k + r % (
uint(perm.size()) - k);
1214 std::swap(perm[k], perm[l]);
1223 bond.resize(weight.size());
1226 bond[
a] = functional->bond(weight[
a], length(
a), k);
1236 this->functional = functional_;
1237 progress_ = this->progress = progress_ ? progress_ :
new Progress;
1238 for (level = 0; (1
u << level) < nodes(); level++);
1240 Float mincost = cost();
1241 vector<Node::Index> minperm = perm;
1247 progress->beginorder(
this, mincost);
1251 for (
uint k = 1; k <= iterations && !progress->quit(); k++)
1253 progress->beginiter(
this, k, iterations, window);
1262 progress->enditer(
this, mincost, c);
1263 if (period && !(k % period))
1271 progress->endorder(
this, mincost);
1275 delete this->progress;
std::vector< Index >::const_iterator ConstPtr
Arc::Index node_end(Node::Index i) const
std::vector< Float > weight
std::vector< Node::Index > adj
Arc::Index directed() const
std::vector< Node::Index > perm
Arc::Index node_begin(Node::Index i) const
double p(const Vector &x, double t)
void vcycle(uint n, uint work=0)
int index(int i, int j, int nx, int ny)
Node::Index insert_node(Float length=1)
double u(const Vector &xvec)
double f(const Vector &p)