From d18b8150ba16f4a930b213dae1f4fb369cb3d0bf Mon Sep 17 00:00:00 2001 From: Tim Dwyer Date: Fri, 14 Jul 2006 04:09:40 +0000 Subject: - Connectors with end-markers now constrained to point downwards in graph layout - vpsc namespace added to libvpsc (bzr r1408) --- src/libvpsc/block.cpp | 18 +++++++++++ src/libvpsc/block.h | 6 ++-- src/libvpsc/blocks.cpp | 3 ++ src/libvpsc/blocks.h | 2 ++ src/libvpsc/constraint.cpp | 2 ++ src/libvpsc/constraint.h | 2 ++ src/libvpsc/csolve_VPSC.cpp | 19 ++++++------ src/libvpsc/csolve_VPSC.h | 28 ++++++++++------- src/libvpsc/generate-constraints.cpp | 3 ++ src/libvpsc/generate-constraints.h | 2 ++ src/libvpsc/remove_rectangle_overlap.cpp | 7 +++-- src/libvpsc/remove_rectangle_overlap.h | 4 +-- src/libvpsc/solve_VPSC.cpp | 52 ++++++++++++++++---------------- src/libvpsc/solve_VPSC.h | 15 +++++---- src/libvpsc/variable.cpp | 3 +- src/libvpsc/variable.h | 6 ++-- 16 files changed, 110 insertions(+), 62 deletions(-) (limited to 'src/libvpsc') diff --git a/src/libvpsc/block.cpp b/src/libvpsc/block.cpp index 69a439cd7..221df536a 100644 --- a/src/libvpsc/block.cpp +++ b/src/libvpsc/block.cpp @@ -23,6 +23,7 @@ using std::endl; #endif using std::vector; +namespace vpsc { void Block::addVariable(Variable* const v) { v->block=this; vars->push_back(v); @@ -346,6 +347,22 @@ void Block::populateSplitBlock(Block *b, Variable* const v, Variable* const u) { populateSplitBlock(b, (*c)->right, v); } } +// Search active constraint tree from u to see if there is a directed path to v. +// Returns true if path is found with all constraints in path having their visited flag +// set true. +bool Block::isActiveDirectedPathBetween(Variable* u, Variable *v) { + if(u==v) return true; + for (Cit c=u->out.begin();c!=u->out.end();++c) { + if(canFollowRight(*c,NULL)) { + if(isActiveDirectedPathBetween((*c)->right,v)) { + (*c)->visited=true; + return true; + } + (*c)->visited=false; + } + } + return false; +} /** * 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 @@ -402,3 +419,4 @@ ostream& operator <<(ostream &os, const Block& b) } return os; } +} diff --git a/src/libvpsc/block.h b/src/libvpsc/block.h index 81e6c7637..9c285f311 100644 --- a/src/libvpsc/block.h +++ b/src/libvpsc/block.h @@ -16,10 +16,10 @@ #include #include +template class PairingHeap; +namespace vpsc { class Variable; class Constraint; -template class PairingHeap; -class StupidPriorityQueue; class Block { @@ -55,6 +55,7 @@ public: long timeStamp; PairingHeap *in; PairingHeap *out; + bool isActiveDirectedPathBetween(Variable* u, Variable *v); private: typedef enum {NONE, LEFT, RIGHT} Direction; typedef std::pair Pair; @@ -71,4 +72,5 @@ private: void setUpConstraintHeap(PairingHeap* &h,bool in); }; +} #endif // SEEN_REMOVEOVERLAP_BLOCK_H diff --git a/src/libvpsc/blocks.cpp b/src/libvpsc/blocks.cpp index 48f0237bf..fe0caacfc 100644 --- a/src/libvpsc/blocks.cpp +++ b/src/libvpsc/blocks.cpp @@ -28,6 +28,8 @@ using std::iterator; using std::list; using std::copy; +namespace vpsc { + long blockTimeCtr; Blocks::Blocks(const int n, Variable* const vs[]) : vs(vs),nvs(n) { @@ -194,3 +196,4 @@ double Blocks::cost() { return c; } +} diff --git a/src/libvpsc/blocks.h b/src/libvpsc/blocks.h index 0be1d7636..72363ef66 100644 --- a/src/libvpsc/blocks.h +++ b/src/libvpsc/blocks.h @@ -23,6 +23,7 @@ #include #include +namespace vpsc { class Block; class Variable; class Constraint; @@ -50,4 +51,5 @@ private: }; extern long blockTimeCtr; +} #endif // SEEN_REMOVEOVERLAP_BLOCKS_H diff --git a/src/libvpsc/constraint.cpp b/src/libvpsc/constraint.cpp index 7c200878b..af5da941a 100644 --- a/src/libvpsc/constraint.cpp +++ b/src/libvpsc/constraint.cpp @@ -12,6 +12,7 @@ #include "constraint.h" #include +namespace vpsc { Constraint::Constraint(Variable *left, Variable *right, double gap, bool equality) : left(left), right(right), @@ -45,3 +46,4 @@ std::ostream& operator <<(std::ostream &os, const Constraint &c) } return os; } +} diff --git a/src/libvpsc/constraint.h b/src/libvpsc/constraint.h index 3da7449cd..c73776daf 100644 --- a/src/libvpsc/constraint.h +++ b/src/libvpsc/constraint.h @@ -15,6 +15,7 @@ #include #include "variable.h" +namespace vpsc { class Constraint { @@ -54,5 +55,6 @@ static inline bool compareConstraints(Constraint *const &l, Constraint *const &r } return sl < sr; } +} #endif // SEEN_REMOVEOVERLAP_CONSTRAINT_H diff --git a/src/libvpsc/csolve_VPSC.cpp b/src/libvpsc/csolve_VPSC.cpp index b78b01054..bd7db5ab2 100644 --- a/src/libvpsc/csolve_VPSC.cpp +++ b/src/libvpsc/csolve_VPSC.cpp @@ -15,6 +15,7 @@ #include "generate-constraints.h" #include "solve_VPSC.h" #include "csolve_VPSC.h" +using namespace vpsc; extern "C" { Variable* newVariable(int id, double desiredPos, double weight) { return new Variable(id,desiredPos,weight); @@ -22,11 +23,11 @@ Variable* newVariable(int id, double desiredPos, double weight) { Constraint* newConstraint(Variable* left, Variable* right, double gap) { return new Constraint(left,right,gap); } -VPSC* newVPSC(int n, Variable* vs[], int m, Constraint* cs[]) { - return new VPSC(n,vs,m,cs); +Solver* newSolver(int n, Variable* vs[], int m, Constraint* cs[]) { + return new Solver(n,vs,m,cs); } -VPSC* newIncVPSC(int n, Variable* vs[], int m, Constraint* cs[]) { - return (VPSC*)new IncVPSC(n,vs,m,cs); +Solver* newIncSolver(int n, Variable* vs[], int m, Constraint* cs[]) { + return (Solver*)new vpsc::IncSolver(n,vs,m,cs); } int genXConstraints(int n, boxf* bb, Variable** vs, Constraint*** cs,int transitiveClosure) { @@ -67,7 +68,7 @@ void deleteConstraint(Constraint* c) { void deleteVariable(Variable* v) { delete v; } -void satisfyVPSC(VPSC* vpsc) { +void satisfyVPSC(Solver* vpsc) { try { vpsc->satisfy(); } catch(const char *e) { @@ -75,17 +76,17 @@ void satisfyVPSC(VPSC* vpsc) { exit(1); } } -int getSplitCnt(IncVPSC *vpsc) { +int getSplitCnt(IncSolver *vpsc) { return vpsc->splitCnt; } -void deleteVPSC(VPSC *vpsc) { +void deleteVPSC(Solver *vpsc) { assert(vpsc!=NULL); delete vpsc; } -void solveVPSC(VPSC* vpsc) { +void solveVPSC(Solver* vpsc) { vpsc->solve(); } -void splitIncVPSC(IncVPSC* vpsc) { +void splitIncVPSC(IncSolver* vpsc) { vpsc->splitBlocks(); } void setVariableDesiredPos(Variable *v, double desiredPos) { diff --git a/src/libvpsc/csolve_VPSC.h b/src/libvpsc/csolve_VPSC.h index cd879effe..81e50d990 100644 --- a/src/libvpsc/csolve_VPSC.h +++ b/src/libvpsc/csolve_VPSC.h @@ -11,19 +11,26 @@ #ifndef _CSOLVE_VPSC_H_ #define _CSOLVE_VPSC_H_ #ifdef __cplusplus +class vpsc::Variable; +class vpsc::Constraint; +class vpsc::Solver; +class vpsc::IncSolver; +using namespace vpsc; extern "C" { -#endif +#else typedef struct Variable Variable; +typedef struct Constraint Constraint; +typedef struct Solver Solver; +typedef struct IncSolver IncSolver; +#endif Variable* newVariable(int id, double desiredPos, double weight); void setVariableDesiredPos(Variable *, double desiredPos); double getVariablePos(Variable*); -typedef struct Constraint Constraint; Constraint* newConstraint(Variable* left, Variable* right, double gap); -typedef struct VPSC VPSC; -VPSC* newVPSC(int n, Variable* vs[], int m, Constraint* cs[]); -void deleteVPSC(VPSC*); +Solver* newSolver(int n, Variable* vs[], int m, Constraint* cs[]); +void deleteSolver(Solver*); void deleteConstraint(Constraint*); void deleteVariable(Variable*); Constraint** newConstraints(int m); @@ -42,12 +49,11 @@ int genXConstraints(int n, boxf[], Variable** vs, Constraint*** cs, int transitiveClosure); int genYConstraints(int n, boxf[], Variable** vs, Constraint*** cs); -void satisfyVPSC(VPSC*); -void solveVPSC(VPSC*); -typedef struct IncVPSC IncVPSC; -VPSC* newIncVPSC(int n, Variable* vs[], int m, Constraint* cs[]); -void splitIncVPSC(IncVPSC*); -int getSplitCnt(IncVPSC *vpsc); +void satisfyVPSC(Solver*); +void solveVPSC(Solver*); +Solver* newIncSolver(int n, Variable* vs[], int m, Constraint* cs[]); +void splitIncSolver(IncSolver*); +int getSplitCnt(IncSolver *vpsc); #ifdef __cplusplus } #endif diff --git a/src/libvpsc/generate-constraints.cpp b/src/libvpsc/generate-constraints.cpp index 312ad960b..3b69e7968 100644 --- a/src/libvpsc/generate-constraints.cpp +++ b/src/libvpsc/generate-constraints.cpp @@ -20,10 +20,12 @@ using std::set; using std::vector; +namespace vpsc { std::ostream& operator <<(std::ostream &os, const Rectangle &r) { os << "{"< +namespace vpsc { class Rectangle { friend std::ostream& operator <<(std::ostream &os, const Rectangle &r); public: @@ -74,5 +75,6 @@ class Constraint; 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/libvpsc/remove_rectangle_overlap.cpp b/src/libvpsc/remove_rectangle_overlap.cpp index 6f6ace03a..78df24b22 100644 --- a/src/libvpsc/remove_rectangle_overlap.cpp +++ b/src/libvpsc/remove_rectangle_overlap.cpp @@ -24,6 +24,7 @@ using std::endl; #endif #define EXTRA_GAP 0.0001 +using namespace vpsc; double Rectangle::xBorder=0; double Rectangle::yBorder=0; @@ -55,7 +56,7 @@ void removeRectangleOverlap(unsigned n, Rectangle *rs[], double xBorder, double for(int i=0;idesiredPosition; } - VPSC vpsc_x(n,vs,m,cs); + Solver vpsc_x(n,vs,m,cs); #ifdef RECTANGLE_OVERLAP_LOGGING ofstream f(LOGFILE,ios::app); f<<"Calling VPSC: Horizontal pass 1"< #ifdef RECTANGLE_OVERLAP_LOGGING #include -using std::ios; -using std::ofstream; -using std::endl; #endif +#include + +using namespace std; -using std::ostringstream; -using std::list; -using std::set; +namespace vpsc { static const double ZERO_UPPERBOUND=-0.0000001; -IncVPSC::IncVPSC(const unsigned n, Variable* const vs[], const unsigned m, Constraint *cs[]) - : VPSC(n,vs,m,cs) { +IncSolver::IncSolver(const unsigned n, Variable* const vs[], const unsigned m, Constraint *cs[]) + : Solver(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* const vs[], const unsigned m, Constraint *cs[]) : m(m), cs(cs), n(n), vs(vs) { +Solver::Solver(const unsigned n, Variable* const vs[], const unsigned m, Constraint *cs[]) : m(m), cs(cs), n(n), vs(vs) { bs=new Blocks(n, vs); #ifdef RECTANGLE_OVERLAP_LOGGING printBlocks(); - assert(!constraintGraphIsCyclic(n,vs)); + //assert(!constraintGraphIsCyclic(n,vs)); #endif } -VPSC::~VPSC() { +Solver::~Solver() { delete bs; } // useful in debugging -void VPSC::printBlocks() { +void Solver::printBlocks() { #ifdef RECTANGLE_OVERLAP_LOGGING ofstream f(LOGFILE,ios::app); for(set::iterator i=bs->begin();i!=bs->end();++i) { @@ -71,7 +69,7 @@ void VPSC::printBlocks() { * first) fixing the position of variables inside blocks relative to one * another so that constraints internal to the block are satisfied. */ -void VPSC::satisfy() { +void Solver::satisfy() { list *vs=bs->totalOrder(); for(list::iterator i=vs->begin();i!=vs->end();++i) { Variable *v=*i; @@ -93,7 +91,7 @@ void VPSC::satisfy() { delete vs; } -void VPSC::refine() { +void Solver::refine() { bool solved=false; // Solve shouldn't loop indefinately // ... but just to make sure we limit the number of iterations @@ -137,12 +135,12 @@ void VPSC::refine() { * refinement is possible by splitting the block. This is done repeatedly * until no further improvement is possible. */ -void VPSC::solve() { +void Solver::solve() { satisfy(); refine(); } -void IncVPSC::solve() { +void IncSolver::solve() { #ifdef RECTANGLE_OVERLAP_LOGGING ofstream f(LOGFILE,ios::app); f<<"solve_inc()..."<merge(rb,v); } else { + if(lb->isActiveDirectedPathBetween(v->right,v->left)) { + // cycle found, relax the violated, cyclic constraint + v->gap = v->slack(); + continue; + } if(splitCtr++>10000) { throw "Cycle Error!"; } @@ -215,7 +218,7 @@ void IncVPSC::satisfy() { printBlocks(); #endif } -void IncVPSC::moveBlocks() { +void IncSolver::moveBlocks() { #ifdef RECTANGLE_OVERLAP_LOGGING ofstream f(LOGFILE,ios::app); f<<"moveBlocks()..."< -using std::map; -using std::vector; struct node { set in; set out; }; // useful in debugging - cycles would be BAD -bool VPSC::constraintGraphIsCyclic(const unsigned n, Variable *vs[]) { +bool Solver::constraintGraphIsCyclic(const unsigned n, Variable* const vs[]) { map varmap; vector graph; for(unsigned i=0;i bmap; vector graph; for(set::const_iterator i=bs->begin();i!=bs->end();++i) { @@ -414,4 +414,4 @@ bool VPSC::blockGraphIsCyclic() { } return false; } - +} diff --git a/src/libvpsc/solve_VPSC.h b/src/libvpsc/solve_VPSC.h index 4cd5559d6..0f919a22a 100644 --- a/src/libvpsc/solve_VPSC.h +++ b/src/libvpsc/solve_VPSC.h @@ -21,6 +21,8 @@ #define SEEN_REMOVEOVERLAP_SOLVE_VPSC_H #include + +namespace vpsc { class Variable; class Constraint; class Blocks; @@ -28,13 +30,13 @@ class Blocks; /** * Variable Placement with Separation Constraints problem instance */ -class VPSC { +class Solver { public: virtual void satisfy(); virtual void solve(); - VPSC(const unsigned n, Variable* const vs[], const unsigned m, Constraint *cs[]); - virtual ~VPSC(); + Solver(const unsigned n, Variable* const vs[], const unsigned m, Constraint *cs[]); + virtual ~Solver(); Constraint** getConstraints(unsigned &m) { m=this->m; return cs; } const Variable* const * getVariables(unsigned &n) { n=this->n; return vs; } protected: @@ -46,21 +48,22 @@ protected: void printBlocks(); private: void refine(); - bool constraintGraphIsCyclic(const unsigned n, Variable *vs[]); + bool constraintGraphIsCyclic(const unsigned n, Variable* const vs[]); bool blockGraphIsCyclic(); }; -class IncVPSC : public VPSC { +class IncSolver : public Solver { public: unsigned splitCnt; void satisfy(); void solve(); void moveBlocks(); void splitBlocks(); - IncVPSC(const unsigned n, Variable* const vs[], const unsigned m, Constraint *cs[]); + IncSolver(const unsigned n, Variable* const vs[], const unsigned m, Constraint *cs[]); private: typedef std::vector ConstraintList; ConstraintList inactive; Constraint* mostViolated(ConstraintList &l); }; +} #endif // SEEN_REMOVEOVERLAP_SOLVE_VPSC_H diff --git a/src/libvpsc/variable.cpp b/src/libvpsc/variable.cpp index 1890f788e..19dc0746a 100644 --- a/src/libvpsc/variable.cpp +++ b/src/libvpsc/variable.cpp @@ -8,8 +8,9 @@ * Released under GNU LGPL. Read the file 'COPYING' for more information. */ #include "variable.h" +namespace vpsc { std::ostream& operator <<(std::ostream &os, const Variable &v) { os << "(" << v.id << "=" << v.position() << ")"; return os; } - +} diff --git a/src/libvpsc/variable.h b/src/libvpsc/variable.h index b1ab66c95..d2c689723 100644 --- a/src/libvpsc/variable.h +++ b/src/libvpsc/variable.h @@ -12,10 +12,11 @@ #include #include -class Block; -class Constraint; #include "block.h" +namespace vpsc { + +class Constraint; typedef std::vector Constraints; class Variable { @@ -48,4 +49,5 @@ public: out.clear(); } }; +} #endif // SEEN_REMOVEOVERLAP_VARIABLE_H -- cgit v1.2.3