Generated on Sat Feb 7 2015 02:01:19 for Gecode by doxygen 1.8.9.1
visualnode.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  * Main authors:
4  * Guido Tack <tack@gecode.org>
5  *
6  * Copyright:
7  * Guido Tack, 2006
8  *
9  * Last modified:
10  * $Date: 2013-07-11 12:30:18 +0200 (Thu, 11 Jul 2013) $ by $Author: schulte $
11  * $Revision: 13840 $
12  *
13  * This file is part of Gecode, the generic constraint
14  * development environment:
15  * http://www.gecode.org
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining
18  * a copy of this software and associated documentation files (the
19  * "Software"), to deal in the Software without restriction, including
20  * without limitation the rights to use, copy, modify, merge, publish,
21  * distribute, sublicense, and/or sell copies of the Software, and to
22  * permit persons to whom the Software is furnished to do so, subject to
23  * the following conditions:
24  *
25  * The above copyright notice and this permission notice shall be
26  * included in all copies or substantial portions of the Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35  *
36  */
37 
39 
42 
43 #include <utility>
44 
45 namespace Gecode { namespace Gist {
46 
47  Shape* Shape::leaf;
48  Shape* Shape::hidden;
49 
52  public:
55  Shape::leaf = Shape::allocate(1);
56  (*Shape::leaf)[0] = Extent(Layout::extent);
57  Shape::leaf->computeBoundingBox();
58 
59  Shape::hidden = Shape::allocate(2);
60  (*Shape::hidden)[0] = Extent(Layout::extent);
61  (*Shape::hidden)[1] = Extent(Layout::extent);
62  Shape::hidden->computeBoundingBox();
63  }
65  Shape::deallocate(Shape::leaf);
66  Shape::deallocate(Shape::hidden);
67  }
68  };
69 
72 
74  : SpaceNode(p)
75  , offset(0)
76  {
77  shape = NULL;
78  setDirty(true);
79  setChildrenLayoutDone(false);
80  setHidden(false);
81  setMarked(false);
82  setOnPath(false);
83  setBookmarked(false);
84  }
85 
87  : SpaceNode(root)
88  , offset(0)
89  {
90  shape = NULL;
91  setDirty(true);
92  setChildrenLayoutDone(false);
93  setHidden(false);
94  setMarked(false);
95  setOnPath(false);
96  setBookmarked(false);
97  }
98 
99  void
103  }
104 
105  void
107  VisualNode* cur = this;
108  while (!cur->isDirty()) {
109  cur->setDirty(true);
110  if (! cur->isRoot()) {
111  cur = cur->getParent(na);
112  }
113  }
114  }
115 
116  void
118  LayoutCursor l(this,na);
120  // int nodesLayouted = 1;
121  // clock_t t0 = clock();
122  // while (p.next()) {}
123  // while (p.next()) { nodesLayouted++; }
124  // double t = (static_cast<double>(clock()-t0) / CLOCKS_PER_SEC) * 1000.0;
125  // double nps = static_cast<double>(nodesLayouted) /
126  // (static_cast<double>(clock()-t0) / CLOCKS_PER_SEC);
127  // std::cout << "Layout done. " << nodesLayouted << " nodes in "
128  // << t << " ms. " << nps << " nodes/s." << std::endl;
129  }
130 
132  VisualNode* cur = this;
133  while (cur) {
134  cur->setOnPath(true);
135  cur = cur->getParent(na);
136  }
137  }
138 
140  VisualNode* cur = this;
141  while (!cur->isRoot()) {
142  cur->setOnPath(false);
143  cur = cur->getParent(na);
144  }
145  }
146 
147  int
149  for (int i=getNumberOfChildren(); i--;) {
150  if (getChild(na,i)->isOnPath())
151  return i;
152  }
153  return -1;
154  }
155 
156  void
158  setHidden(!isHidden());
159  dirtyUp(na);
160  }
161 
162  void
163  VisualNode::hideFailed(const NodeAllocator& na, bool onlyDirty) {
164  HideFailedCursor c(this,na,onlyDirty);
166  dirtyUp(na);
167  }
168 
169  void
171  BestNode* curBest, int c_d, int a_d) {
172  bool clear = na.hasLabel(this);
173  BranchLabelCursor c(this,curBest,c_d,a_d,clear,na);
175  dirtyUp(na);
176  }
177 
178  void
180  BestNode* curBest, int c_d, int a_d) {
181  if (na.hasLabel(this)) {
182  // clear labels on path to root
183  VisualNode* p = this;
184  while (p) {
185  na.clearLabel(p);
186  p = p->getParent(na);
187  }
188  } else {
189  // set labels on path to root
190  std::vector<std::pair<VisualNode*,int> > path;
191  VisualNode* p = this;
192  while (p) {
193  path.push_back(std::pair<VisualNode*,int>(p,p->getAlternative(na)));
194  p = p->getParent(na);
195  }
196  while (!path.empty()) {
197  std::pair<VisualNode*,int> cur = path.back(); path.pop_back();
198  if (p) {
199  std::string l =
200  cur.first->getBranchLabel(na,p,p->getChoice(),
201  curBest,c_d,a_d,cur.second);
202  na.setLabel(cur.first,QString(l.c_str()));
203  }
204  p = cur.first;
205  }
206  }
207  dirtyUp(na);
208  }
209 
210  void
212  UnhideAllCursor c(this,na);
214  dirtyUp(na);
215  }
216 
217  void
219  if (getStatus() == STOP)
220  setStatus(UNSTOP);
221  else if (getStatus() == UNSTOP)
222  setStatus(STOP);
223  dirtyUp(na);
224  }
225 
226  void
228  UnstopAllCursor c(this,na);
230  dirtyUp(na);
231  }
232 
233  void
235 
236  bool
239  if (x < box.left ||
240  x > box.right ||
241  depth >= getShape()->depth()) {
242  return false;
243  }
244  Extent theExtent;
245  if (getShape()->getExtentAtDepth(depth, theExtent)) {
246  return (theExtent.l <= x && x <= theExtent.r);
247  } else {
248  return false;
249  }
250  }
251 
252  VisualNode*
253  VisualNode::findNode(const NodeAllocator& na, int x, int y) {
254  VisualNode* cur = this;
255  int depth = y / Layout::dist_y;
256 
257  while (depth > 0 && cur != NULL) {
258  if (cur->isHidden()) {
259  break;
260  }
261  VisualNode* oldCur = cur;
262  cur = NULL;
263  for (unsigned int i=0; i<oldCur->getNumberOfChildren(); i++) {
264  VisualNode* nextChild = oldCur->getChild(na,i);
265  int newX = x - nextChild->getOffset();
266  if (nextChild->containsCoordinateAtDepth(newX, depth - 1)) {
267  cur = nextChild;
268  x = newX;
269  break;
270  }
271  }
272  depth--;
273  y -= Layout::dist_y;
274  }
275 
276  if(cur == this && !cur->containsCoordinateAtDepth(x, 0)) {
277  return NULL;
278  }
279  return cur;
280  }
281 
282  std::string
284  return "";
285  }
286 
287  std::string
289  VisualNode* p, const Choice* c,
290  BestNode* curBest, int c_d, int a_d, int alt) {
291  std::ostringstream oss;
292  p->acquireSpace(na,curBest,c_d,a_d);
293  p->getWorkingSpace()->print(*c,alt,oss);
294  return oss.str();
295  }
296 
297 
299  class Layouter {
300  public:
302  template<class S1, class S2>
303  static int getAlpha(const S1& shape1, int depth1,
304  const S2& shape2, int depth2);
306  template<class S1, class S2>
307  static void merge(Extent* result,
308  const S1& shape1, int depth1,
309  const S2& shape2, int depth2, int alpha);
310  };
311 
312  template<class S1, class S2>
313  int
314  Layouter::getAlpha(const S1& shape1, int depth1,
315  const S2& shape2, int depth2) {
316  int alpha = Layout::minimalSeparation;
317  int extentR = 0;
318  int extentL = 0;
319  for (int i=0; i<depth1 && i<depth2; i++) {
320  extentR += shape1[i].r;
321  extentL += shape2[i].l;
322  alpha = std::max(alpha, extentR - extentL + Layout::minimalSeparation);
323  }
324  return alpha;
325  }
326 
327  template<class S1, class S2>
328  void
330  const S1& shape1, int depth1,
331  const S2& shape2, int depth2, int alpha) {
332  if (depth1 == 0) {
333  for (int i=depth2; i--;)
334  result[i] = shape2[i];
335  } else if (depth2 == 0) {
336  for (int i=depth1; i--;)
337  result[i] = shape1[i];
338  } else {
339  // Extend the topmost right extent by alpha. This, in effect,
340  // moves the second shape to the right by alpha units.
341  int topmostL = shape1[0].l;
342  int topmostR = shape2[0].r;
343  int backoffTo1 =
344  shape1[0].r - alpha - shape2[0].r;
345  int backoffTo2 =
346  shape2[0].l + alpha - shape1[0].l;
347 
348  result[0] = Extent(topmostL, topmostR+alpha);
349 
350  // Now, since extents are given in relative units, in order to
351  // compute the extents of the merged shape, we can just collect the
352  // extents of shape1 and shape2, until one of the shapes ends. If
353  // this happens, we need to "back-off" to the axis of the deeper
354  // shape in order to properly determine the remaining extents.
355  int i=1;
356  for (; i<depth1 && i<depth2; i++) {
357  Extent currentExtent1 = shape1[i];
358  Extent currentExtent2 = shape2[i];
359  int newExtentL = currentExtent1.l;
360  int newExtentR = currentExtent2.r;
361  result[i] = Extent(newExtentL, newExtentR);
362  backoffTo1 += currentExtent1.r - currentExtent2.r;
363  backoffTo2 += currentExtent2.l - currentExtent1.l;
364  }
365 
366  // If shape1 is deeper than shape2, back off to the axis of shape1,
367  // and process the remaining extents of shape1.
368  if (i<depth1) {
369  Extent currentExtent1 = shape1[i];
370  int newExtentL = currentExtent1.l;
371  int newExtentR = currentExtent1.r;
372  result[i] = Extent(newExtentL, newExtentR+backoffTo1);
373  ++i;
374  for (; i<depth1; i++) {
375  result[i] = shape1[i];
376  }
377  }
378 
379  // Vice versa, if shape2 is deeper than shape1, back off to the
380  // axis of shape2, and process the remaining extents of shape2.
381  if (i<depth2) {
382  Extent currentExtent2 = shape2[i];
383  int newExtentL = currentExtent2.l;
384  int newExtentR = currentExtent2.r;
385  result[i] = Extent(newExtentL+backoffTo2, newExtentR);
386  ++i;
387  for (; i<depth2; i++) {
388  result[i] = shape2[i];
389  }
390  }
391  }
392  }
393 
394  void
396  if (shape != s)
398  shape = s;
400  }
401 
402  void
404  int numberOfShapes = getNumberOfChildren();
405  Extent extent;
406  if (na.hasLabel(this)) {
407  int ll = na.getLabel(this).length();
408  ll *= 7;
409  VisualNode* p = getParent(na);
410  int alt = 0;
411  int n_alt = 1;
412  if (p) {
413  alt = getAlternative(na);
414  n_alt = p->getNumberOfChildren();
415  }
416  extent = Extent(Layout::extent);
417  if (alt==0 && n_alt > 1) {
418  extent.l = std::min(extent.l, -ll);
419  } else if (alt==n_alt-1 && n_alt > 1) {
420  extent.r = std::max(extent.r, ll);
421  } else {
422  extent.l = std::min(extent.l, -ll);
423  extent.r = std::max(extent.r, ll);
424  }
425  } else {
426  if (numberOfShapes==0) {
427  setShape(Shape::leaf);
428  return;
429  } else {
430  extent = Extent(Layout::extent);
431  }
432  }
433 
434  int maxDepth = 0;
435  for (int i = numberOfShapes; i--;)
436  maxDepth = std::max(maxDepth, getChild(na,i)->getShape()->depth());
437  Shape* mergedShape;
438  if (getShape() && getShape() != Shape::leaf &&
439  getShape()->depth() >= maxDepth+1) {
440  mergedShape = getShape();
441  mergedShape->setDepth(maxDepth+1);
442  } else {
443  mergedShape = Shape::allocate(maxDepth+1);
444  }
445  (*mergedShape)[0] = extent;
446  if (numberOfShapes < 1) {
447  setShape(mergedShape);
448  } else if (numberOfShapes == 1) {
449  getChild(na,0)->setOffset(0);
450  const Shape* childShape = getChild(na,0)->getShape();
451  for (int i=childShape->depth(); i--;)
452  (*mergedShape)[i+1] = (*childShape)[i];
453  (*mergedShape)[1].extend(- extent.l, - extent.r);
454  setShape(mergedShape);
455  } else {
456  // alpha stores the necessary distances between the
457  // axes of the shapes in the list: alpha[i].first gives the distance
458  // between shape[i] and shape[i-1], when shape[i-1] and shape[i]
459  // are merged left-to-right; alpha[i].second gives the distance between
460  // shape[i] and shape[i+1], when shape[i] and shape[i+1] are merged
461  // right-to-left.
462  assert(root->copy != NULL);
463  Region r(*root->copy);
464  std::pair<int,int>* alpha =
465  r.alloc<std::pair<int,int> >(numberOfShapes);
466 
467  // distance between the leftmost and the rightmost axis in the list
468  int width = 0;
469 
470  Extent* currentShapeL = r.alloc<Extent>(maxDepth);
471  int ldepth = getChild(na,0)->getShape()->depth();
472  for (int i=ldepth; i--;)
473  currentShapeL[i] = (*getChild(na,0)->getShape())[i];
474 
475  // After merging, we can pick the result of either merging left or right
476  // Here we chose the result of merging right
477  Shape* rShape = getChild(na,numberOfShapes-1)->getShape();
478  int rdepth = rShape->depth();
479  for (int i=rdepth; i--;)
480  (*mergedShape)[i+1] = (*rShape)[i];
481  Extent* currentShapeR = &(*mergedShape)[1];
482 
483  for (int i = 1; i < numberOfShapes; i++) {
484  // Merge left-to-right. Note that due to the asymmetry of the
485  // merge operation, nextAlphaL is the distance between the
486  // *leftmost* axis in the shape list, and the axis of
487  // nextShapeL; what we are really interested in is the distance
488  // between the *previous* axis and the axis of nextShapeL.
489  // This explains the correction.
490 
491  Shape* nextShapeL = getChild(na,i)->getShape();
492  int nextAlphaL =
493  Layouter::getAlpha<Extent*,Shape>(&currentShapeL[0], ldepth,
494  *nextShapeL, nextShapeL->depth());
495  Layouter::merge<Extent*,Shape>(&currentShapeL[0],
496  &currentShapeL[0], ldepth,
497  *nextShapeL, nextShapeL->depth(),
498  nextAlphaL);
499  ldepth = std::max(ldepth,nextShapeL->depth());
500  alpha[i].first = nextAlphaL - width;
501  width = nextAlphaL;
502 
503  // Merge right-to-left. Here, a correction of nextAlphaR is
504  // not required.
505  Shape* nextShapeR = getChild(na,numberOfShapes-1-i)->getShape();
506  int nextAlphaR =
507  Layouter::getAlpha<Shape,Extent*>(*nextShapeR, nextShapeR->depth(),
508  &currentShapeR[0], rdepth);
509  Layouter::merge<Shape,Extent*>(&currentShapeR[0],
510  *nextShapeR, nextShapeR->depth(),
511  &currentShapeR[0], rdepth,
512  nextAlphaR);
513  rdepth = std::max(rdepth,nextShapeR->depth());
514  alpha[numberOfShapes - i].second = nextAlphaR;
515  }
516 
517  // The merged shape has to be adjusted to its topmost extent
518  (*mergedShape)[1].extend(- extent.l, - extent.r);
519 
520  // After the loop, the merged shape has the same axis as the
521  // leftmost shape in the list. What we want is to move the axis
522  // such that it is the center of the axis of the leftmost shape in
523  // the list and the axis of the rightmost shape.
524  int halfWidth = false ? 0 : width / 2;
525  (*mergedShape)[1].move(- halfWidth);
526 
527  // Finally, for the offset lists. Now that the axis of the merged
528  // shape is at the center of the two extreme axes, the first shape
529  // needs to be offset by -halfWidth units with respect to the new
530  // axis. As for the offsets for the other shapes, we take the
531  // median of the alphaL and alphaR values, as suggested in
532  // Kennedy's paper.
533  int offset = - halfWidth;
534  getChild(na,0)->setOffset(offset);
535  for (int i = 1; i < numberOfShapes; i++) {
536  offset += (alpha[i].first + alpha[i].second) / 2;
537  getChild(na,i)->setOffset(offset);
538  }
539  setShape(mergedShape);
540  }
541  }
542 
543 }}
544 
545 // STATISTICS: gist-any
A cursor that computes a tree layout for VisualNodes.
Definition: layoutcursor.hh:48
bool isOnPath(void)
Return whether node is on the path.
Definition: visualnode.hpp:197
Node representing stop point.
Definition: spacenode.hh:53
std::string toolTip(NodeAllocator &na, BestNode *curBest, int c_d, int a_d)
Return string that is used as a tool tip.
Definition: visualnode.cpp:283
void unhideAll(const NodeAllocator &na)
Unhide all nodes in the subtree of this node.
Definition: visualnode.cpp:211
int right
Right coordinate.
Definition: visualnode.hh:61
void labelPath(NodeAllocator &na, BestNode *curBest, int c_d, int a_d)
Create or clear branch labels on path to root.
Definition: visualnode.cpp:179
void setOnPath(bool onPath0)
Set whether node is on the path.
Definition: visualnode.hpp:202
int left
Left coordinate.
Definition: visualnode.hh:59
NNF * l
Left subtree.
Definition: bool-expr.cpp:244
void setMarked(bool m)
Set mark of this node.
Definition: visualnode.hpp:182
static const int extent
Definition: visualnode.hh:51
void dispose(void)
Free allocated memory.
Definition: visualnode.cpp:100
int l
Left extent.
Definition: visualnode.hh:70
Static reference to the currently best space.
Definition: spacenode.hh:84
const FloatNum max
Largest allowed float value.
Definition: float.hh:831
void setLabel(T *n, const QString &l)
Set label of node n to l.
Definition: node.hpp:136
void computeBoundingBox(void)
Compute bounding box.
Definition: visualnode.hpp:114
bool isDirty(void)
Return whether node is marked as dirty.
Definition: visualnode.hpp:157
void layout(const NodeAllocator &na)
Compute layout for the subtree of this node.
Definition: visualnode.cpp:117
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition: region.hpp:326
bool isHidden(void)
Return if node is hidden.
Definition: visualnode.hpp:133
long long int ll(int x)
Cast x into a long long int.
Definition: mult.hpp:57
void setChildrenLayoutDone(bool d)
Mark node whether the layout of the node's children has been completed.
Definition: visualnode.hpp:172
void setDirty(bool d)
Mark node as dirty.
Definition: visualnode.hpp:162
Node allocator.
Definition: node.hh:52
unsigned int getNumberOfChildren(void) const
Return the number of children.
Definition: node.hpp:218
void path(Home home, int offset, const IntVarArgs &x, IntVar s, IntVar e, IntConLevel icl)
Post propagator such that x forms a Hamiltonian path.
Definition: circuit.cpp:128
int offset
Relative offset from the parent node.
Definition: visualnode.hh:142
Handle to region.
Definition: region.hpp:61
A cursor that marks failed subtrees as hidden.
Definition: nodecursor.hh:90
void setHidden(bool h)
Set hidden state to h.
Definition: visualnode.hpp:138
const Space * getWorkingSpace(void) const
Return working space (if present).
Definition: spacenode.hpp:116
static Shape * allocate(int d)
Construct shape of depth d.
Definition: visualnode.hpp:85
void toggleStop(const NodeAllocator &na)
Do not stop at this node.
Definition: visualnode.cpp:218
Computation spaces.
Definition: core.hpp:1362
void setBookmarked(bool m)
Set bookmark of this node.
Definition: visualnode.hpp:192
void setStatus(NodeStatus s)
Set status to s.
Definition: spacenode.hpp:69
int getAlternative(const NodeAllocator &na) const
Return alternative number of this node.
Definition: spacenode.hpp:173
std::string getBranchLabel(NodeAllocator &na, VisualNode *p, const Choice *c, BestNode *curBest, int c_d, int a_d, int alt)
Return string that describes the branch.
Definition: visualnode.cpp:288
void acquireSpace(NodeAllocator &na, BestNode *curBest, int c_d, int a_d)
Acquire working space, either from parent or by recomputation.
Definition: spacenode.cpp:160
Run a cursor over a tree, processing nodes in post-order.
Definition: nodevisitor.hh:60
void labelBranches(NodeAllocator &na, BestNode *curBest, int c_d, int a_d)
Create or clear branch labels in subtree.
Definition: visualnode.cpp:170
Gecode::FloatVal c(-8, 8)
void unstopAll(const NodeAllocator &na)
Do not stop at any stop node in the subtree of this node.
Definition: visualnode.cpp:227
const Choice * getChoice(void)
Return choice of this node.
Definition: spacenode.hpp:185
int getParent(void) const
Return the parent.
Definition: node.hpp:186
NodeStatus getStatus(void) const
Return current status of the node.
Definition: spacenode.hpp:75
QString getLabel(T *n) const
Get label of node n.
Definition: node.hpp:148
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:236
bool isRoot(void) const
Check if this node is the root of a tree.
Definition: node.hpp:215
const FloatNum min
Smallest allowed float value.
Definition: float.hh:833
Gecode::IntArgs i(4, 1, 2, 3, 4)
Helper functions for the layout algorithm.
Definition: visualnode.cpp:299
void clearLabel(T *n)
Remove label of node n.
Definition: node.hpp:142
NNF * r
Right subtree.
Definition: bool-expr.cpp:246
const unsigned int a_d
Create a clone during recomputation if distance is greater than a_d (adaptive distance) ...
Definition: search.hh:99
void print(const Choice &c, unsigned int a, std::ostream &o) const
Print branch for choice c and alternative a.
Definition: core.cpp:454
static const int dist_y
Definition: visualnode.hh:50
ShapeAllocator(void)
Constructor.
Definition: visualnode.cpp:54
A cursor that marks all nodes in the tree as not stopping.
Definition: nodecursor.hh:121
int getPathAlternative(const NodeAllocator &na)
Return the alternative of the child that is on the path (-1 if none)
Definition: visualnode.cpp:148
void changedStatus(const NodeAllocator &na)
Signal that the status has changed.
Definition: visualnode.cpp:234
Shape * getShape(void)
Return the shape of this node.
Definition: visualnode.hpp:207
int depth(void) const
Return depth of the shape.
Definition: visualnode.hpp:64
Node * x
Pointer to corresponding Boolean expression node.
Definition: bool-expr.cpp:253
Choice for performing commit
Definition: core.hpp:1036
void dirtyUp(const NodeAllocator &na)
Mark all nodes up the path to the parent as dirty.
Definition: visualnode.cpp:106
Run a cursor over a tree, processing nodes in pre-order.
Definition: nodevisitor.hh:76
static Shape * hidden
Static shape for hidden nodes.
Definition: visualnode.hh:110
Shape * shape
Shape of this node.
Definition: visualnode.hh:144
ShapeAllocator shapeAllocator
Allocate shapes statically.
Definition: visualnode.cpp:71
void toggleHidden(const NodeAllocator &na)
Toggle whether this node is hidden.
Definition: visualnode.cpp:157
A cursor that marks all nodes in the tree as not hidden.
Definition: nodecursor.hh:108
const BoundingBox & getBoundingBox(void) const
Return bounding box.
Definition: visualnode.hpp:128
static void merge(Extent *result, const S1 &shape1, int depth1, const S2 &shape2, int depth2, int alpha)
Merge shape1 and shape2 into result with distance alpha.
Definition: visualnode.cpp:329
void unPathUp(const NodeAllocator &na)
Set all nodes from the node to the root not to be on the path.
Definition: visualnode.cpp:139
Node class that supports visual layout
Definition: visualnode.hh:129
int getOffset(void)
Return offset off this node from its parent.
Definition: visualnode.hpp:151
void dispose(void)
Free allocated memory.
Definition: spacenode.cpp:295
Allocate shapes statically.
Definition: visualnode.cpp:51
VisualNode * findNode(const NodeAllocator &na, int x, int y)
Find a node in this subtree at coordinates x, y.
Definition: visualnode.cpp:253
VisualNode(int p)
Construct with parent p.
Definition: visualnode.cpp:73
const unsigned int c_d
Create a clone after every c_d commits (commit distance)
Definition: search.hh:97
void computeShape(const NodeAllocator &na, VisualNode *root)
Compute the shape according to the shapes of the children.
Definition: visualnode.cpp:403
static void deallocate(Shape *)
Definition: visualnode.hpp:95
The shape of a subtree.
Definition: visualnode.hh:87
A node of a search tree of Gecode spaces.
Definition: spacenode.hh:93
static int getAlpha(const S1 &shape1, int depth1, const S2 &shape2, int depth2)
Compute distance needed between shape1 and shape2.
Definition: visualnode.cpp:314
Space * copy
A copy used for recomputation, or NULL.
Definition: spacenode.hh:100
void pathUp(const NodeAllocator &na)
Set all nodes from the node to the root to be on the path.
Definition: visualnode.cpp:131
static Shape * leaf
Static shape for leaf nodes.
Definition: visualnode.hh:108
Gecode toplevel namespace
void setDepth(int d)
Set depth of the shape to d (must be smaller than original depth)
Definition: visualnode.hpp:67
int getChild(int n) const
Return index of child no n.
Definition: node.hpp:199
bool containsCoordinateAtDepth(int x, int depth)
Check if the x at depth depth lies in this subtree.
Definition: visualnode.cpp:237
int r
Right extent.
Definition: visualnode.hh:72
bool hasLabel(T *n) const
Return whether node n has a label.
Definition: node.hpp:130
void setShape(Shape *s)
Set the shape of this node.
Definition: visualnode.cpp:395
Extent representing shape of a tree at one depth level
Definition: visualnode.hh:67
A cursor that labels branches.
Definition: nodecursor.hh:195
static const int minimalSeparation
Definition: visualnode.hh:52
void hideFailed(const NodeAllocator &na, bool onlyDirty=false)
Hide all failed subtrees of this node.
Definition: visualnode.cpp:163
Node representing ignored stop point.
Definition: spacenode.hh:54