Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
vpsc.h
Go to the documentation of this file.
1/*
2 * vim: ts=4 sw=4 et tw=0 wm=0
3 *
4 * libavoid - Fast, Incremental, Object-avoiding Line Router
5 *
6 * Copyright (C) 2005-2014 Monash University
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 * See the file LICENSE.LGPL distributed with the library.
13 *
14 * Licensees holding a valid commercial license may use this file in
15 * accordance with the commercial license agreement provided with the
16 * library.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 *
22 * Author(s): Tim Dwyer
23 * Michael Wybrow
24 *
25 * --------------
26 *
27 * This file contains a slightly modified version of IncSolver() from libvpsc:
28 * A solver for the problem of Variable Placement with Separation Constraints.
29 * It has the following changes from the Adaptagrams VPSC version:
30 * - The required VPSC code has been consolidated into a single file.
31 * - Unnecessary code (like Solver) has been removed.
32 * - The PairingHeap code has been replaced by a STL priority_queue.
33 *
34 * Modifications: Michael Wybrow
35 *
36*/
37
38#ifndef LIBAVOID_VPSC_H
39#define LIBAVOID_VPSC_H
40
41
42#ifdef USELIBVPSC
43
44// By default, libavoid will use it's own version of VPSC defined in this file.
45//
46// Alternatively, you can directly use IncSolver from libvpsc. This
47// introduces a dependency on libvpsc but it can be preferable in cases
48// where you are building all of Adaptagrams together and want to work
49// with a set of CompoundConstraints or other classes built upon the
50// base libvpsc Constraint classes.
51
52// Include necessary headers from libvpsc.
53#include "libvpsc/variable.h"
54#include "libvpsc/constraint.h"
55#include "libvpsc/rectangle.h"
56#include "libvpsc/solve_VPSC.h"
57
58// Use the libvpsc versions of things needed by libavoid.
59using vpsc::Variable;
60using vpsc::Variables;
63using vpsc::IncSolver;
65
66#else
67
68#include <vector>
69#include <list>
70#include <set>
71#include <queue>
72#include <iostream>
73#include <cfloat>
74
75#include "libavoid/assertions.h"
76
77namespace Avoid {
78
79class Variable;
80class Constraint;
81class Blocks;
82typedef std::vector<Variable*> Variables;
83typedef std::vector<Constraint*> Constraints;
85public:
86 bool operator() (Constraint *const &l, Constraint *const &r) const;
87};
89 PositionStats() : scale(0), AB(0), AD(0), A2(0) {}
90 void addVariable(Variable* const v);
91 double scale;
92 double AB;
93 double AD;
94 double A2;
95};
96
97typedef std::priority_queue<Constraint*,std::vector<Constraint*>,
99
100class Block
101{
102 typedef Variables::iterator Vit;
103 typedef Constraints::iterator Cit;
104 typedef Constraints::const_iterator Cit_const;
105
106 friend std::ostream& operator <<(std::ostream &os,const Block &b);
107public:
109 double posn;
110 //double weight;
111 //double wposn;
113 Block(Blocks *blocks, Variable* const v=nullptr);
114 ~Block(void);
116 Constraint* findMinLMBetween(Variable* const lv, Variable* const rv);
122 void merge(Block *b, Constraint *c, double dist);
124 void mergeIn(Block *b);
125 void mergeOut(Block *b);
126 void split(Block *&l, Block *&r, Constraint *c);
127 Constraint* splitBetween(Variable* vl, Variable* vr, Block* &lb, Block* &rb);
128 void setUpInConstraints();
129 void setUpOutConstraints();
130 double cost();
135 bool getActivePathBetween(Constraints& path, Variable const* u,
136 Variable const* v, Variable const *w) const;
138 Variable const* u, Variable const* v) const;
139 bool getActiveDirectedPathBetween(Constraints& path, Variable const * u, Variable const * v) const;
140private:
141 typedef enum {NONE, LEFT, RIGHT} Direction;
142 typedef std::pair<double, Constraint*> Pair;
143 void reset_active_lm(Variable* const v, Variable* const u);
144 void list_active(Variable* const v, Variable* const u);
145 double compute_dfdv(Variable* const v, Variable* const u);
146 double compute_dfdv(Variable* const v, Variable* const u, Constraint *&min_lm);
147 bool split_path(Variable*, Variable* const, Variable* const,
148 Constraint* &min_lm, bool desperation);
149 bool canFollowLeft(Constraint const* c, Variable const* last) const;
150 bool canFollowRight(Constraint const* c, Variable const* last) const;
151 void populateSplitBlock(Block *b, Variable* v, Variable const* u);
152 void addVariable(Variable* v);
153 void setUpConstraintHeap(Heap* &h,bool in);
154
155 // Parent container, that holds the blockTimeCtr.
157};
158
159
160class Constraint;
161typedef std::vector<Constraint*> Constraints;
163{
164 friend std::ostream& operator <<(std::ostream &os, const Variable &v);
165 friend class Block;
166 friend class Constraint;
167 friend class IncSolver;
168public:
169 int id; // useful in log files
172 double weight; // how much the variable wants to
173 // be at it's desired position
174 double scale; // translates variable to another space
175 double offset;
181 inline Variable(const int id, const double desiredPos=-1.0,
182 const double weight=1.0, const double scale=1.0)
183 : id(id)
184 , desiredPosition(desiredPos)
185 , weight(weight)
186 , scale(scale)
187 , offset(0)
188 , block(nullptr)
189 , visited(false)
190 , fixedDesiredPosition(false)
191 {
192 }
193 double dfdv(void) const {
194 return 2. * weight * ( position() - desiredPosition );
195 }
196private:
197 inline double position(void) const {
198 return (block->ps.scale*block->posn+offset)/scale;
199 }
200 inline double unscaledPosition(void) const {
201 COLA_ASSERT(block->ps.scale == 1);
202 COLA_ASSERT(scale == 1);
203 return block->posn + offset;
204 }
205};
206
207
209{
210public:
211 Constraint(Variable *left, Variable *right, double gap, bool equality=false);
212 ~Constraint();
213 inline double slack(void) const
214 {
215 if (unsatisfiable)
216 {
217 return DBL_MAX;
218 }
219 if (needsScaling)
220 {
221 return right->scale * right->position() - gap -
222 left->scale * left->position();
223 }
224 COLA_ASSERT(left->scale == 1);
225 COLA_ASSERT(right->scale == 1);
227 }
228 std::string toString(void) const;
229
230 friend std::ostream& operator <<(std::ostream &os,const Constraint &c);
233 double gap;
234 double lm;
236 bool active;
237 const bool equality;
240 void *creator;
241};
242/*
243 * A block structure defined over the variables such that each block contains
244 * 1 or more variables, with the invariant that all constraints inside a block
245 * are satisfied by keeping the variables fixed relative to one another
246 */
248{
249public:
251 ~Blocks(void);
252 void mergeLeft(Block *r);
253 void mergeRight(Block *l);
254 void split(Block *b, Block *&l, Block *&r, Constraint *c);
255 std::list<Variable*> *totalOrder();
256 void cleanup();
257 double cost();
258
259 size_t size() const;
260 Block *at(size_t index) const;
261 void insert(Block *block);
262
264private:
265 void dfsVisit(Variable *v, std::list<Variable*> *order);
266 void removeBlock(Block *doomed);
267
268 std::vector<Block *> m_blocks;
269 Variables const &vs;
270 size_t nvs;
271};
272
273inline size_t Blocks::size() const
274{
275 return m_blocks.size();
276}
277
278inline Block *Blocks::at(size_t index) const
279{
280 return m_blocks[index];
281}
282
283inline void Blocks::insert(Block *block)
284{
285 m_blocks.push_back(block);
286}
287
295/*
296 * Variable Placement with Separation Constraints problem instance
297 */
299public:
300 unsigned splitCnt;
301 bool satisfy();
302 bool solve();
303 void moveBlocks();
304 void splitBlocks();
305 IncSolver(Variables const &vs, Constraints const &cs);
306
307 ~IncSolver();
308 void addConstraint(Constraint *constraint);
309 Variables const & getVariables() { return vs; }
310protected:
312 size_t m;
314 size_t n;
315 Variables const &vs;
317
318 void printBlocks();
319 void copyResult();
320private:
321 bool constraintGraphIsCyclic(const unsigned n, Variable* const vs[]);
322 bool blockGraphIsCyclic();
326};
327
329{
330 template <typename T>
331 void operator()(T *ptr){ delete ptr;}
332};
333
335 Variables const &vars, Constraints const &constraints);
336
337}
338
339#endif // ! USELIBVPSC
340
341#endif // AVOID_VPSC_H
void split(Block *&l, Block *&r, Constraint *c)
Definition vpsc.cpp:1259
double posn
Definition vpsc.h:109
Constraint * splitBetween(Variable *vl, Variable *vr, Block *&lb, Block *&rb)
Definition vpsc.cpp:1237
Blocks * blocks
Definition vpsc.h:156
bool canFollowLeft(Constraint const *c, Variable const *last) const
Definition vpsc.cpp:934
bool deleted
Definition vpsc.h:131
Constraint * findMinInConstraint()
Definition vpsc.cpp:864
friend std::ostream & operator<<(std::ostream &os, const Block &b)
Definition vpsc.cpp:1281
bool canFollowRight(Constraint const *c, Variable const *last) const
Definition vpsc.cpp:937
bool getActivePathBetween(Constraints &path, Variable const *u, Variable const *v, Variable const *w) const
Definition vpsc.cpp:1183
void setUpInConstraints()
Definition vpsc.cpp:758
void reset_active_lm(Variable *const v, Variable *const u)
Definition vpsc.cpp:1093
long timeStamp
Definition vpsc.h:132
std::pair< double, Constraint * > Pair
Definition vpsc.h:142
~Block(void)
Definition vpsc.cpp:752
void list_active(Variable *const v, Variable *const u)
Definition vpsc.cpp:1109
Heap * out
Definition vpsc.h:134
void mergeOut(Block *b)
Definition vpsc.cpp:855
void merge(Block *b, Constraint *c, double dist)
Definition vpsc.cpp:807
Variables * vars
Definition vpsc.h:108
double cost()
Definition vpsc.cpp:1273
Variables::iterator Vit
Definition vpsc.h:102
Constraint * findMinLMBetween(Variable *const lv, Variable *const rv)
Definition vpsc.cpp:1146
void populateSplitBlock(Block *b, Variable *v, Variable const *u)
Definition vpsc.cpp:1169
void updateWeightedPosition()
Definition vpsc.cpp:738
Constraints::iterator Cit
Definition vpsc.h:103
void mergeIn(Block *b)
Definition vpsc.cpp:838
bool getActiveDirectedPathBetween(Constraints &path, Variable const *u, Variable const *v) const
Definition vpsc.cpp:1218
Constraints::const_iterator Cit_const
Definition vpsc.h:104
bool isActiveDirectedPathBetween(Variable const *u, Variable const *v) const
Definition vpsc.cpp:1207
void deleteMinInConstraint()
Definition vpsc.cpp:923
void setUpOutConstraints()
Definition vpsc.cpp:761
bool split_path(Variable *, Variable *const, Variable *const, Constraint *&min_lm, bool desperation)
Definition vpsc.cpp:995
Heap * in
Definition vpsc.h:133
Constraint * findMinOutConstraint()
Definition vpsc.cpp:913
double compute_dfdv(Variable *const v, Variable *const u)
Definition vpsc.cpp:967
void addVariable(Variable *v)
Definition vpsc.cpp:704
void deleteMinOutConstraint()
Definition vpsc.cpp:931
void setUpConstraintHeap(Heap *&h, bool in)
Definition vpsc.cpp:764
PositionStats ps
Definition vpsc.h:112
Constraint * findMinLM()
Definition vpsc.cpp:1135
long blockTimeCtr
Definition vpsc.h:263
size_t size() const
Definition vpsc.h:273
void dfsVisit(Variable *v, std::list< Variable * > *order)
Definition vpsc.cpp:527
void mergeLeft(Block *r)
Definition vpsc.cpp:546
void cleanup()
Definition vpsc.cpp:614
Blocks(Variables const &vs)
void split(Block *b, Block *&l, Block *&r, Constraint *c)
Definition vpsc.cpp:651
~Blocks(void)
Definition vpsc.cpp:498
double cost()
Definition vpsc.cpp:678
std::vector< Block * > m_blocks
Definition vpsc.h:268
void mergeRight(Block *l)
Definition vpsc.cpp:580
size_t nvs
Definition vpsc.h:270
Variables const & vs
Definition vpsc.h:269
void removeBlock(Block *doomed)
Definition vpsc.cpp:608
std::list< Variable * > * totalOrder()
Definition vpsc.cpp:513
void insert(Block *block)
Definition vpsc.h:283
Block * at(size_t index) const
Definition vpsc.h:278
bool operator()(Constraint *const &l, Constraint *const &r) const
Definition vpsc.cpp:1366
Variable * right
Definition vpsc.h:232
bool needsScaling
Definition vpsc.h:239
double slack(void) const
Definition vpsc.h:213
Variable * left
Definition vpsc.h:231
bool unsatisfiable
Definition vpsc.h:238
std::string toString(void) const
Definition vpsc.cpp:1323
const bool equality
Definition vpsc.h:237
friend std::ostream & operator<<(std::ostream &os, const Constraint &c)
Definition vpsc.cpp:1340
void * creator
Definition vpsc.h:240
void moveBlocks()
Definition vpsc.cpp:367
void copyResult()
Definition vpsc.cpp:124
unsigned splitCnt
Definition vpsc.h:300
Constraints violated
Definition vpsc.h:324
void addConstraint(Constraint *constraint)
Definition vpsc.cpp:96
bool needsScaling
Definition vpsc.h:316
bool constraintGraphIsCyclic(const unsigned n, Variable *const vs[])
Definition vpsc.cpp:137
Variables const & getVariables()
Definition vpsc.h:309
bool satisfy()
Definition vpsc.cpp:274
Variables const & vs
Definition vpsc.h:315
Constraints const & cs
Definition vpsc.h:313
void printBlocks()
Definition vpsc.cpp:107
bool blockGraphIsCyclic()
Definition vpsc.cpp:184
Constraint * mostViolated(Constraints &l)
Definition vpsc.cpp:431
Constraints inactive
Definition vpsc.h:323
void splitBlocks()
Definition vpsc.cpp:383
Blocks * bs
Definition vpsc.h:311
double dfdv(void) const
Definition vpsc.h:193
double desiredPosition
Definition vpsc.h:170
double scale
Definition vpsc.h:174
bool fixedDesiredPosition
Definition vpsc.h:178
Variable(const int id, const double desiredPos=-1.0, const double weight=1.0, const double scale=1.0)
Definition vpsc.h:181
double finalPosition
Definition vpsc.h:171
Constraints in
Definition vpsc.h:179
friend std::ostream & operator<<(std::ostream &os, const Variable &v)
Definition vpsc.cpp:1389
double offset
Definition vpsc.h:175
Constraints out
Definition vpsc.h:180
double unscaledPosition(void) const
Definition vpsc.h:200
bool visited
Definition vpsc.h:177
Block * block
Definition vpsc.h:176
double weight
Definition vpsc.h:172
double position(void) const
Definition vpsc.h:197
A constraint determines a minimum or exact spacing required between two Variable objects.
Definition constraint.h:45
Incremental solver for Variable Placement with Separation Constraints problem instance.
Definition solve_VPSC.h:105
A variable is comprised of an ideal position, final position and a weight.
Definition variable.h:45
const double w
Definition conic-4.cpp:19
double c[8][4]
const unsigned order
libavoid: Object-avoiding orthogonal and polyline connector routing library.
Constraints constraintsRemovingRedundantEqualities(Variables const &vars, Constraints const &constraints)
Definition vpsc.cpp:1468
std::vector< Variable * > Variables
Definition vpsc.h:82
std::vector< Constraint * > Constraints
Definition vpsc.h:83
std::priority_queue< Constraint *, std::vector< Constraint * >, CompareConstraints > Heap
Definition vpsc.h:98
double dist(const Point &a, const Point &b)
Definition geometry.cpp:310
std::vector< vpsc::Variable * > Variables
A vector of pointers to Variable objects.
std::vector< vpsc::Constraint * > Constraints
A vector of pointers to Constraint objects.
void addVariable(Variable *const v)
Definition vpsc.cpp:688
UnsatisfiedConstraint(Constraint &c)
Definition vpsc.h:292
void operator()(T *ptr)
Definition vpsc.h:331
int index