summaryrefslogtreecommitdiffstats
path: root/src/removeoverlap
diff options
context:
space:
mode:
authorTim Dwyer <tgdwyer@gmail.com>2006-07-12 00:55:58 +0000
committertgdwyer <tgdwyer@users.sourceforge.net>2006-07-12 00:55:58 +0000
commit12b21e1d27f43deaa748419919b40b80cedd0ddd (patch)
tree9748126a763c5a10b9ee25401cf2463a65a2aed6 /src/removeoverlap
parentupdate (diff)
downloadinkscape-12b21e1d27f43deaa748419919b40b80cedd0ddd.tar.gz
inkscape-12b21e1d27f43deaa748419919b40b80cedd0ddd.zip
Previously graph layout was done using the Kamada-Kawai layout algorithm
implemented in Boost. I am replacing this with a custom implementation of a constrained stress-majorization algorithm. The stress-majorization algorithm is more robust and has better convergence characteristics than Kamada-Kawai, and also simple constraints can be placed on node position (for example, to enforce downward-pointing edges, non-overlap constraints, or cluster constraints). Another big advantage is that we no longer need Boost. I've tested the basic functionality, but I have yet to properly handle disconnected graphs or to properly scale the resulting layout. This commit also includes significant refactoring... the quadratic program solver - libvpsc (Variable Placement with Separation Constraints) has been moved to src/libvpsc and the actual graph layout algorithm is in libcola. (bzr r1394)
Diffstat (limited to 'src/removeoverlap')
-rw-r--r--src/removeoverlap/Makefile_insert23
-rw-r--r--src/removeoverlap/block.cpp403
-rw-r--r--src/removeoverlap/block.h68
-rw-r--r--src/removeoverlap/blocks.cpp196
-rw-r--r--src/removeoverlap/blocks.h53
-rw-r--r--src/removeoverlap/constraint.cpp47
-rw-r--r--src/removeoverlap/constraint.h58
-rw-r--r--src/removeoverlap/generate-constraints.cpp303
-rw-r--r--src/removeoverlap/generate-constraints.h78
-rw-r--r--src/removeoverlap/pairingheap/.cvsignore5
-rw-r--r--src/removeoverlap/pairingheap/PairingHeap.cpp333
-rw-r--r--src/removeoverlap/pairingheap/PairingHeap.h119
-rw-r--r--src/removeoverlap/pairingheap/dsexceptions.h9
-rwxr-xr-xsrc/removeoverlap/placement_SolveVPSC.cpp130
-rwxr-xr-xsrc/removeoverlap/placement_SolveVPSC.h53
-rw-r--r--src/removeoverlap/remove_rectangle_overlap-test.cpp308
-rwxr-xr-xsrc/removeoverlap/remove_rectangle_overlap.cpp115
-rwxr-xr-xsrc/removeoverlap/remove_rectangle_overlap.h21
-rw-r--r--src/removeoverlap/removeoverlap.cpp6
-rw-r--r--src/removeoverlap/solve_VPSC.cpp412
-rw-r--r--src/removeoverlap/solve_VPSC.h57
-rw-r--r--src/removeoverlap/variable.cpp15
-rw-r--r--src/removeoverlap/variable.h51
23 files changed, 4 insertions, 2859 deletions
diff --git a/src/removeoverlap/Makefile_insert b/src/removeoverlap/Makefile_insert
index e28304431..9df2ca2e3 100644
--- a/src/removeoverlap/Makefile_insert
+++ b/src/removeoverlap/Makefile_insert
@@ -6,26 +6,5 @@ removeoverlap/clean:
rm -f removeoverlap/libremoveoverlap.a $(removeoverlap_libremoveoverlap_a_OBJECTS)
removeoverlap_libremoveoverlap_a_SOURCES = \
- removeoverlap/block.cpp \
- removeoverlap/block.h \
- removeoverlap/blocks.cpp \
- removeoverlap/blocks.h \
- removeoverlap/constraint.cpp \
- removeoverlap/constraint.h \
- removeoverlap/generate-constraints.cpp \
- removeoverlap/generate-constraints.h \
- removeoverlap/remove_rectangle_overlap.cpp \
- removeoverlap/remove_rectangle_overlap.h \
removeoverlap/removeoverlap.cpp \
- removeoverlap/removeoverlap.h \
- removeoverlap/solve_VPSC.cpp \
- removeoverlap/solve_VPSC.h \
- removeoverlap/variable.cpp \
- removeoverlap/variable.h \
- removeoverlap/pairingheap/dsexceptions.h \
- removeoverlap/pairingheap/PairingHeap.cpp \
- removeoverlap/pairingheap/PairingHeap.h
-
-removeoverlap_remove_rectangle_overlap_test_SOURCES = \
- removeoverlap/remove_rectangle_overlap-test.cpp
-removeoverlap_remove_rectangle_overlap_test_LDADD = removeoverlap/libremoveoverlap.a -lglib-2.0
+ removeoverlap/removeoverlap.h
diff --git a/src/removeoverlap/block.cpp b/src/removeoverlap/block.cpp
deleted file mode 100644
index 042d9fc3c..000000000
--- a/src/removeoverlap/block.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/**
- * \brief A block is a group of variables that must be moved together to improve
- * the goal function without violating already active constraints.
- * The variables in a block are spanned by a tree of active constraints.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-#include <cassert>
-#include "pairingheap/PairingHeap.h"
-#include "constraint.h"
-#include "block.h"
-#include "blocks.h"
-#ifdef RECTANGLE_OVERLAP_LOGGING
-#include <fstream>
-using std::ios;
-using std::ofstream;
-using std::endl;
-#endif
-using std::vector;
-
-typedef vector<Constraint*>::iterator Cit;
-
-void Block::addVariable(Variable *v) {
- v->block=this;
- vars->push_back(v);
- weight+=v->weight;
- wposn += v->weight * (v->desiredPosition - v->offset);
- posn=wposn/weight;
-}
-Block::Block(Variable *v) {
- timeStamp=0;
- posn=weight=wposn=0;
- in=NULL;
- out=NULL;
- deleted=false;
- vars=new vector<Variable*>;
- if(v!=NULL) {
- v->offset=0;
- addVariable(v);
- }
-}
-
-double Block::desiredWeightedPosition() {
- double wp = 0;
- for (vector<Variable*>::iterator v=vars->begin();v!=vars->end();++v) {
- wp += ((*v)->desiredPosition - (*v)->offset) * (*v)->weight;
- }
- return wp;
-}
-Block::~Block(void)
-{
- delete vars;
- delete in;
- delete out;
-}
-void Block::setUpInConstraints() {
- setUpConstraintHeap(in,true);
-}
-void Block::setUpOutConstraints() {
- setUpConstraintHeap(out,false);
-}
-void Block::setUpConstraintHeap(PairingHeap<Constraint*>* &h,bool in) {
- delete h;
- h = new PairingHeap<Constraint*>(&compareConstraints);
- for (vector<Variable*>::iterator i=vars->begin();i!=vars->end();++i) {
- Variable *v=*i;
- vector<Constraint*> *cs=in?&(v->in):&(v->out);
- for (Cit j=cs->begin();j!=cs->end();++j) {
- Constraint *c=*j;
- c->timeStamp=blockTimeCtr;
- if (c->left->block != this && in || c->right->block != this && !in) {
- h->insert(c);
- }
- }
- }
-}
-void Block::merge(Block* b, Constraint* c) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" merging on: "<<*c<<",c->left->offset="<<c->left->offset<<",c->right->offset="<<c->right->offset<<endl;
-#endif
- double dist = c->right->offset - c->left->offset - c->gap;
- Block *l=c->left->block;
- Block *r=c->right->block;
- if (vars->size() < b->vars->size()) {
- r->merge(l,c,dist);
- } else {
- l->merge(r,c,-dist);
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" merged block="<<(b->deleted?*this:*b)<<endl;
-#endif
-}
-/**
- * Merges b into this block across c. Can be either a
- * right merge or a left merge
- * @param b block to merge into this
- * @param c constraint being merged
- * @param distance separation required to satisfy c
- */
-void Block::merge(Block *b, Constraint *c, double dist) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" merging: "<<*b<<"dist="<<dist<<endl;
-#endif
- c->active=true;
- wposn+=b->wposn-dist*b->weight;
- weight+=b->weight;
- posn=wposn/weight;
- for(vector<Variable*>::iterator i=b->vars->begin();i!=b->vars->end();++i) {
- Variable *v=*i;
- v->block=this;
- v->offset+=dist;
- vars->push_back(v);
- }
- b->deleted=true;
-}
-
-void Block::mergeIn(Block *b) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" merging constraint heaps... "<<endl;
-#endif
- // We check the top of the heaps to remove possible internal constraints
- findMinInConstraint();
- b->findMinInConstraint();
- in->merge(b->in);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" merged heap: "<<*in<<endl;
-#endif
-}
-void Block::mergeOut(Block *b) {
- findMinOutConstraint();
- b->findMinOutConstraint();
- out->merge(b->out);
-}
-Constraint *Block::findMinInConstraint() {
- Constraint *v = NULL;
- vector<Constraint*> outOfDate;
- while (!in->isEmpty()) {
- v = in->findMin();
- Block *lb=v->left->block;
- Block *rb=v->right->block;
- // rb may not be this if called between merge and mergeIn
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" checking constraint ... "<<*v;
- f<<" timestamps: left="<<lb->timeStamp<<" right="<<rb->timeStamp<<" constraint="<<v->timeStamp<<endl;
-#endif
- if(lb == rb) {
- // constraint has been merged into the same block
-#ifdef RECTANGLE_OVERLAP_LOGGING
- if(v->slack()<0) {
- f<<" violated internal constraint found! "<<*v<<endl;
- f<<" lb="<<*lb<<endl;
- f<<" rb="<<*rb<<endl;
- }
-#endif
- in->deleteMin();
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" ... skipping internal constraint"<<endl;
-#endif
- } else if(v->timeStamp < lb->timeStamp) {
- // block at other end of constraint has been moved since this
- in->deleteMin();
- outOfDate.push_back(v);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" reinserting out of date (reinsert later)"<<endl;
-#endif
- } else {
- break;
- }
- }
- for(Cit i=outOfDate.begin();i!=outOfDate.end();++i) {
- v=*i;
- v->timeStamp=blockTimeCtr;
- in->insert(v);
- }
- if(in->isEmpty()) {
- v=NULL;
- } else {
- v=in->findMin();
- }
- return v;
-}
-Constraint *Block::findMinOutConstraint() {
- if(out->isEmpty()) return NULL;
- Constraint *v = out->findMin();
- while (v->left->block == v->right->block) {
- out->deleteMin();
- if(out->isEmpty()) return NULL;
- v = out->findMin();
- }
- return v;
-}
-void Block::deleteMinInConstraint() {
- in->deleteMin();
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"deleteMinInConstraint... "<<endl;
- f<<" result: "<<*in<<endl;
-#endif
-}
-void Block::deleteMinOutConstraint() {
- out->deleteMin();
-}
-inline bool Block::canFollowLeft(Constraint *c, Variable *last) {
- return c->left->block==this && c->active && last!=c->left;
-}
-inline bool Block::canFollowRight(Constraint *c, Variable *last) {
- return c->right->block==this && c->active && last!=c->right;
-}
-
-// computes the derivative of v and the lagrange multipliers
-// of v's out constraints (as the recursive sum of those below.
-// Does not backtrack over u.
-// also records the constraint with minimum lagrange multiplier
-// in min_lm
-double Block::compute_dfdv(Variable *v, Variable *u, Constraint *&min_lm) {
- double dfdv=v->weight*(v->position() - v->desiredPosition);
- for(Cit it=v->out.begin();it!=v->out.end();++it) {
- Constraint *c=*it;
- if(canFollowRight(c,u)) {
- dfdv+=c->lm=compute_dfdv(c->right,v,min_lm);
- if(!c->equality&&(min_lm==NULL||c->lm<min_lm->lm)) min_lm=c;
- }
- }
- for(Cit it=v->in.begin();it!=v->in.end();++it) {
- Constraint *c=*it;
- if(canFollowLeft(c,u)) {
- dfdv-=c->lm=-compute_dfdv(c->left,v,min_lm);
- if(!c->equality&&(min_lm==NULL||c->lm<min_lm->lm)) min_lm=c;
- }
- }
- return dfdv;
-}
-
-
-// computes dfdv for each variable and uses the sum of dfdv on either side of
-// the constraint c to compute the lagrangian multiplier lm_c.
-// The top level v and r are variables between which we want to find the
-// constraint with the smallest lm.
-// When we find r we pass NULL to subsequent recursive calls,
-// thus r=NULL indicates constraints are not on the shortest path.
-// Similarly, m is initially NULL and is only assigned a value if the next
-// variable to be visited is r or if a possible min constraint is returned from
-// a nested call (rather than NULL).
-// Then, the search for the m with minimum lm occurs as we return from
-// the recursion (checking only constraints traversed left-to-right
-// in order to avoid creating any new violations).
-// We also do not consider equality constraints as potential split points
-Block::Pair Block::compute_dfdv_between(Variable* r, Variable* v, Variable* u,
- Direction dir = NONE, bool changedDirection = false) {
- double dfdv=v->weight*(v->position() - v->desiredPosition);
- Constraint *m=NULL;
- for(Cit it(v->in.begin());it!=v->in.end();++it) {
- Constraint *c=*it;
- if(canFollowLeft(c,u)) {
- if(dir==RIGHT) {
- changedDirection = true;
- }
- if(c->left==r) {
- r=NULL;
- if(!c->equality) m=c;
- }
- Pair p=compute_dfdv_between(r,c->left,v,
- LEFT,changedDirection);
- dfdv -= c->lm = -p.first;
- if(r && p.second)
- m = p.second;
- }
- }
- for(Cit it(v->out.begin());it!=v->out.end();++it) {
- Constraint *c=*it;
- if(canFollowRight(c,u)) {
- if(dir==LEFT) {
- changedDirection = true;
- }
- if(c->right==r) {
- r=NULL;
- if(!c->equality) m=c;
- }
- Pair p=compute_dfdv_between(r,c->right,v,
- RIGHT,changedDirection);
- dfdv += c->lm = p.first;
- if(r && p.second)
- m = changedDirection && !c->equality && c->lm < p.second->lm
- ? c
- : p.second;
- }
- }
- return Pair(dfdv,m);
-}
-
-// resets LMs for all active constraints to 0 by
-// traversing active constraint tree starting from v,
-// not back tracking over u
-void Block::reset_active_lm(Variable *v, Variable *u) {
- for(Cit it=v->out.begin();it!=v->out.end();++it) {
- Constraint *c=*it;
- if(canFollowRight(c,u)) {
- c->lm=0;
- reset_active_lm(c->right,v);
- }
- }
- for(Cit it=v->in.begin();it!=v->in.end();++it) {
- Constraint *c=*it;
- if(canFollowLeft(c,u)) {
- c->lm=0;
- reset_active_lm(c->left,v);
- }
- }
-}
-/**
- * finds the constraint with the minimum lagrange multiplier, that is, the constraint
- * that most wants to split
- */
-Constraint *Block::findMinLM() {
- Constraint *min_lm=NULL;
- reset_active_lm(vars->front(),NULL);
- compute_dfdv(vars->front(),NULL,min_lm);
- return min_lm;
-}
-Constraint *Block::findMinLMBetween(Variable* lv, Variable* rv) {
- Constraint *min_lm=NULL;
- reset_active_lm(vars->front(),NULL);
- min_lm=compute_dfdv_between(rv,lv,NULL).second;
- return min_lm;
-}
-
-// populates block b by traversing the active constraint tree adding variables as they're
-// visited. Starts from variable v and does not backtrack over variable u.
-void Block::populateSplitBlock(Block *b, Variable *v, Variable *u) {
- b->addVariable(v);
- for (Cit c=v->in.begin();c!=v->in.end();++c) {
- if (canFollowLeft(*c,u))
- populateSplitBlock(b, (*c)->left, v);
- }
- for (Cit c=v->out.begin();c!=v->out.end();++c) {
- if (canFollowRight(*c,u))
- populateSplitBlock(b, (*c)->right, v);
- }
-}
-/**
- * Block needs to be split because of a violated constraint between vl and vr.
- * We need to search the active constraint tree between l and r and find the constraint
- * with min lagrangrian multiplier and split at that point.
- * Returns the split constraint
- */
-Constraint* Block::splitBetween(Variable* vl, Variable* vr, Block* &lb, Block* &rb) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" need to split between: "<<*vl<<" and "<<*vr<<endl;
-#endif
- Constraint *c=findMinLMBetween(vl, vr);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" going to split on: "<<*c<<endl;
-#endif
- split(lb,rb,c);
- deleted = true;
- return c;
-}
-/**
- * Creates two new blocks, l and r, and splits this block across constraint c,
- * placing the left subtree of constraints (and associated variables) into l
- * and the right into r.
- */
-void Block::split(Block* &l, Block* &r, Constraint* c) {
- c->active=false;
- l=new Block();
- populateSplitBlock(l,c->left,c->right);
- r=new Block();
- populateSplitBlock(r,c->right,c->left);
-}
-
-/**
- * Computes the cost (squared euclidean distance from desired positions) of the
- * current positions for variables in this block
- */
-double Block::cost() {
- double c = 0;
- for (vector<Variable*>::iterator v=vars->begin();v!=vars->end();++v) {
- double diff = (*v)->position() - (*v)->desiredPosition;
- c += (*v)->weight * diff * diff;
- }
- return c;
-}
-ostream& operator <<(ostream &os, const Block &b)
-{
- os<<"Block:";
- for(vector<Variable*>::iterator v=b.vars->begin();v!=b.vars->end();++v) {
- os<<" "<<**v;
- }
- if(b.deleted) {
- os<<" Deleted!";
- }
- return os;
-}
diff --git a/src/removeoverlap/block.h b/src/removeoverlap/block.h
deleted file mode 100644
index 997009a55..000000000
--- a/src/removeoverlap/block.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * \brief A block is a group of variables that must be moved together to improve
- * the goal function without violating already active constraints.
- * The variables in a block are spanned by a tree of active constraints.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-#ifndef SEEN_REMOVEOVERLAP_BLOCK_H
-#define SEEN_REMOVEOVERLAP_BLOCK_H
-
-#include <vector>
-#include <iostream>
-class Variable;
-class Constraint;
-template <class T> class PairingHeap;
-class StupidPriorityQueue;
-
-class Block
-{
- friend std::ostream& operator <<(std::ostream &os,const Block &b);
-public:
- std::vector<Variable*> *vars;
- double posn;
- double weight;
- double wposn;
- Block(Variable *v=NULL);
- ~Block(void);
- Constraint* findMinLM();
- Constraint* findMinLMBetween(Variable* lv, Variable* rv);
- Constraint* findMinInConstraint();
- Constraint* findMinOutConstraint();
- void deleteMinInConstraint();
- void deleteMinOutConstraint();
- double desiredWeightedPosition();
- void merge(Block *b, Constraint *c, double dist);
- void merge(Block *b, Constraint *c);
- void mergeIn(Block *b);
- void mergeOut(Block *b);
- void split(Block *&l, Block *&r, Constraint *c);
- Constraint* splitBetween(Variable* vl, Variable* vr, Block* &lb, Block* &rb);
- void setUpInConstraints();
- void setUpOutConstraints();
- double cost();
- bool deleted;
- long timeStamp;
- PairingHeap<Constraint*> *in;
- PairingHeap<Constraint*> *out;
-private:
- typedef enum {NONE, LEFT, RIGHT} Direction;
- typedef std::pair<double, Constraint*> Pair;
- void reset_active_lm(Variable *v, Variable *u);
- double compute_dfdv(Variable *v, Variable *u, Constraint *&min_lm);
- Pair compute_dfdv_between(
- Variable*, Variable*, Variable*, Direction, bool);
- bool canFollowLeft(Constraint *c, Variable *last);
- bool canFollowRight(Constraint *c, Variable *last);
- void populateSplitBlock(Block *b, Variable *v, Variable *u);
- void addVariable(Variable *v);
- void setUpConstraintHeap(PairingHeap<Constraint*>* &h,bool in);
-};
-
-#endif // SEEN_REMOVEOVERLAP_BLOCK_H
diff --git a/src/removeoverlap/blocks.cpp b/src/removeoverlap/blocks.cpp
deleted file mode 100644
index 62b7e99f5..000000000
--- a/src/removeoverlap/blocks.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * \brief A block structure defined over the variables
- *
- * A block structure defined over the variables such that each block contains
- * 1 or more variables, with the invariant that all constraints inside a block
- * are satisfied by keeping the variables fixed relative to one another
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-#include "blocks.h"
-#include "block.h"
-#include "constraint.h"
-#ifdef RECTANGLE_OVERLAP_LOGGING
-#include <fstream>
-using std::ios;
-using std::ofstream;
-using std::endl;
-#endif
-using std::set;
-using std::vector;
-using std::iterator;
-using std::list;
-using std::copy;
-
-long blockTimeCtr;
-
-Blocks::Blocks(const int n, Variable *vs[]) : vs(vs),nvs(n) {
- blockTimeCtr=0;
- for(int i=0;i<nvs;i++) {
- insert(new Block(vs[i]));
- }
-}
-Blocks::~Blocks(void)
-{
- blockTimeCtr=0;
- for(set<Block*>::iterator i=begin();i!=end();++i) {
- delete *i;
- }
- clear();
-}
-
-/**
- * returns a list of variables with total ordering determined by the constraint
- * DAG
- */
-list<Variable*> *Blocks::totalOrder() {
- list<Variable*> *order = new list<Variable*>;
- for(int i=0;i<nvs;i++) {
- vs[i]->visited=false;
- }
- for(int i=0;i<nvs;i++) {
- if(vs[i]->in.size()==0) {
- dfsVisit(vs[i],order);
- }
- }
- return order;
-}
-// Recursive depth first search giving total order by pushing nodes in the DAG
-// onto the front of the list when we finish searching them
-void Blocks::dfsVisit(Variable *v, list<Variable*> *order) {
- v->visited=true;
- vector<Constraint*>::iterator it=v->out.begin();
- for(;it!=v->out.end();++it) {
- Constraint *c=*it;
- if(!c->right->visited) {
- dfsVisit(c->right, order);
- }
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" order="<<*v<<endl;
-#endif
- order->push_front(v);
-}
-/**
- * Processes incoming constraints, most violated to least, merging with the
- * neighbouring (left) block until no more violated constraints are found
- */
-void Blocks::mergeLeft(Block *r) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"mergeLeft called on "<<*r<<endl;
-#endif
- r->timeStamp=++blockTimeCtr;
- r->setUpInConstraints();
- Constraint *c=r->findMinInConstraint();
- while (c != NULL && c->slack()<0) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<"mergeLeft on constraint: "<<*c<<endl;
-#endif
- r->deleteMinInConstraint();
- Block *l = c->left->block;
- if (l->in==NULL) l->setUpInConstraints();
- double dist = c->right->offset - c->left->offset - c->gap;
- if (r->vars->size() < l->vars->size()) {
- dist=-dist;
- std::swap(l, r);
- }
- blockTimeCtr++;
- r->merge(l, c, dist);
- r->mergeIn(l);
- r->timeStamp=blockTimeCtr;
- removeBlock(l);
- c=r->findMinInConstraint();
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<"merged "<<*r<<endl;
-#endif
-}
-/**
- * Symmetrical to mergeLeft
- */
-void Blocks::mergeRight(Block *l) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"mergeRight called on "<<*l<<endl;
-#endif
- l->setUpOutConstraints();
- Constraint *c = l->findMinOutConstraint();
- while (c != NULL && c->slack()<0) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<"mergeRight on constraint: "<<*c<<endl;
-#endif
- l->deleteMinOutConstraint();
- Block *r = c->right->block;
- r->setUpOutConstraints();
- double dist = c->left->offset + c->gap - c->right->offset;
- if (l->vars->size() > r->vars->size()) {
- dist=-dist;
- std::swap(l, r);
- }
- l->merge(r, c, dist);
- l->mergeOut(r);
- removeBlock(r);
- c=l->findMinOutConstraint();
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<"merged "<<*l<<endl;
-#endif
-}
-void Blocks::removeBlock(Block *doomed) {
- doomed->deleted=true;
- //erase(doomed);
-}
-void Blocks::cleanup() {
- vector<Block*> bcopy(begin(),end());
- for(vector<Block*>::iterator i=bcopy.begin();i!=bcopy.end();++i) {
- Block *b=*i;
- if(b->deleted) {
- erase(b);
- delete b;
- }
- }
-}
-/**
- * Splits block b across constraint c into two new blocks, l and r (c's left
- * and right sides respectively)
- */
-void Blocks::split(Block *b, Block *&l, Block *&r, Constraint *c) {
- b->split(l,r,c);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Split left: "<<*l<<endl;
- f<<"Split right: "<<*r<<endl;
-#endif
- r->posn = b->posn;
- r->wposn = r->posn * r->weight;
- mergeLeft(l);
- // r may have been merged!
- r = c->right->block;
- r->wposn = r->desiredWeightedPosition();
- r->posn = r->wposn / r->weight;
- mergeRight(r);
- removeBlock(b);
-
- insert(l);
- insert(r);
-}
-/**
- * returns the cost total squared distance of variables from their desired
- * positions
- */
-double Blocks::cost() {
- double c = 0;
- for(set<Block*>::iterator i=begin();i!=end();++i) {
- c += (*i)->cost();
- }
- return c;
-}
-
diff --git a/src/removeoverlap/blocks.h b/src/removeoverlap/blocks.h
deleted file mode 100644
index 1a603eb41..000000000
--- a/src/removeoverlap/blocks.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * \brief A block structure defined over the variables
- *
- * A block structure defined over the variables such that each block contains
- * 1 or more variables, with the invariant that all constraints inside a block
- * are satisfied by keeping the variables fixed relative to one another
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-#ifndef SEEN_REMOVEOVERLAP_BLOCKS_H
-#define SEEN_REMOVEOVERLAP_BLOCKS_H
-
-#ifdef RECTANGLE_OVERLAP_LOGGING
-#define LOGFILE "cRectangleOverlap.log"
-#endif
-
-#include <set>
-#include <list>
-
-class Block;
-class Variable;
-class Constraint;
-/**
- * A block structure defined over the variables such that each block contains
- * 1 or more variables, with the invariant that all constraints inside a block
- * are satisfied by keeping the variables fixed relative to one another
- */
-class Blocks : public std::set<Block*>
-{
-public:
- Blocks(const int n, Variable *vs[]);
- ~Blocks(void);
- void mergeLeft(Block *r);
- void mergeRight(Block *l);
- void split(Block *b, Block *&l, Block *&r, Constraint *c);
- std::list<Variable*> *totalOrder();
- void cleanup();
- double cost();
-private:
- void dfsVisit(Variable *v, std::list<Variable*> *order);
- void removeBlock(Block *doomed);
- Variable **vs;
- int nvs;
-};
-
-extern long blockTimeCtr;
-#endif // SEEN_REMOVEOVERLAP_BLOCKS_H
diff --git a/src/removeoverlap/constraint.cpp b/src/removeoverlap/constraint.cpp
deleted file mode 100644
index 7c200878b..000000000
--- a/src/removeoverlap/constraint.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * \brief A constraint determines a minimum or exact spacing required between
- * two variables.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-#include "constraint.h"
-#include <cassert>
-Constraint::Constraint(Variable *left, Variable *right, double gap, bool equality)
-: left(left),
- right(right),
- gap(gap),
- timeStamp(0),
- active(false),
- visited(false),
- equality(equality)
-{
- left->out.push_back(this);
- right->in.push_back(this);
-}
-Constraint::~Constraint() {
- Constraints::iterator i;
- for(i=left->out.begin(); i!=left->out.end(); i++) {
- if(*i==this) break;
- }
- left->out.erase(i);
- for(i=right->in.begin(); i!=right->in.end(); i++) {
- if(*i==this) break;
- }
- right->in.erase(i);
-}
-std::ostream& operator <<(std::ostream &os, const Constraint &c)
-{
- if(&c==NULL) {
- os<<"NULL";
- } else {
- const char *type=c.equality?"=":"<=";
- os<<*c.left<<"+"<<c.gap<<type<<*c.right<<"("<<c.slack()<<")"<<(c.active?"-active":"");
- }
- return os;
-}
diff --git a/src/removeoverlap/constraint.h b/src/removeoverlap/constraint.h
deleted file mode 100644
index 3da7449cd..000000000
--- a/src/removeoverlap/constraint.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * \brief A constraint determines a minimum or exact spacing required between
- * two variables.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-#ifndef SEEN_REMOVEOVERLAP_CONSTRAINT_H
-#define SEEN_REMOVEOVERLAP_CONSTRAINT_H
-
-#include <iostream>
-#include "variable.h"
-
-class Constraint
-{
- friend std::ostream& operator <<(std::ostream &os,const Constraint &c);
-public:
- Variable *left;
- Variable *right;
- double gap;
- double lm;
- Constraint(Variable *left, Variable *right, double gap, bool equality=false);
- ~Constraint();
- inline double slack() const { return right->position() - gap - left->position(); }
- long timeStamp;
- bool active;
- bool visited;
- bool equality;
-};
-#include <float.h>
-#include "block.h"
-static inline bool compareConstraints(Constraint *const &l, Constraint *const &r) {
- double const sl =
- l->left->block->timeStamp > l->timeStamp
- ||l->left->block==l->right->block
- ?-DBL_MAX:l->slack();
- double const sr =
- r->left->block->timeStamp > r->timeStamp
- ||r->left->block==r->right->block
- ?-DBL_MAX:r->slack();
- if(sl==sr) {
- // arbitrary choice based on id
- if(l->left->id==r->left->id) {
- if(l->right->id<r->right->id) return true;
- return false;
- }
- if(l->left->id<r->left->id) return true;
- return false;
- }
- return sl < sr;
-}
-
-#endif // SEEN_REMOVEOVERLAP_CONSTRAINT_H
diff --git a/src/removeoverlap/generate-constraints.cpp b/src/removeoverlap/generate-constraints.cpp
deleted file mode 100644
index 312ad960b..000000000
--- a/src/removeoverlap/generate-constraints.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/**
- * \brief Functions to automatically generate constraints for the
- * rectangular node overlap removal problem.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-#include <set>
-#include <cassert>
-#include "generate-constraints.h"
-#include "constraint.h"
-
-#include "isnan.h" /* Include last */
-
-using std::set;
-using std::vector;
-
-std::ostream& operator <<(std::ostream &os, const Rectangle &r) {
- os << "{"<<r.minX<<","<<r.maxX<<","<<r.minY<<","<<r.maxY<<"},";
- return os;
-}
-Rectangle::Rectangle(double x, double X, double y, double Y)
-: minX(x),maxX(X),minY(y),maxY(Y) {
- assert(x<=X);
- assert(y<=Y);
-}
-
-struct Node;
-struct CmpNodePos { bool operator()(const Node* u, const Node* v) const; };
-
-typedef set<Node*,CmpNodePos> NodeSet;
-
-struct Node {
- Variable *v;
- Rectangle *r;
- double pos;
- Node *firstAbove, *firstBelow;
- NodeSet *leftNeighbours, *rightNeighbours;
- Node(Variable *v, Rectangle *r, double p) : v(v),r(r),pos(p) {
- firstAbove=firstBelow=NULL;
- leftNeighbours=rightNeighbours=NULL;
- assert(r->width()<1e40);
- }
- ~Node() {
- delete leftNeighbours;
- delete rightNeighbours;
- }
- void addLeftNeighbour(Node *u) {
- leftNeighbours->insert(u);
- }
- void addRightNeighbour(Node *u) {
- rightNeighbours->insert(u);
- }
- void setNeighbours(NodeSet *left, NodeSet *right) {
- leftNeighbours=left;
- rightNeighbours=right;
- for(NodeSet::iterator i=left->begin();i!=left->end();++i) {
- Node *v=*(i);
- v->addRightNeighbour(this);
- }
- for(NodeSet::iterator i=right->begin();i!=right->end();++i) {
- Node *v=*(i);
- v->addLeftNeighbour(this);
- }
- }
-};
-bool CmpNodePos::operator() (const Node* u, const Node* v) const {
- if (u->pos < v->pos) {
- return true;
- }
- if (v->pos < u->pos) {
- return false;
- }
- if (isNaN(u->pos) != isNaN(v->pos)) {
- return isNaN(u->pos);
- }
- return u < v;
-
- /* I don't know how important it is to handle NaN correctly
- * (e.g. we probably handle it badly in other code anyway, and
- * in any case the best we can hope for is to reduce the
- * badness of other nodes).
- *
- * Nevertheless, we try to do the right thing here and in
- * event comparison. The issue is that (on platforms with
- * ieee floating point comparison) NaN compares neither less
- * than nor greater than any other number, yet sort wants a
- * well-defined ordering. In particular, we want to ensure
- * transitivity of equivalence, which normally wouldn't be
- * guaranteed if the "middle" item in the transitivity
- * involves a NaN. (NaN is neither less than nor greater than
- * other numbers, so tends to be considered as equal to all
- * other numbers: even unequal numbers.)
- */
-}
-
-NodeSet* getLeftNeighbours(NodeSet &scanline,Node *v) {
- NodeSet *leftv = new NodeSet;
- NodeSet::iterator i=scanline.find(v);
- while(i--!=scanline.begin()) {
- Node *u=*(i);
- if(u->r->overlapX(v->r)<=0) {
- leftv->insert(u);
- return leftv;
- }
- if(u->r->overlapX(v->r)<=u->r->overlapY(v->r)) {
- leftv->insert(u);
- }
- }
- return leftv;
-}
-NodeSet* getRightNeighbours(NodeSet &scanline,Node *v) {
- NodeSet *rightv = new NodeSet;
- NodeSet::iterator i=scanline.find(v);
- for(++i;i!=scanline.end(); ++i) {
- Node *u=*(i);
- if(u->r->overlapX(v->r)<=0) {
- rightv->insert(u);
- return rightv;
- }
- if(u->r->overlapX(v->r)<=u->r->overlapY(v->r)) {
- rightv->insert(u);
- }
- }
- return rightv;
-}
-
-typedef enum {Open, Close} EventType;
-struct Event {
- EventType type;
- Node *v;
- double pos;
- Event(EventType t, Node *v, double p) : type(t),v(v),pos(p) {};
-};
-Event **events;
-int compare_events(const void *a, const void *b) {
- Event *ea=*(Event**)a;
- Event *eb=*(Event**)b;
- if(ea->v->r==eb->v->r) {
- // when comparing opening and closing from the same rect
- // open must come first
- if(ea->type==Open) return -1;
- return 1;
- } else if(ea->pos > eb->pos) {
- return 1;
- } else if(ea->pos < eb->pos) {
- return -1;
- } else if(isNaN(ea->pos) != isNaN(ea->pos)) {
- /* See comment in CmpNodePos. */
- return ( isNaN(ea->pos)
- ? -1
- : 1 );
- }
- return 0;
-}
-
-/**
- * Prepares constraints in order to apply VPSC horizontally. Assumes variables have already been created.
- * useNeighbourLists determines whether or not a heuristic is used to deciding whether to resolve
- * all overlap in the x pass, or leave some overlaps for the y pass.
- */
-int generateXConstraints(const int n, Rectangle** rs, Variable** vars, Constraint** &cs, const bool useNeighbourLists) {
- events=new Event*[2*n];
- int i,m,ctr=0;
- for(i=0;i<n;i++) {
- vars[i]->desiredPosition=rs[i]->getCentreX();
- Node *v = new Node(vars[i],rs[i],rs[i]->getCentreX());
- events[ctr++]=new Event(Open,v,rs[i]->getMinY());
- events[ctr++]=new Event(Close,v,rs[i]->getMaxY());
- }
- qsort((Event*)events, (size_t)2*n, sizeof(Event*), compare_events );
-
- NodeSet scanline;
- vector<Constraint*> constraints;
- for(i=0;i<2*n;i++) {
- Event *e=events[i];
- Node *v=e->v;
- if(e->type==Open) {
- scanline.insert(v);
- if(useNeighbourLists) {
- v->setNeighbours(
- getLeftNeighbours(scanline,v),
- getRightNeighbours(scanline,v)
- );
- } else {
- NodeSet::iterator it=scanline.find(v);
- if(it--!=scanline.begin()) {
- Node *u=*it;
- v->firstAbove=u;
- u->firstBelow=v;
- }
- it=scanline.find(v);
- if(++it!=scanline.end()) {
- Node *u=*it;
- v->firstBelow=u;
- u->firstAbove=v;
- }
- }
- } else {
- // Close event
- int r;
- if(useNeighbourLists) {
- for(NodeSet::iterator i=v->leftNeighbours->begin();
- i!=v->leftNeighbours->end();i++
- ) {
- Node *u=*i;
- double sep = (v->r->width()+u->r->width())/2.0;
- constraints.push_back(new Constraint(u->v,v->v,sep));
- r=u->rightNeighbours->erase(v);
- }
-
- for(NodeSet::iterator i=v->rightNeighbours->begin();
- i!=v->rightNeighbours->end();i++
- ) {
- Node *u=*i;
- double sep = (v->r->width()+u->r->width())/2.0;
- constraints.push_back(new Constraint(v->v,u->v,sep));
- r=u->leftNeighbours->erase(v);
- }
- } else {
- Node *l=v->firstAbove, *r=v->firstBelow;
- if(l!=NULL) {
- double sep = (v->r->width()+l->r->width())/2.0;
- constraints.push_back(new Constraint(l->v,v->v,sep));
- l->firstBelow=v->firstBelow;
- }
- if(r!=NULL) {
- double sep = (v->r->width()+r->r->width())/2.0;
- constraints.push_back(new Constraint(v->v,r->v,sep));
- r->firstAbove=v->firstAbove;
- }
- }
- r=scanline.erase(v);
- delete v;
- }
- delete e;
- }
- delete [] events;
- cs=new Constraint*[m=constraints.size()];
- for(i=0;i<m;i++) cs[i]=constraints[i];
- return m;
-}
-
-/**
- * Prepares constraints in order to apply VPSC vertically to remove ALL overlap.
- */
-int generateYConstraints(const int n, Rectangle** rs, Variable** vars, Constraint** &cs) {
- events=new Event*[2*n];
- int ctr=0,i,m;
- for(i=0;i<n;i++) {
- vars[i]->desiredPosition=rs[i]->getCentreY();
- Node *v = new Node(vars[i],rs[i],rs[i]->getCentreY());
- events[ctr++]=new Event(Open,v,rs[i]->getMinX());
- events[ctr++]=new Event(Close,v,rs[i]->getMaxX());
- }
- qsort((Event*)events, (size_t)2*n, sizeof(Event*), compare_events );
- NodeSet scanline;
- vector<Constraint*> constraints;
- for(i=0;i<2*n;i++) {
- Event *e=events[i];
- Node *v=e->v;
- if(e->type==Open) {
- scanline.insert(v);
- NodeSet::iterator i=scanline.find(v);
- if(i--!=scanline.begin()) {
- Node *u=*i;
- v->firstAbove=u;
- u->firstBelow=v;
- }
- i=scanline.find(v);
- if(++i!=scanline.end()) {
- Node *u=*i;
- v->firstBelow=u;
- u->firstAbove=v;
- }
- } else {
- // Close event
- Node *l=v->firstAbove, *r=v->firstBelow;
- if(l!=NULL) {
- double sep = (v->r->height()+l->r->height())/2.0;
- constraints.push_back(new Constraint(l->v,v->v,sep));
- l->firstBelow=v->firstBelow;
- }
- if(r!=NULL) {
- double sep = (v->r->height()+r->r->height())/2.0;
- constraints.push_back(new Constraint(v->v,r->v,sep));
- r->firstAbove=v->firstAbove;
- }
- scanline.erase(v);
- delete v;
- }
- delete e;
- }
- delete [] events;
- cs=new Constraint*[m=constraints.size()];
- for(i=0;i<m;i++) cs[i]=constraints[i];
- return m;
-}
diff --git a/src/removeoverlap/generate-constraints.h b/src/removeoverlap/generate-constraints.h
deleted file mode 100644
index 56ee9536a..000000000
--- a/src/removeoverlap/generate-constraints.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * \brief Functions to automatically generate constraints for the
- * rectangular node overlap removal problem.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-#ifndef SEEN_REMOVEOVERLAP_GENERATE_CONSTRAINTS_H
-#define SEEN_REMOVEOVERLAP_GENERATE_CONSTRAINTS_H
-#include <iostream>
-
-class Rectangle {
- friend std::ostream& operator <<(std::ostream &os, const Rectangle &r);
-public:
- static double xBorder,yBorder;
- Rectangle(double x, double X, double y, double Y);
- double getMaxX() const { return maxX+xBorder; }
- double getMaxY() const { return maxY+yBorder; }
- double getMinX() const { return minX; }
- double getMinY() const { return minY; }
- double getMinD(unsigned const d) const {
- return ( d == 0 ? getMinX() : getMinY() );
- }
- double getMaxD(unsigned const d) const {
- return ( d == 0 ? getMaxX() : getMaxY() );
- }
- double getCentreX() const { return minX+width()/2.0; }
- double getCentreY() const { return minY+height()/2.0; }
- double width() const { return getMaxX()-minX; }
- double height() const { return getMaxY()-minY; }
- static void setXBorder(double x) {xBorder=x;}
- static void setYBorder(double y) {yBorder=y;}
- void moveCentreX(double x) {
- moveMinX(x-width()/2.0);
- }
- void moveCentreY(double y) {
- moveMinY(y-height()/2.0);
- }
- void moveMinX(double x) {
- maxX=x+width()-xBorder;
- minX=x;
- }
- void moveMinY(double y) {
- maxY=y+height()-yBorder;
- minY=y;
- }
- inline double overlapX(Rectangle *r) const {
- if (getCentreX() <= r->getCentreX() && r->minX < getMaxX())
- return getMaxX() - r->minX;
- if (r->getCentreX() <= getCentreX() && minX < r->getMaxX())
- return r->getMaxX() - minX;
- return 0;
- }
- inline double overlapY(Rectangle *r) const {
- if (getCentreY() <= r->getCentreY() && r->minY < getMaxY())
- return getMaxY() - r->minY;
- if (r->getCentreY() <= getCentreY() && minY < r->getMaxY())
- return r->getMaxY() - minY;
- return 0;
- }
-private:
- double minX,maxX,minY,maxY;
-};
-
-
-class Variable;
-class Constraint;
-
-// returns number of constraints generated
-int generateXConstraints(const int n, Rectangle** rs, Variable** vars, Constraint** &cs, const bool useNeighbourLists);
-int generateYConstraints(const int n, Rectangle** rs, Variable** vars, Constraint** &cs);
-
-
-#endif // SEEN_REMOVEOVERLAP_GENERATE_CONSTRAINTS_H
diff --git a/src/removeoverlap/pairingheap/.cvsignore b/src/removeoverlap/pairingheap/.cvsignore
deleted file mode 100644
index e8014d011..000000000
--- a/src/removeoverlap/pairingheap/.cvsignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Makefile
-Makefile.in
-.deps
-makefile
-.dirstamp
diff --git a/src/removeoverlap/pairingheap/PairingHeap.cpp b/src/removeoverlap/pairingheap/PairingHeap.cpp
deleted file mode 100644
index 42d009c6a..000000000
--- a/src/removeoverlap/pairingheap/PairingHeap.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/**
- * \brief Pairing heap datastructure implementation
- *
- * Based on example code in "Data structures and Algorithm Analysis in C++"
- * by Mark Allen Weiss, used and released under the GPL by permission
- * of the author.
- *
- * No promises about correctness. Use at your own risk!
- *
- * Authors:
- * Mark Allen Weiss
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU GPL. Read the file 'COPYING' for more information.
- */
-
-#include <vector>
-#include <list>
-#include "dsexceptions.h"
-#include "PairingHeap.h"
-
-#ifndef PAIRING_HEAP_CPP
-#define PAIRING_HEAP_CPP
-using namespace std;
-/**
-* Construct the pairing heap.
-*/
-template <class T>
-PairingHeap<T>::PairingHeap( bool (*lessThan)(T const &lhs, T const &rhs) )
-{
- root = NULL;
- counter=0;
- this->lessThan=lessThan;
-}
-
-
-/**
-* Copy constructor
-*/
-template <class T>
-PairingHeap<T>::PairingHeap( const PairingHeap<T> & rhs )
-{
- root = NULL;
- counter=rhs->size();
- *this = rhs;
-}
-
-/**
-* Destroy the leftist heap.
-*/
-template <class T>
-PairingHeap<T>::~PairingHeap( )
-{
- makeEmpty( );
-}
-
-/**
-* Insert item x into the priority queue, maintaining heap order.
-* Return a pointer to the node containing the new item.
-*/
-template <class T>
-PairNode<T> *
-PairingHeap<T>::insert( const T & x )
-{
- PairNode<T> *newNode = new PairNode<T>( x );
-
- if( root == NULL )
- root = newNode;
- else
- compareAndLink( root, newNode );
- counter++;
- return newNode;
-}
-template <class T>
-int PairingHeap<T>::size() {
- return counter;
-}
-/**
-* Find the smallest item in the priority queue.
-* Return the smallest item, or throw Underflow if empty.
-*/
-template <class T>
-const T & PairingHeap<T>::findMin( ) const
-{
- if( isEmpty( ) )
- throw Underflow( );
- return root->element;
-}
-/**
- * Remove the smallest item from the priority queue.
- * Throws Underflow if empty.
- */
-template <class T>
-void PairingHeap<T>::deleteMin( )
-{
- if( isEmpty( ) )
- throw Underflow( );
-
- PairNode<T> *oldRoot = root;
-
- if( root->leftChild == NULL )
- root = NULL;
- else
- root = combineSiblings( root->leftChild );
- counter--;
- delete oldRoot;
-}
-
-/**
-* Test if the priority queue is logically empty.
-* Returns true if empty, false otherwise.
-*/
-template <class T>
-bool PairingHeap<T>::isEmpty( ) const
-{
- return root == NULL;
-}
-
-/**
-* Test if the priority queue is logically full.
-* Returns false in this implementation.
-*/
-template <class T>
-bool PairingHeap<T>::isFull( ) const
-{
- return false;
-}
-
-/**
-* Make the priority queue logically empty.
-*/
-template <class T>
-void PairingHeap<T>::makeEmpty( )
-{
- reclaimMemory( root );
- root = NULL;
-}
-
-/**
-* Deep copy.
-*/
-template <class T>
-const PairingHeap<T> &
-PairingHeap<T>::operator=( const PairingHeap<T> & rhs )
-{
- if( this != &rhs )
- {
- makeEmpty( );
- root = clone( rhs.root );
- }
-
- return *this;
-}
-
-/**
-* Internal method to make the tree empty.
-* WARNING: This is prone to running out of stack space.
-*/
-template <class T>
-void PairingHeap<T>::reclaimMemory( PairNode<T> * t ) const
-{
- if( t != NULL )
- {
- reclaimMemory( t->leftChild );
- reclaimMemory( t->nextSibling );
- delete t;
- }
-}
-
-/**
-* Change the value of the item stored in the pairing heap.
-* Does nothing if newVal is larger than currently stored value.
-* p points to a node returned by insert.
-* newVal is the new value, which must be smaller
-* than the currently stored value.
-*/
-template <class T>
-void PairingHeap<T>::decreaseKey( PairNode<T> *p,
- const T & newVal )
-{
- if( p->element < newVal )
- return; // newVal cannot be bigger
- p->element = newVal;
- if( p != root )
- {
- if( p->nextSibling != NULL )
- p->nextSibling->prev = p->prev;
- if( p->prev->leftChild == p )
- p->prev->leftChild = p->nextSibling;
- else
- p->prev->nextSibling = p->nextSibling;
-
- p->nextSibling = NULL;
- compareAndLink( root, p );
- }
-}
-
-/**
-* Internal method that is the basic operation to maintain order.
-* Links first and second together to satisfy heap order.
-* first is root of tree 1, which may not be NULL.
-* first->nextSibling MUST be NULL on entry.
-* second is root of tree 2, which may be NULL.
-* first becomes the result of the tree merge.
-*/
-template <class T>
-void PairingHeap<T>::
-compareAndLink( PairNode<T> * & first,
- PairNode<T> *second ) const
-{
- if( second == NULL )
- return;
- if( lessThan(second->element,first->element) )
- {
- // Attach first as leftmost child of second
- second->prev = first->prev;
- first->prev = second;
- first->nextSibling = second->leftChild;
- if( first->nextSibling != NULL )
- first->nextSibling->prev = first;
- second->leftChild = first;
- first = second;
- }
- else
- {
- // Attach second as leftmost child of first
- second->prev = first;
- first->nextSibling = second->nextSibling;
- if( first->nextSibling != NULL )
- first->nextSibling->prev = first;
- second->nextSibling = first->leftChild;
- if( second->nextSibling != NULL )
- second->nextSibling->prev = second;
- first->leftChild = second;
- }
-}
-
-/**
-* Internal method that implements two-pass merging.
-* firstSibling the root of the conglomerate;
-* assumed not NULL.
-*/
-template <class T>
-PairNode<T> *
-PairingHeap<T>::combineSiblings( PairNode<T> *firstSibling ) const
-{
- if( firstSibling->nextSibling == NULL )
- return firstSibling;
-
- // Allocate the array
- static vector<PairNode<T> *> treeArray( 5 );
-
- // Store the subtrees in an array
- int numSiblings = 0;
- for( ; firstSibling != NULL; numSiblings++ )
- {
- if( numSiblings == (int)treeArray.size( ) )
- treeArray.resize( numSiblings * 2 );
- treeArray[ numSiblings ] = firstSibling;
- firstSibling->prev->nextSibling = NULL; // break links
- firstSibling = firstSibling->nextSibling;
- }
- if( numSiblings == (int)treeArray.size( ) )
- treeArray.resize( numSiblings + 1 );
- treeArray[ numSiblings ] = NULL;
-
- // Combine subtrees two at a time, going left to right
- int i = 0;
- for( ; i + 1 < numSiblings; i += 2 )
- compareAndLink( treeArray[ i ], treeArray[ i + 1 ] );
-
- int j = i - 2;
-
- // j has the result of last compareAndLink.
- // If an odd number of trees, get the last one.
- if( j == numSiblings - 3 )
- compareAndLink( treeArray[ j ], treeArray[ j + 2 ] );
-
- // Now go right to left, merging last tree with
- // next to last. The result becomes the new last.
- for( ; j >= 2; j -= 2 )
- compareAndLink( treeArray[ j - 2 ], treeArray[ j ] );
- return treeArray[ 0 ];
-}
-
-/**
-* Internal method to clone subtree.
-* WARNING: This is prone to running out of stack space.
-*/
-template <class T>
-PairNode<T> *
-PairingHeap<T>::clone( PairNode<T> * t ) const
-{
- if( t == NULL )
- return NULL;
- else
- {
- PairNode<T> *p = new PairNode<T>( t->element );
- if( ( p->leftChild = clone( t->leftChild ) ) != NULL )
- p->leftChild->prev = p;
- if( ( p->nextSibling = clone( t->nextSibling ) ) != NULL )
- p->nextSibling->prev = p;
- return p;
- }
-}
-template <class T>
-ostream& operator <<(ostream &os, const PairingHeap<T> &b)
-{
- os<<"Heap:";
- if (b.root != NULL) {
- PairNode<T> *r = b.root;
- list<PairNode<T>*> q;
- q.push_back(r);
- while (!q.empty()) {
- r = q.front();
- q.pop_front();
- if (r->leftChild != NULL) {
- os << *r->element << ">";
- PairNode<T> *c = r->leftChild;
- while (c != NULL) {
- q.push_back(c);
- os << "," << *c->element;
- c = c->nextSibling;
- }
- os << "|";
- }
- }
- }
- return os;
-}
-#endif
diff --git a/src/removeoverlap/pairingheap/PairingHeap.h b/src/removeoverlap/pairingheap/PairingHeap.h
deleted file mode 100644
index 52941873b..000000000
--- a/src/removeoverlap/pairingheap/PairingHeap.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * \brief Pairing heap datastructure implementation
- *
- * Based on example code in "Data structures and Algorithm Analysis in C++"
- * by Mark Allen Weiss, used and released under the GPL by permission
- * of the author.
- *
- * No promises about correctness. Use at your own risk!
- *
- * Authors:
- * Mark Allen Weiss
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU GPL. Read the file 'COPYING' for more information.
- */
-#ifndef PAIRING_HEAP_H_
-#define PAIRING_HEAP_H_
-#include <stdlib.h>
-#include <fstream>
-// Pairing heap class
-//
-// CONSTRUCTION: with no parameters
-//
-// ******************PUBLIC OPERATIONS*********************
-// PairNode & insert( x ) --> Insert x
-// deleteMin( minItem ) --> Remove (and optionally return) smallest item
-// T findMin( ) --> Return smallest item
-// bool isEmpty( ) --> Return true if empty; else false
-// bool isFull( ) --> Return true if empty; else false
-// void makeEmpty( ) --> Remove all items
-// void decreaseKey( PairNode p, newVal )
-// --> Decrease value in node p
-// ******************ERRORS********************************
-// Throws Underflow as warranted
-
-
-// Node and forward declaration because g++ does
-// not understand nested classes.
-template <class T>
-class PairingHeap;
-
-template <class T>
-std::ostream& operator<< (std::ostream &os,const PairingHeap<T> &b);
-
-template <class T>
-class PairNode
-{
- friend std::ostream& operator<< <T>(std::ostream &os,const PairingHeap<T> &b);
- T element;
- PairNode *leftChild;
- PairNode *nextSibling;
- PairNode *prev;
-
- PairNode( const T & theElement ) :
- element( theElement ),
- leftChild(NULL), nextSibling(NULL), prev(NULL)
- { }
- friend class PairingHeap<T>;
-};
-
-template <class T>
-class Comparator
-{
-public:
- virtual bool isLessThan(T const &lhs, T const &rhs) const = 0;
-};
-
-template <class T>
-class PairingHeap
-{
- friend std::ostream& operator<< <T>(std::ostream &os,const PairingHeap<T> &b);
-public:
- PairingHeap( bool (*lessThan)(T const &lhs, T const &rhs) );
- PairingHeap( const PairingHeap & rhs );
- ~PairingHeap( );
-
- bool isEmpty( ) const;
- bool isFull( ) const;
- int size();
-
- PairNode<T> *insert( const T & x );
- const T & findMin( ) const;
- void deleteMin( );
- void makeEmpty( );
- void decreaseKey( PairNode<T> *p, const T & newVal );
- void merge( PairingHeap<T> *rhs )
- {
- PairNode<T> *broot=rhs->getRoot();
- if (root == NULL) {
- if(broot != NULL) {
- root = broot;
- }
- } else {
- compareAndLink(root, broot);
- }
- counter+=rhs->size();
- }
-
- const PairingHeap & operator=( const PairingHeap & rhs );
-protected:
- PairNode<T> * getRoot() {
- PairNode<T> *r=root;
- root=NULL;
- return r;
- }
-private:
- PairNode<T> *root;
- bool (*lessThan)(T const &lhs, T const &rhs);
- int counter;
- void reclaimMemory( PairNode<T> *t ) const;
- void compareAndLink( PairNode<T> * & first, PairNode<T> *second ) const;
- PairNode<T> * combineSiblings( PairNode<T> *firstSibling ) const;
- PairNode<T> * clone( PairNode<T> * t ) const;
-};
-
-#include "PairingHeap.cpp"
-#endif
diff --git a/src/removeoverlap/pairingheap/dsexceptions.h b/src/removeoverlap/pairingheap/dsexceptions.h
deleted file mode 100644
index bef2c78c5..000000000
--- a/src/removeoverlap/pairingheap/dsexceptions.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef DSEXCEPTIONS_H_
-#define DSEXCEPTIONS_H_
-
-class Underflow { };
-class Overflow { };
-class OutOfMemory { };
-class BadIterator { };
-
-#endif
diff --git a/src/removeoverlap/placement_SolveVPSC.cpp b/src/removeoverlap/placement_SolveVPSC.cpp
deleted file mode 100755
index a9f4344c8..000000000
--- a/src/removeoverlap/placement_SolveVPSC.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-#include <jni.h>
-#include "placement_SolveVPSC.h"
-#include <stdio.h>
-#include "solve_VPSC.h"
-#include "variable.h"
-#include "constraint.h"
-#include "remove_rectangle_overlap.h"
-#include "generate-constraints.h"
-#include <assert.h>
-#include <map>
-#define MaxSize 500
-
-JNIEXPORT jdouble JNICALL Java_placement_SolveVPSC_solve
- (JNIEnv *env, jobject obj, jobjectArray vName, jdoubleArray vWeight, jdoubleArray vDesPos, jintArray cLeft, jintArray cRight, jdoubleArray cGap, jdoubleArray vResult, jint mode)
-{
- jsize n = env->GetArrayLength(vWeight);
- jsize m = env->GetArrayLength(cLeft);
- int i;
- double *lvWeight = env->GetDoubleArrayElements(vWeight, 0);
- double *lvDesPos = env->GetDoubleArrayElements(vDesPos, 0);
- long *lcLeft = env->GetIntArrayElements(cLeft, 0);
- long *lcRight = env->GetIntArrayElements(cRight, 0);
- double *lcGap = env->GetDoubleArrayElements(cGap, 0);
- Variable **vs=new Variable*[n];
- Constraint **cs=new Constraint*[m];
- for (i=0; i<n; i++) {
- jstring lvName = (jstring)env->GetObjectArrayElement(vName, i);
- const char *name = env->GetStringUTFChars(lvName, NULL);
- // once upon a time variables had real names, now you'll have to
- // track them by number.
- vs[i]=new Variable(i,lvDesPos[i],lvWeight[i]);
- }
- for (i=0; i<m; i++) {
- cs[i]=new Constraint(vs[lcLeft[i]],vs[lcRight[i]],lcGap[i]);
- }
- double cost=0;
- VPSC vpsc(vs,n,cs,m);
- if(mode==0) {
- vpsc.satisfy();
- } else {
- vpsc.solve();
- }
- for (i=0; i<n; i++) {
- double p=vs[i]->position();
- env->SetDoubleArrayRegion(vResult, i,1,&p);
- }
- for (i=0; i<m; i++) {
- delete cs[i];
- }
- delete [] cs;
- for (i=0; i<n; i++) {
- delete vs[i];
- }
- env->ReleaseIntArrayElements(cLeft, lcLeft, 0);
- env->ReleaseIntArrayElements(cRight, lcRight, 0);
- env->ReleaseDoubleArrayElements(cGap, lcGap, 0);
- env->ReleaseDoubleArrayElements(vWeight, lvWeight, 0);
- env->ReleaseDoubleArrayElements(vDesPos, lvDesPos, 0);
- delete [] vs;
- return cost;
-}
-
-static Variable **vs;
-static Constraint **cs;
-static int m,n;
-JNIEXPORT jint JNICALL Java_placement_SolveVPSC_generateXConstraints
-(JNIEnv *env, jobject obj, jdoubleArray rMinX, jdoubleArray rMaxX, jdoubleArray rMinY, jdoubleArray rMaxY, jdoubleArray rWeight) {
- n = (int)env->GetArrayLength(rWeight);
- Rectangle **rs=new Rectangle*[n];
- double *ws = env->GetDoubleArrayElements(rWeight, 0);
- double *minX = env->GetDoubleArrayElements(rMinX, 0);
- double *maxX = env->GetDoubleArrayElements(rMaxX, 0);
- double *minY = env->GetDoubleArrayElements(rMinY, 0);
- double *maxY = env->GetDoubleArrayElements(rMaxY, 0);
- for(int i=0;i<n;i++) rs[i]=new Rectangle(minX[i],maxX[i],minY[i],maxY[i]);
- m = generateXConstraints(rs, ws, n, vs, cs, true);
- return m;
-}
-
-JNIEXPORT jint JNICALL Java_placement_SolveVPSC_generateYConstraints
-(JNIEnv *env, jobject obj, jdoubleArray rMinX, jdoubleArray rMaxX, jdoubleArray rMinY, jdoubleArray rMaxY, jdoubleArray rWeight) {
- n = (int)env->GetArrayLength(rWeight);
- Rectangle **rs=new Rectangle*[n];
- double *ws = env->GetDoubleArrayElements(rWeight, 0);
- double *minX = env->GetDoubleArrayElements(rMinX, 0);
- double *maxX = env->GetDoubleArrayElements(rMaxX, 0);
- double *minY = env->GetDoubleArrayElements(rMinY, 0);
- double *maxY = env->GetDoubleArrayElements(rMaxY, 0);
- for(int i=0;i<n;i++) rs[i]=new Rectangle(minX[i],maxX[i],minY[i],maxY[i]);
- m = generateYConstraints(rs, ws, n, vs, cs);
- return m;
-}
-using namespace std;
-JNIEXPORT void JNICALL Java_placement_SolveVPSC_getConstraints
-(JNIEnv *env, jobject obj, jintArray cLeft, jintArray cRight, jdoubleArray cGap) {
- map<Variable*,int> vmap;
- for(int i=0;i<n;i++) {
- vmap[vs[i]]=i;
- }
-
- for(int i=0;i<m;i++) {
- jint l=vmap[cs[i]->left];
- jint r=vmap[cs[i]->right];
- double g=cs[i]->gap;
- env->SetIntArrayRegion(cLeft, i,1,&l);
- env->SetIntArrayRegion(cRight, i,1,&r);
- env->SetDoubleArrayRegion(cGap, i,1,&g);
- }
-}
-JNIEXPORT void JNICALL Java_placement_SolveVPSC_removeOverlaps
-(JNIEnv *env, jobject obj, jdoubleArray rMinX, jdoubleArray rMaxX, jdoubleArray rMinY, jdoubleArray rMaxY) {
- //assert(1==2); //break for debugging
- n = (int)env->GetArrayLength(rMinX);
- Rectangle **rs=new Rectangle*[n];
- double *minX = env->GetDoubleArrayElements(rMinX, 0);
- double *maxX = env->GetDoubleArrayElements(rMaxX, 0);
- double *minY = env->GetDoubleArrayElements(rMinY, 0);
- double *maxY = env->GetDoubleArrayElements(rMaxY, 0);
- for(int i=0;i<n;i++) rs[i]=new Rectangle(minX[i],maxX[i],minY[i],maxY[i]);
- removeRectangleOverlap(rs,n,0,0);
- for (i=0; i<n; i++) {
- double x=rs[i]->getMinX();
- double y=rs[i]->getMinY();
- env->SetDoubleArrayRegion(rMinX, i,1,&x);
- env->SetDoubleArrayRegion(rMinY, i,1,&y);
- }
- delete [] rs;
- env->ReleaseDoubleArrayElements(rMaxX, maxX, 0);
- env->ReleaseDoubleArrayElements(rMaxY, maxY, 0);
-} \ No newline at end of file
diff --git a/src/removeoverlap/placement_SolveVPSC.h b/src/removeoverlap/placement_SolveVPSC.h
deleted file mode 100755
index 9f1c10cda..000000000
--- a/src/removeoverlap/placement_SolveVPSC.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class placement_SolveVPSC */
-
-#ifndef _Included_placement_SolveVPSC
-#define _Included_placement_SolveVPSC
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class: placement_SolveVPSC
- * Method: solve
- * Signature: ([Ljava/lang/String;[D[D[I[I[D[DI)D
- */
-JNIEXPORT jdouble JNICALL Java_placement_SolveVPSC_solve
- (JNIEnv *, jobject, jobjectArray, jdoubleArray, jdoubleArray, jintArray, jintArray, jdoubleArray, jdoubleArray, jint);
-
-/*
- * Class: placement_SolveVPSC
- * Method: generateXConstraints
- * Signature: ([D[D[D[D[D)I
- */
-JNIEXPORT jint JNICALL Java_placement_SolveVPSC_generateXConstraints
- (JNIEnv *, jobject, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray);
-
-/*
- * Class: placement_SolveVPSC
- * Method: generateYConstraints
- * Signature: ([D[D[D[D[D)I
- */
-JNIEXPORT jint JNICALL Java_placement_SolveVPSC_generateYConstraints
- (JNIEnv *, jobject, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray);
-
-/*
- * Class: placement_SolveVPSC
- * Method: getConstraints
- * Signature: ([I[I[D)V
- */
-JNIEXPORT void JNICALL Java_placement_SolveVPSC_getConstraints
- (JNIEnv *, jobject, jintArray, jintArray, jdoubleArray);
-
-/*
- * Class: placement_SolveVPSC
- * Method: removeOverlaps
- * Signature: ([D[D[D[D)V
- */
-JNIEXPORT void JNICALL Java_placement_SolveVPSC_removeOverlaps
- (JNIEnv *, jobject, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/removeoverlap/remove_rectangle_overlap-test.cpp b/src/removeoverlap/remove_rectangle_overlap-test.cpp
deleted file mode 100644
index 20f5489cc..000000000
--- a/src/removeoverlap/remove_rectangle_overlap-test.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-#include "removeoverlap/remove_rectangle_overlap.h"
-#include <unistd.h> // for alarm()
-#include <time.h> // for srand seed and clock().
-#include <glib/gmacros.h>
-#include <glib/gmem.h>
-#include <cstdlib>
-#include <cmath>
-#include "removeoverlap/generate-constraints.h"
-#include "utest/utest.h"
-using std::abs;
-using std::rand;
-
-static bool
-possibly_eq(double const a, double const b)
-{
- return abs(a - b) < 1e-13;
-}
-
-static bool
-possibly_le(double const a, double const b)
-{
- return a - b < 1e-13;
-}
-
-static void
-show_rects(unsigned const n_rects, double const rect2coords[][4])
-{
- for (unsigned i = 0; i < n_rects; ++i) {
- printf("{%g, %g, %g, %g},\n",
- rect2coords[i][0],
- rect2coords[i][1],
- rect2coords[i][2],
- rect2coords[i][3]);
- }
-}
-
-/**
- * Returns the signum of x, but erring towards returning 0 if x is "not too far" from 0. ("Not too
- * far from 0" means [-0.9, 0.9] in current version.)
- */
-static int
-sgn0(double const x)
-{
- if (x <= -0.9) {
- return -1;
- } else if (0.9 <= x) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static void
-test_case(unsigned const n_rects, double const rect2coords[][4])
-{
- Rectangle **rs = (Rectangle **) g_malloc(sizeof(Rectangle*) * n_rects);
- for (unsigned i = 0; i < n_rects; ++i) {
- rs[i] = new Rectangle(rect2coords[i][0],
- rect2coords[i][1],
- rect2coords[i][2],
- rect2coords[i][3]);
- }
- removeRectangleOverlap(n_rects,rs,0.0, 0.0);
- for (unsigned i = 0; i < n_rects; ++i) {
- UTEST_ASSERT(possibly_eq(rs[i]->width(), (rect2coords[i][1] -
- rect2coords[i][0] )));
- UTEST_ASSERT(possibly_eq(rs[i]->height(), (rect2coords[i][3] -
- rect2coords[i][2] )));
- for (unsigned j = 0; j < i; ++j) {
- if (!( possibly_le(rs[i]->getMaxX(), rs[j]->getMinX()) ||
- possibly_le(rs[j]->getMaxX(), rs[i]->getMinX()) ||
- possibly_le(rs[i]->getMaxY(), rs[j]->getMinY()) ||
- possibly_le(rs[j]->getMaxY(), rs[i]->getMinY()) )) {
- show_rects(n_rects, rect2coords);
- char buf[32];
- sprintf(buf, "[%u],[%u] of %u", j, i, n_rects);
- utest__fail("Found overlap among ", buf, " rectangles");
- }
- }
-
- /* Optimality test. */
- {
- bool found_block[2] = {false, false};
- int const desired_movement[2] = {sgn0(rect2coords[i][0] - rs[i]->getMinX()),
- sgn0(rect2coords[i][2] - rs[i]->getMinY())};
- for (unsigned j = 0; j < n_rects; ++j) {
- if (j == i)
- continue;
- for (unsigned d = 0; d < 2; ++d) {
- if ( ( desired_movement[d] < 0
- ? abs(rs[j]->getMaxD(d) - rs[i]->getMinD(d))
- : abs(rs[i]->getMaxD(d) - rs[j]->getMinD(d)) )
- < .002 ) {
- found_block[d] = true;
- }
- }
- }
-
- for (unsigned d = 0; d < 2; ++d) {
- if ( !found_block[d]
- && desired_movement[d] != 0 ) {
- show_rects(n_rects, rect2coords);
- char buf[32];
- sprintf(buf, "%c in rectangle [%u] of %u", "XY"[d], i, n_rects);
- utest__fail("Found clear non-optimality in ", buf, " rectangles");
- }
- }
- }
- }
- for (unsigned i = 0; i < n_rects; ++i) {
- delete rs[i];
- }
- g_free(rs);
-}
-
-int main()
-{
- srand(time(NULL));
-
- /* Ensure that the program doesn't run for more than 60 seconds. */
- alarm(60);
-
- utest_start("removeRectangleOverlap(zero gaps)");
-
- /* Derived from Bulia's initial test case. This used to crash. */
- UTEST_TEST("eg0") {
- double case0[][4] = {
- {-180.5, 69.072, 368.071, 629.071},
- {99.5, 297.644, 319.5, 449.071},
- {199.5, 483.358, 450.929, 571.929},
- {168.071, 277.644, 462.357, 623.357},
- {99.5, 99.751, 479.5, 674.786},
- {-111.929, 103.358, 453.786, 611.929},
- {-29.0714, 143.358, 273.786, 557.643},
- {122.357, 269.072, 322.357, 531.929},
- {256.643, 357.644, 396.643, 520.5}
- };
- test_case(G_N_ELEMENTS(case0), case0);
- }
-
-#if 0 /* This involves a zero-height rect, so we'll ignore for the moment. */
- UTEST_TEST("eg1") {
- double case1[][4] = {
- {5, 14, 9, 14},
- {6, 13, 6, 8},
- {11, 12, 5, 5},
- {5, 8, 5, 7},
- {12, 14, 14, 15},
- {12, 14, 1, 14},
- {1, 15, 14, 15},
- {5, 6, 13, 13}
- };
- test_case(G_N_ELEMENTS(case1), case1);
- }
-#endif
-
- /* The next few examples used to result in overlaps. */
- UTEST_TEST("eg2") {
- double case2[][4] = {
- {3, 4, 6, 13},
- {0, 1, 0, 5},
- {0, 4, 1, 6},
- {2, 5, 0, 6},
- {0, 10, 9, 13},
- {5, 11, 1, 13},
- {1, 2, 3, 8}
- };
- test_case(G_N_ELEMENTS(case2), case2);
- }
-
- UTEST_TEST("eg3") {
- double case3[][4] = {
- {0, 5, 0, 3},
- {1, 2, 1, 3},
- {3, 7, 4, 7},
- {0, 9, 4, 5},
- {3, 7, 0, 3}
- };
- test_case(G_N_ELEMENTS(case3), case3);
- }
-
- UTEST_TEST("eg4") {
- double case4[][4] = {
- {0, 1, 2, 3},
- {0, 4, 0, 4},
- {1, 6, 0, 4},
- {2, 3, 4, 5},
- {0, 5, 4, 6}
- };
- test_case(G_N_ELEMENTS(case4), case4);
- }
-
- UTEST_TEST("eg5") {
- double case5[][4] = {
- {1, 5, 1, 2},
- {1, 6, 5, 7},
- {6, 8, 1, 2},
- {2, 3, 1, 4},
- {5, 8, 2, 6}
- };
- test_case(G_N_ELEMENTS(case5), case5);
- }
-
- /* This one causes overlap in 2005-12-19 04:00 UTC version. */
- UTEST_TEST("olap6") {
- double case6[][4] = {
- {7, 22, 39, 54},
- {7, 33, 0, 59},
- {3, 26, 16, 56},
- {7, 17, 18, 20},
- {1, 59, 11, 26},
- {19, 20, 13, 49},
- {1, 10, 0, 4},
- {47, 52, 1, 3}
- };
- test_case(G_N_ELEMENTS(case6), case6);
- }
-
- /* The next two examples caused loops in the version at 2005-12-07 04:00 UTC. */
- UTEST_TEST("loop0") {
- double loop0[][4] = {
- {13, 16, 6, 27},
- {0, 6, 0, 12},
- {11, 14, 1, 10},
- {12, 39, 5, 24},
- {14, 34, 4, 7},
- {1, 30, 20, 27},
- {1, 6, 1, 2},
- {19, 28, 10, 24},
- {4, 34, 15, 21},
- {7, 13, 13, 34}
- };
- test_case(G_N_ELEMENTS(loop0), loop0);
- }
-
- UTEST_TEST("loop1") {
- double loop1[][4] = {
- {6, 18, 9, 16},
- {8, 26, 10, 13},
- {3, 10, 0, 14},
- {0, 5, 16, 22},
- {1, 8, 11, 21},
- {1, 5, 0, 13},
- {24, 25, 0, 2}
- };
- test_case(G_N_ELEMENTS(loop1), loop1);
- }
-
- UTEST_TEST("loop2") {
- double loop2[][4] = {
- {16, 22, 9, 16},
- {8, 9, 14, 19},
- {17, 25, 8, 13},
- {10, 26, 26, 29},
- {14, 19, 9, 19},
- {0, 18, 3, 12},
- {7, 8, 14, 22},
- {14, 20, 25, 29}
- };
- test_case(G_N_ELEMENTS(loop2), loop2);
- }
-
- /* Random cases of up to 10 rectangles, with small non-neg int coords. */
- for (unsigned n = 0; n <= 10; ++n) {
- char buf[64];
- sprintf(buf, "random ints with %u rectangles", n);
- UTEST_TEST(buf) {
- unsigned const fld_size = 8 * n;
- double (*coords)[4] = (double (*)[4]) g_malloc(n * 4 * sizeof(double));
- clock_t const clock_stop = clock() + CLOCKS_PER_SEC;
- for (unsigned repeat = (n == 0 ? 1
- : n == 1 ? 36
- : (1 << 16) ); repeat--;) {
- for (unsigned i = 0; i < n; ++i) {
- for (unsigned d = 0; d < 2; ++d) {
- //unsigned const start = rand() % fld_size;
- //unsigned const end = start + rand() % (fld_size - start);
- unsigned const end = 1 + (rand() % (fld_size - 1));
- unsigned const start = rand() % end;
- coords[i][2 * d] = start;
- coords[i][2 * d + 1] = end;
- }
- }
- test_case(n, coords);
- if (clock() >= clock_stop) {
- break;
- }
- }
- g_free(coords);
- }
- }
-
- return ( utest_end()
- ? EXIT_SUCCESS
- : EXIT_FAILURE );
-}
-
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/removeoverlap/remove_rectangle_overlap.cpp b/src/removeoverlap/remove_rectangle_overlap.cpp
deleted file mode 100755
index 9fbef647b..000000000
--- a/src/removeoverlap/remove_rectangle_overlap.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * \brief remove overlaps between a set of rectangles.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-#include <iostream>
-#include <cassert>
-#include "generate-constraints.h"
-#include "solve_VPSC.h"
-#include "variable.h"
-#include "constraint.h"
-#ifdef RECTANGLE_OVERLAP_LOGGING
-#include <fstream>
-#include "blocks.h"
-using std::ios;
-using std::ofstream;
-using std::endl;
-#endif
-
-#define EXTRA_GAP 0.0001
-
-double Rectangle::xBorder=0;
-double Rectangle::yBorder=0;
-/**
- * Takes an array of n rectangles and moves them as little as possible
- * such that rectangles are separated by at least xBorder horizontally
- * and yBorder vertically
- *
- * Works in three passes:
- * 1) removes some overlap horizontally
- * 2) removes remaining overlap vertically
- * 3) a last horizontal pass removes all overlap starting from original
- * x-positions - this corrects the case where rectangles were moved
- * too much in the first pass.
- */
-void removeRectangleOverlap(unsigned n, Rectangle *rs[], double xBorder, double yBorder) {
- try {
- // The extra gap avoids numerical imprecision problems
- Rectangle::setXBorder(xBorder+EXTRA_GAP);
- Rectangle::setYBorder(yBorder+EXTRA_GAP);
- Variable **vs=new Variable*[n];
- for(unsigned int i=0;i<n;i++) {
- vs[i]=new Variable(i,0,1);
- }
- Constraint **cs;
- double *oldX = new double[n];
- int m=generateXConstraints(n,rs,vs,cs,true);
- for(unsigned int i=0;i<n;i++) {
- oldX[i]=vs[i]->desiredPosition;
- }
- VPSC vpsc_x(n,vs,m,cs);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Calling VPSC: Horizontal pass 1"<<endl;
- f.close();
-#endif
- vpsc_x.solve();
- for(unsigned int i=0;i<n;i++) {
- rs[i]->moveCentreX(vs[i]->position());
- }
- for(int i = 0; i < m; ++i) {
- delete cs[i];
- }
- delete [] cs;
- // Removing the extra gap here ensures things that were moved to be adjacent to
- // one another above are not considered overlapping
- Rectangle::setXBorder(Rectangle::xBorder-EXTRA_GAP);
- m=generateYConstraints(n,rs,vs,cs);
- VPSC vpsc_y(n,vs,m,cs);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f.open(LOGFILE,ios::app);
- f<<"Calling VPSC: Vertical pass"<<endl;
- f.close();
-#endif
- vpsc_y.solve();
- for(unsigned int i=0;i<n;i++) {
- rs[i]->moveCentreY(vs[i]->position());
- rs[i]->moveCentreX(oldX[i]);
- }
- delete [] oldX;
- for(int i = 0; i < m; ++i) {
- delete cs[i];
- }
- delete [] cs;
- Rectangle::setYBorder(Rectangle::yBorder-EXTRA_GAP);
- m=generateXConstraints(n,rs,vs,cs,false);
- VPSC vpsc_x2(n,vs,m,cs);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f.open(LOGFILE,ios::app);
- f<<"Calling VPSC: Horizontal pass 2"<<endl;
- f.close();
-#endif
- vpsc_x2.solve();
- for(int i = 0; i < m; ++i) {
- delete cs[i];
- }
- delete [] cs;
- for(unsigned int i=0;i<n;i++) {
- rs[i]->moveCentreX(vs[i]->position());
- delete vs[i];
- }
- delete [] vs;
- } catch (char const *str) {
- std::cerr<<str<<std::endl;
- for(unsigned int i=0;i<n;i++) {
- std::cerr << *rs[i]<<std::endl;
- }
- }
-}
diff --git a/src/removeoverlap/remove_rectangle_overlap.h b/src/removeoverlap/remove_rectangle_overlap.h
deleted file mode 100755
index 08b035e31..000000000
--- a/src/removeoverlap/remove_rectangle_overlap.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef REMOVE_RECTANGLE_OVERLAP_H_SEEN
-#define REMOVE_RECTANGLE_OVERLAP_H_SEEN
-
-/**
- * \file Declaration of main internal remove-overlaps function.
- */
-/*
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-class Rectangle;
-
-void removeRectangleOverlap(unsigned n, Rectangle *rs[], double xBorder, double yBorder);
-
-
-#endif /* !REMOVE_RECTANGLE_OVERLAP_H_SEEN */
diff --git a/src/removeoverlap/removeoverlap.cpp b/src/removeoverlap/removeoverlap.cpp
index d79fa9eab..3a8481db2 100644
--- a/src/removeoverlap/removeoverlap.cpp
+++ b/src/removeoverlap/removeoverlap.cpp
@@ -12,8 +12,8 @@
#include "util/glib-list-iterators.h"
#include "sp-item.h"
#include "sp-item-transform.h"
-#include "removeoverlap/generate-constraints.h"
-#include "removeoverlap/remove_rectangle_overlap.h"
+#include "libvpsc/generate-constraints.h"
+#include "libvpsc/remove_rectangle_overlap.h"
/**
* Takes a list of inkscape items and moves them as little as possible
@@ -29,7 +29,7 @@ void removeoverlap(GSList const *const items, double const xGap, double const yG
std::list<SPItem *> selected;
selected.insert<GSListConstIterator<SPItem *> >(selected.end(), items, NULL);
if (selected.empty()) return;
- unsigned n=selected.size();
+ int n=selected.size();
//Check 2 or more selected objects
if (n < 2) return;
diff --git a/src/removeoverlap/solve_VPSC.cpp b/src/removeoverlap/solve_VPSC.cpp
deleted file mode 100644
index 77279c8a8..000000000
--- a/src/removeoverlap/solve_VPSC.cpp
+++ /dev/null
@@ -1,412 +0,0 @@
-/**
- * \brief Solve an instance of the "Variable Placement with Separation
- * Constraints" problem.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-
-#include <cassert>
-#include "constraint.h"
-#include "block.h"
-#include "blocks.h"
-#include "solve_VPSC.h"
-#include <math.h>
-#include <sstream>
-#ifdef RECTANGLE_OVERLAP_LOGGING
-#include <fstream>
-using std::ios;
-using std::ofstream;
-using std::endl;
-#endif
-
-using std::ostringstream;
-using std::list;
-using std::set;
-
-IncVPSC::IncVPSC(const unsigned n, Variable *vs[], const unsigned m, Constraint *cs[])
- : VPSC(n,vs,m,cs) {
- inactive.assign(cs,cs+m);
- for(ConstraintList::iterator i=inactive.begin();i!=inactive.end();++i) {
- (*i)->active=false;
- }
-}
-VPSC::VPSC(const unsigned n, Variable *vs[], const unsigned m, Constraint *cs[]) : cs(cs), m(m), vs(vs) {
- bs=new Blocks(n, vs);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- printBlocks();
- assert(!constraintGraphIsCyclic(n,vs));
-#endif
-}
-VPSC::~VPSC() {
- delete bs;
-}
-
-// useful in debugging
-void VPSC::printBlocks() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- for(set<Block*>::iterator i=bs->begin();i!=bs->end();++i) {
- Block *b=*i;
- f<<" "<<*b<<endl;
- }
- for(unsigned i=0;i<m;i++) {
- f<<" "<<*cs[i]<<endl;
- }
-#endif
-}
-/**
-* Produces a feasible - though not necessarily optimal - solution by
-* examining blocks in the partial order defined by the directed acyclic
-* graph of constraints. For each block (when processing left to right) we
-* maintain the invariant that all constraints to the left of the block
-* (incoming constraints) are satisfied. This is done by repeatedly merging
-* blocks into bigger blocks across violated constraints (most violated
-* first) fixing the position of variables inside blocks relative to one
-* another so that constraints internal to the block are satisfied.
-*/
-void VPSC::satisfy() {
- list<Variable*> *vs=bs->totalOrder();
- for(list<Variable*>::iterator i=vs->begin();i!=vs->end();++i) {
- Variable *v=*i;
- if(!v->block->deleted) {
- bs->mergeLeft(v->block);
- }
- }
- bs->cleanup();
- for(unsigned i=0;i<m;i++) {
- if(cs[i]->slack()<-0.0000001) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Error: Unsatisfied constraint: "<<*cs[i]<<endl;
-#endif
- //assert(cs[i]->slack()>-0.0000001);
- throw "Unsatisfied constraint";
- }
- }
- delete vs;
-}
-
-void VPSC::refine() {
- bool solved=false;
- // Solve shouldn't loop indefinately
- // ... but just to make sure we limit the number of iterations
- unsigned maxtries=100;
- while(!solved&&maxtries>0) {
- solved=true;
- maxtries--;
- for(set<Block*>::const_iterator i=bs->begin();i!=bs->end();++i) {
- Block *b=*i;
- b->setUpInConstraints();
- b->setUpOutConstraints();
- }
- for(set<Block*>::const_iterator i=bs->begin();i!=bs->end();++i) {
- Block *b=*i;
- Constraint *c=b->findMinLM();
- if(c!=NULL && c->lm<0) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Split on constraint: "<<*c<<endl;
-#endif
- // Split on c
- Block *l=NULL, *r=NULL;
- bs->split(b,l,r,c);
- bs->cleanup();
- // split alters the block set so we have to restart
- solved=false;
- break;
- }
- }
- }
- for(unsigned i=0;i<m;i++) {
- if(cs[i]->slack()<-0.0000001) {
- assert(cs[i]->slack()>-0.0000001);
- throw "Unsatisfied constraint";
- }
- }
-}
-/**
- * Calculate the optimal solution. After using satisfy() to produce a
- * feasible solution, refine() examines each block to see if further
- * refinement is possible by splitting the block. This is done repeatedly
- * until no further improvement is possible.
- */
-void VPSC::solve() {
- satisfy();
- refine();
-}
-
-void IncVPSC::solve() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"solve_inc()..."<<endl;
-#endif
- double lastcost,cost = bs->cost();
- do {
- lastcost=cost;
- satisfy();
- splitBlocks();
- cost = bs->cost();
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" cost="<<cost<<endl;
-#endif
- } while(fabs(lastcost-cost)>0.0001);
-}
-/**
- * incremental version of satisfy that allows refinement after blocks are
- * moved.
- *
- * - move blocks to new positions
- * - repeatedly merge across most violated constraint until no more
- * violated constraints exist
- *
- * Note: there is a special case to handle when the most violated constraint
- * is between two variables in the same block. Then, we must split the block
- * over an active constraint between the two variables. We choose the
- * constraint with the most negative lagrangian multiplier.
- */
-void IncVPSC::satisfy() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"satisfy_inc()..."<<endl;
-#endif
- splitBlocks();
- long splitCtr = 0;
- Constraint* v = NULL;
- while((v=mostViolated(inactive))&&(v->equality || v->slack()<-0.000001)) {
- assert(!v->active);
- Block *lb = v->left->block, *rb = v->right->block;
- if(lb != rb) {
- lb->merge(rb,v);
- } else {
- if(splitCtr++>10000) {
- throw "Cycle Error!";
- }
- // constraint is within block, need to split first
- inactive.push_back(lb->splitBetween(v->left,v->right,lb,rb));
- lb->merge(rb,v);
- bs->insert(lb);
- }
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" finished merges."<<endl;
-#endif
- bs->cleanup();
- for(unsigned i=0;i<m;i++) {
- v=cs[i];
- if(v->slack()<-0.0000001) {
- //assert(cs[i]->slack()>-0.0000001);
- ostringstream s;
- s<<"Unsatisfied constraint: "<<*v;
- throw s.str().c_str();
- }
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" finished cleanup."<<endl;
- printBlocks();
-#endif
-}
-void IncVPSC::moveBlocks() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"moveBlocks()..."<<endl;
-#endif
- for(set<Block*>::const_iterator i(bs->begin());i!=bs->end();++i) {
- Block *b = *i;
- b->wposn = b->desiredWeightedPosition();
- b->posn = b->wposn / b->weight;
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" moved blocks."<<endl;
-#endif
-}
-void IncVPSC::splitBlocks() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
-#endif
- moveBlocks();
- splitCnt=0;
- // Split each block if necessary on min LM
- for(set<Block*>::const_iterator i(bs->begin());i!=bs->end();++i) {
- Block* b = *i;
- Constraint* v=b->findMinLM();
- if(v!=NULL && v->lm < -0.0000001) {
- assert(!v->equality);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" found split point: "<<*v<<" lm="<<v->lm<<endl;
-#endif
- splitCnt++;
- Block *b = v->left->block, *l=NULL, *r=NULL;
- assert(v->left->block == v->right->block);
- double pos = b->posn;
- b->split(l,r,v);
- l->posn=r->posn=pos;
- l->wposn = l->posn * l->weight;
- r->wposn = r->posn * r->weight;
- bs->insert(l);
- bs->insert(r);
- b->deleted=true;
- inactive.push_back(v);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" new blocks: "<<*l<<" and "<<*r<<endl;
-#endif
- }
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" finished splits."<<endl;
-#endif
- bs->cleanup();
-}
-
-/**
- * Scan constraint list for the most violated constraint, or the first equality
- * constraint
- */
-Constraint* IncVPSC::mostViolated(ConstraintList &l) {
- double minSlack = DBL_MAX;
- Constraint* v=NULL;
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Looking for most violated..."<<endl;
-#endif
- ConstraintList::iterator end = l.end();
- ConstraintList::iterator deletePoint = end;
- for(ConstraintList::iterator i=l.begin();i!=end;++i) {
- Constraint *c=*i;
- double slack = c->slack();
- if(c->equality || slack < minSlack) {
- minSlack=slack;
- v=c;
- deletePoint=i;
- if(c->equality) break;
- }
- }
- // Because the constraint list is not order dependent we just
- // move the last element over the deletePoint and resize
- // downwards. There is always at least 1 element in the
- // vector because of search.
- if(deletePoint != end && (minSlack<-0.0000001||v->equality)) {
- *deletePoint = l[l.size()-1];
- l.resize(l.size()-1);
- }
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" most violated is: "<<*v<<endl;
-#endif
- return v;
-}
-
-#include <map>
-using std::map;
-using std::vector;
-struct node {
- set<node*> in;
- set<node*> out;
-};
-// useful in debugging - cycles would be BAD
-bool VPSC::constraintGraphIsCyclic(const unsigned n, Variable *vs[]) {
- map<Variable*, node*> varmap;
- vector<node*> graph;
- for(unsigned i=0;i<n;i++) {
- node *u=new node;
- graph.push_back(u);
- varmap[vs[i]]=u;
- }
- for(unsigned i=0;i<n;i++) {
- for(vector<Constraint*>::iterator c=vs[i]->in.begin();c!=vs[i]->in.end();++c) {
- Variable *l=(*c)->left;
- varmap[vs[i]]->in.insert(varmap[l]);
- }
-
- for(vector<Constraint*>::iterator c=vs[i]->out.begin();c!=vs[i]->out.end();++c) {
- Variable *r=(*c)->right;
- varmap[vs[i]]->out.insert(varmap[r]);
- }
- }
- while(graph.size()>0) {
- node *u=NULL;
- vector<node*>::iterator i=graph.begin();
- for(;i!=graph.end();++i) {
- u=*i;
- if(u->in.size()==0) {
- break;
- }
- }
- if(i==graph.end() && graph.size()>0) {
- //cycle found!
- return true;
- } else {
- graph.erase(i);
- for(set<node*>::iterator j=u->out.begin();j!=u->out.end();++j) {
- node *v=*j;
- v->in.erase(u);
- }
- delete u;
- }
- }
- for(unsigned i=0; i<graph.size(); ++i) {
- delete graph[i];
- }
- return false;
-}
-
-// useful in debugging - cycles would be BAD
-bool VPSC::blockGraphIsCyclic() {
- map<Block*, node*> bmap;
- vector<node*> graph;
- for(set<Block*>::const_iterator i=bs->begin();i!=bs->end();++i) {
- Block *b=*i;
- node *u=new node;
- graph.push_back(u);
- bmap[b]=u;
- }
- for(set<Block*>::const_iterator i=bs->begin();i!=bs->end();++i) {
- Block *b=*i;
- b->setUpInConstraints();
- Constraint *c=b->findMinInConstraint();
- while(c!=NULL) {
- Block *l=c->left->block;
- bmap[b]->in.insert(bmap[l]);
- b->deleteMinInConstraint();
- c=b->findMinInConstraint();
- }
-
- b->setUpOutConstraints();
- c=b->findMinOutConstraint();
- while(c!=NULL) {
- Block *r=c->right->block;
- bmap[b]->out.insert(bmap[r]);
- b->deleteMinOutConstraint();
- c=b->findMinOutConstraint();
- }
- }
- while(graph.size()>0) {
- node *u=NULL;
- vector<node*>::iterator i=graph.begin();
- for(;i!=graph.end();++i) {
- u=*i;
- if(u->in.size()==0) {
- break;
- }
- }
- if(i==graph.end() && graph.size()>0) {
- //cycle found!
- return true;
- } else {
- graph.erase(i);
- for(set<node*>::iterator j=u->out.begin();j!=u->out.end();++j) {
- node *v=*j;
- v->in.erase(u);
- }
- delete u;
- }
- }
- for(unsigned i=0; i<graph.size(); i++) {
- delete graph[i];
- }
- return false;
-}
-
diff --git a/src/removeoverlap/solve_VPSC.h b/src/removeoverlap/solve_VPSC.h
deleted file mode 100644
index 9f6244a5a..000000000
--- a/src/removeoverlap/solve_VPSC.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * \brief Solve an instance of the "Variable Placement with Separation
- * Constraints" problem.
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-#ifndef SEEN_REMOVEOVERLAP_SOLVE_VPSC_H
-#define SEEN_REMOVEOVERLAP_SOLVE_VPSC_H
-
-#include <vector>
-class Variable;
-class Constraint;
-class Blocks;
-
-/**
- * Variable Placement with Separation Constraints problem instance
- */
-class VPSC {
-public:
- virtual void satisfy();
- virtual void solve();
-
- VPSC(const unsigned n, Variable *vs[], const unsigned m, Constraint *cs[]);
- virtual ~VPSC();
- Constraint** getConstraints() { return cs; }
- Variable** getVariables() { return vs; }
-protected:
- Blocks *bs;
- Constraint **cs;
- unsigned m;
- Variable **vs;
- void printBlocks();
-private:
- void refine();
- bool constraintGraphIsCyclic(const unsigned n, Variable *vs[]);
- bool blockGraphIsCyclic();
-};
-
-class IncVPSC : public VPSC {
-public:
- unsigned splitCnt;
- void satisfy();
- void solve();
- void moveBlocks();
- void splitBlocks();
- IncVPSC(const unsigned n, Variable *vs[], const unsigned m, Constraint *cs[]);
-private:
- typedef std::vector<Constraint*> ConstraintList;
- ConstraintList inactive;
- Constraint* mostViolated(ConstraintList &l);
-};
-#endif // SEEN_REMOVEOVERLAP_SOLVE_VPSC_H
diff --git a/src/removeoverlap/variable.cpp b/src/removeoverlap/variable.cpp
deleted file mode 100644
index 1890f788e..000000000
--- a/src/removeoverlap/variable.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-#include "variable.h"
-std::ostream& operator <<(std::ostream &os, const Variable &v) {
- os << "(" << v.id << "=" << v.position() << ")";
- return os;
-}
-
diff --git a/src/removeoverlap/variable.h b/src/removeoverlap/variable.h
deleted file mode 100644
index b1ab66c95..000000000
--- a/src/removeoverlap/variable.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- *
- * Authors:
- * Tim Dwyer <tgdwyer@gmail.com>
- *
- * Copyright (C) 2005 Authors
- *
- * Released under GNU LGPL. Read the file 'COPYING' for more information.
- */
-#ifndef SEEN_REMOVEOVERLAP_VARIABLE_H
-#define SEEN_REMOVEOVERLAP_VARIABLE_H
-
-#include <vector>
-#include <iostream>
-class Block;
-class Constraint;
-#include "block.h"
-
-typedef std::vector<Constraint*> Constraints;
-class Variable
-{
- friend std::ostream& operator <<(std::ostream &os, const Variable &v);
-public:
- const int id; // useful in log files
- double desiredPosition;
- const double weight;
- double offset;
- Block *block;
- bool visited;
- Constraints in;
- Constraints out;
- char *toString();
- inline Variable(const int id, const double desiredPos, const double weight)
- : id(id)
- , desiredPosition(desiredPos)
- , weight(weight)
- , offset(0)
- , block(NULL)
- , visited(false)
- {
- }
- inline double position() const {
- return block->posn+offset;
- }
- //double position() const;
- ~Variable(void){
- in.clear();
- out.clear();
- }
-};
-#endif // SEEN_REMOVEOVERLAP_VARIABLE_H