Вы находитесь на странице: 1из 30

Lees O(n2 log n) Visibility Graph Algorithm Implementation and Analysis

Dave Coleman
Department of Computer Science (Dated: May 2, 2012)

I.

ABSTRACT

Visibility graphs have many applications, including nding the shortest path, robotic motion planning and the art-gallery problem. The rst non-trivial algorithm developed for nding the visibility graph runs in O(n2 log n) and is presented in this paper. Its correctness, space, and time usage are mathematically analyzed. Because faster algorithms to solve this problem have been discovered, this paper is somewhat original in its analysis and implementation details of an otherwise forgotten algorithm.

II. A.

INTRODUCTION Visibility Graph

Visibility is an important property in computational geometry and is used in many dierent types of problems, structures and algorithms [8]. One of the most basic structures is the visibility graph, where an input graph G describes a set of geometric primitives in an d-dimensional space, and the output visibility graph Gv describes the visibility between every vertex and every other vertex in G. Here, we dene visibility as the ability to run a straight line between two vertices without crossing any other edge in the input graph G. In this way, two visible vertexes are said to be unobstructed by any obstacle, and a line is drawn between them in the output Gv . An example visibility graph in d = 2 dimensions Euclidean space is shown in Figure 1. The set of geometric primitives inG can consist of a variety of dierent types of shapes: rectilinear, circular, line segments, convex polygons or, most generally, simple polygons. Many dierent algorithms have been developed based on the assumption of which types of geometric primitives are allowable. In this paper we will focus on simple non-intersecting line-segments, so as to simplify our proofs and analysis. Very little modication would be required to expand the problem space to general polygons. The layout of the geometric primitives is another variFIG. 1: Top: An input graph G consisting of a set of simple line segments. Bottom: a generated visibility graph Gv describing all possible non-obstructed connections between each vertex.

david.t.coleman@colorado.edu;

www.davetcoleman.com

ation between computational geometry papers. In some, visibility within a simple polygon is the only problem space, but more often there exists obstacles within the space, also referred to as holes or islands. Another variation of the visibility graph for all points is nding the visibility tree for just one point, which is simply a subproblem of the visibility graph for all points.

2
B. Applications

Visibility graphs are most often thought of for use in Euclidean shortest-path problems, were a start point s and end point t are given and the task is to nd the optimal continuous path through the obstacle space without violating physical constraints. This application exploits the fact that the shortest paths are found on the arcs of the visibility graph. Once the visibility graph has been constructed, the shortest path problem can be trivially solved using well known algorithms such as Dijkstras [6], A* search[5], or Floyd-Warshall [3] algorithms. Robotic motion planning is a common sub problem of the shortest path problem, as demonstrated in Lozano-Perez and Wesleys 1979 collision-free paths algorithm [11]. One of the most famous examples of visibility graphs used in robotic motion planning is Shakey the Robot [11]. However, the application of visibility graphs realistically limits the workspace to two dimensions and is generally computationally intractable for modern real-world robotics problems. Sampling-based approaches are considered the current state of the art and, although unable to determine that no path exists, have a probability of failure that decreases to zero as more computational time is spent [7]. Additional applications of visibility graphs include nding the minimum dominating set to help solve the art gallery problem and in solving pursuer-evader problems [10]. Finally, visibility graphs can be used to optimize radio antenna placement, urban planning and architectural design [1].

average, or handle sparse graphs more eciently. One of the last papers published on visibility graphs during this time period achieved O(|e| + n log n) time bounds, which are output-sensitive algorithms optimal for graphs of a certain minimum density threshold [4].

III. A.

METHODS

Description of the Algorithm

Lees O(n2 log n) algorithm computes the visibility graph Gv from G(V, E ) by computing the visibility graph of a single vertex n times. For each vertex vi V , the visibility of all other vertices is calculated by 1) sorting all surrounding vertices in angular order from some starting scan line, 2) using a rotating plane sweep technique to visit each vertex in angular order and 3) keeping track of the distance of each surrounding line segment on the scan line in a sorted data structure. The following details these 3 procedures: For each vi V a visibility tree is generated describing the visibility of all other points vj V vi with respect to vi . Each visibility tree is created by setting vi to be the center vertex c. A starting scan line vector s is initialized for each c, with the origin of the vector at c. Its direction is irrelevant for the algorithm but in this paper and implementation s will be assumed to be the horizontal unit vector i pointing straight and to the right from c, i.e. s = i = [1, 0]. From scan line s = i we calculate the counter clockwise angle i = angle(scvi , i) for every vertex vi V c. The angles are inserted to an optimally sorted data structure A from smallest to largest.

C.

History

The naive approach to computing the visibility of a graph runs in O(n3 ) times. The rst non-trivial solution to this problem was developed by D.T. Lee in his 1978 Ph.D. dissertation that ran in O(n2 log n) time [9]. The solution is included at the end of his thesis as somewhat of a side thought and it has since then received very little attention in the computational geometry eld. Only available upon email request, the typed report includes hand-written edits and drawings. This is the algorithm that will be analyzed in this paper. In the 1980s a large number of O(n2 ) visibility graph papers were published, most of which entailed a topological sort of the vertex pairs. E. Welzl in particular described this technique using an arrangement of the dual of the vertices that required O(n2 ) working space [13]. The working storage of the topological sweep was later improved to O(n) by Edelsbrunner and Guibas [2]. Further improvements included handling dynamic updates of the workspace, using less running time on
FIG. 2: Example of an initialized edge list with all edges that intersect scan line s. Image courtesy of [8]

A second optimally sorted data structure Es is initialized containing all the line segments li E that intersect scan line s at the start of the algorithm. This operation requires |E | checks, calculating if s and line segment li intersect. The line segments that are found

3 to intersect are inserted into Es with their keys being the distance from c to the intersection point v[i,i1] such that the root of the sorted data structure always contains the edge closest to c. We can intuitively see that this root edge is the only edge visible from c at this scan line instance. Figure 2 depicts an initialized scan list, though in this example vector s is not horizontal. After the initialization phase the algorithm visits every vertex vi in order of i in A. The scan line does not have to actually visit every angle in the circle, but only those i where a vertex vi intersects s. For each vi scanned, the algorithm decides if its corresponding line segment lvi ,vi +1 is the rst or last vertex seen of its corresponding li . If it is the rst vertex seen, then lvi ,vi +1 is added to Es and is considered open. If it is the second vertex seen, or if it was initialized as open on s0 , then it is removed from Es and is considered closed. For each visited vi , a check is made to see if vi is the root of Es , signifying that vi is the closest vertex to c with respect to s. If vi has this property, then vi is considered visible and is added to the visibility graph Gv ; otherwise it is obscured by some other edge appearing before it, with respect to c, and is ignored. In this way every visible vertex with respect to c is found and a visibility tree is generated for some vi . This process is repeated n times to build a complete visibility graph.

Finally, the sweeping for-loop begins its check of every vi V c points. At each vertex a line is either inserted into or removed from Es once, requiring again O(log n) time for each operation. Thus the total running time for this step is also (n 1) log n = O(n log n). With these three steps and the outer forloop combined, our summed running time is O(n (.5n + n + n 1) log n), which asymptotically reduces to simply O(n2 log n).

C.

Space Requirements

The space requirements of Lees algorithm is analyzed in the following. The input graph G requires O(V + E ) space, but we will assume that the input graph is not included in our space requirements. Two optimum sorting data structures are needed in the algorithm - A and Es . D.T. Lees original paper suggested an AVL tree be used; in our implementation we have used a skip list. Regardless, both use O(n) space, totaling 2O(n). Because each i is inserted into A once, n = |V | for datastructure A. In the worse case all edges are intersected by s at the same time, making Es have size n = |E | = .5|V |. No other memory is used in the algorithm, so the total overall space requirements, not including the input graph, is O(1.5|V |), which is equivalent to simply O(n).

B.

Runtime D. Analysis of Correctness

The asymptotic runtime of Lees algorithm is analyzed in the following. The algorithm has four for-loops as well as the operations of the optimal sorting data structure. An outer for-loop iterates once through n = |V | = 2|E | points, nding the visibility tree for every point. Within the outer for loop, each end point pair for every |E | line segments are inserted into the optimal sorting data structure A. Insert, delete, and nd all take O(log n) time using a probabilistic structure such as a skip list, or balance binary search tree, such as an AVL tree. Thus, the insertion time for A takes 2|E | log n = O(n log n). Next, the sweep line edge list Es is initialized by checking all |E | edges in G for intersection with s = i. The edge list Es uses the same data structure as A, and thus all insertions take O(log n) time. In the worse case, all |E | edges intersect s at some i , so the total runtime for this step is O(|E | log |E |). There are twice as many vertices as edges, and so because |E | < |V |, this runtime is asymptotically overshadowed by the previous step and can be ignored.

We begin our proof of correctness of Lees O(n2 log n) algorithm by dening the components of the algorithm. Denition 1. A visibility graph Gv = (V, Ev ) is the set of all vertices V in input graph G, and the set of edges Ev which connects two vertices vi , vj V without intersecting any obstacles, for all vi , vj V . We assume that two endpoints i and j of the same line are also considered visible. We restrict our obstacle set to the |E | disjoint line segments, in any direction. Denition 2. The line sweep vector s is a vector with its origin at some point c V that rotates starting from direction i a full 2 radians. Denition 3. A line segment li is an obstacle in the 2 dimensional problem space dened between vertices vi and vi1 . Denition 4. The set Es contains all li that intersect with s originating at point c, ordered in decreasing Euclidean distance from c to li .

4 The above denitions we will now begin to prove the algorithms correctness by observing the existence of optimal substructure of the visibility graph: Lemma 1. The visibility tree containing set of all edges Ei connecting a single point vi to all other visible points vj V vi , with respect to the single point vi , is a subsolution to nding the visibility graph of all points vj V in G. Proof. Assume the visibility tree Ei for some vi is generated correctly every time. For N = 1 points, by the just stated assumption no other endpoint vj of a line segment is visible from that N = 1 point that is not already in the set Ei=1 . For N = 2 points, following the same assumption, no point will be visible to those N = 2 points that is not already in the combined visibility tree set Ei=[1,2] . For N = |V | points, it follows that no point in V will be visible from any other point in V that is not already in the set Ei=1N . In this case our above denition of a visibility graph is satised and our N sub-solutions have resulted in correctly nding the visibility graph Gv for all points vj V . Lemma 1 assumed that the set of edges Ei dening a visibility tree, for some vertex i, was generated correctly every time. We now prove our algorithm for this subproblem. We begin by dening the assumptions of our scan line method: Lemma 2. No more than one obstacle is visible at any time from a center point c with respect to the direction of a scan line vector s at any angle in Euclidean space. Proof. A Euclidean vector is dened as a geometric object that has a direction and length (or magnitude), but it does not itself have a width, or at least the width could be considered innitely narrow. An innitely narrow segment of a directional vector could not be obstructed by more than n = 1 geometric element at a time because otherwise the combined width of n > 1 geometric elements would have to be innitely small. The combined width of two objects would be greater than innitely small. Therefore, because obstacles in our problem space are assumed to be line segments, our lemma stands.

With Lemma 2 and Corollary 1 we have proved the correctness of the results of scan line s at one i . We will now expand our proof to all 2 and our discretization method. Lemma 3. No change is made in the visibility of any line segment with respect to s except when s intersects an end point of some line segments. Proof. By contradiction. Assume the set Es correctly contains all line segments that intersect some vector s and assume s is at some a that does not intersect any end points vi V . The only way to change the visibility of a line segment at s would be to remove the rst line segment Es because this is the line segment closest to c. Suppose we removed this line segment, despite having no vi in intersection with s. Then there exists a li that intersects s and Es violates denition 4 dening what Es must contain, and by contradiction this lemma is proved.

Corollary 2. In the non-discrete angular space between 0 and 2 , our scan line need only check |V | 1 discrete steps where i = angle(scvi , i),. Proof. Following from Lemma 3, no changes in visibility occur with respect to the rotation of s around c except when s intersects an end point vi , and there are only |V | 1 endpoints around c so it follows that only |V | 1 angles of i need to be checked. The utility of a scan line is now suciently proven by Lemma 3 and Corollary 2. The mechanism for tracking the removal and insertion of lines into Es is now proved: Lemma 4. A line segment li with an end point vi in intersection with s must be added to the set Es if the opposite end point vi1 of li has not previously been visited (the line was closed). Otherwise, if it has been previously visited, li must be removed from the set Es (the line was open). Proof. Following the stated assumption that s rotates in a counter clockwise direction, and recalling that at initialization all li in intersection with s are added to Es and marked as open, it can be observed that Lemma 4 is required to maintain Denition 4, that Es must contain all line segments that intersect s. Using Lemmas 1 to 4 and Corollaries 1 and 2 the following theorem is supported: Theorem 1. Given a set of n disjoint line segments in the Euclidean plane, the visibility graph can be constructed correctly in O(n2 log n) time using the rotational sweep method in Lees algorithm.

Corollary 1. The intersection point of s and li Es with the minimum Euclidean distance to c is the only line segment visible. Proof. Although s may cross several li Es , by Lemma 2 we know only one point can have the visible property for a given s, and by the denition of visibility we know it must be the rst line segment it reaches. The rst line segment a vector crosses from some point c is the segment closest in Euclidean distance.

5
IV. A. RESULTS

Implementation

The O(n2 log n) algorithm was implemented in C++ and visualized/animated using the open source, cross-platform CImg graphics library. With the graphics library we were able to visually verify geometric results such as shown in Figure 3. The full source code is appended at the end of this paper and is available as an open source project online at https: //github.com/davetcoleman/visibility_graph

line s would visit and so it would be inserted into the skip list Es with the distance d1 from its rst endpoint to c. Next, the scan line would visit the rst endpoint of l2 and it would add l2 to Es with distance d2 . Thus, Es would have as its rst ordered line segment l1 , and for its seconds l2 . But by denition 4, Es should have as its rst line segment the segment closest to c, and at scan line s the closest intersecting line segment is now actually l2 . As it is now clear, in our current example the ordering of Es would be incorrect at location s unless there was some way to update the value of l1 to reect its distance from c with respect to i of s .

FIG. 3: Test input graph of 8 line segments (white) and the generated visibility graph of Ev lines (blue) FIG. 4: Line l1 originally was the closest point to c, but at scan line s line l2 covers l1 . This demonstrates the need for elements variable values in the skip list. B. Skip Lists

D.T. Lees original paper suggested an AVL tree data tree structure be used, but his paper was published before the invention of skip lists in 1989 by W. Pugh [12]. In this implementation we chose to use a skip list due to its average case performance and advantage in concurrent access and modications. However, a unique property of our algorithm required special modication to the skip list such that the key values of data already in the skip list are variable. That is to say, the value of each element in the skip list changes as the scan line rotates around some center c. The need for this property is motivated in Figure 4. In this example line l1 is the rst line segment that scan

This might seem like an impossible property of a skip list, but in fact there is an additional property that states that the ordering of the items in the skip list are guaranteed not to change, just the values. In other words, although l1 at angle i has an intersection with s that is a greater distance than that of l2 from c, the ordering of l1 in Es with respect to all other open line segments in Es would remain unchanged due to the assumption that no line segments can intersect in our problem space. Therefore, in implementing the actual visibility graph, each line segment was represented as an object that could quickly re-calculate its intersection with s and then distance to c. This was accomplished by caching the slope m and y-intercept b at the initialization of the

6 line object, as well as caching the resultant distance d from c for every i such that d is only calculated once for every thetai .

C.

Precision Errors

Another issue with our implementation was rounding errors that occurred when calculating the angles between two close points. This was especially problematic as we increased the number of line segments added to our nitely-sized graphics window. Sometimes two unique points would be added to the angle list A with the same angle because of rounding errors, and the result was that some points were mistakenly added as visible. Particularly problematic were perfectly horizontal and vertical lines. With vertical lines the slope m would tend to innity, but in this implementation it was faked with some very large number. In the same way, a horizontal line has a slope with an innitely small m, and this again suered from the limitations of our computer hardware.

FIG. 5: An example generated problem space for nx = ( (10n )1/2 )2 line segments, with randomly chosen shapes.

D.

Numerical Time Usage

To calculate the numerical time usage of this algorithm, the source code was modied to automatically generate a set of n line segments. To test the runtime with exponentially increasing problem space it was instrumented to generate approximately n = 10x line segments. However, to ensure a useful test set was generated without intersection, each line segment was constrained to a grid area. Within each line segments grid, padding was added to allow more visibility between grids. Additionally, 4 shapes were used inside the grids: a horizontal, vertical, diagonal increasing and diagonal decreasing line segment. Which of the 4 was chosen was decided at random, such that every test was run on a problem set with a high probability of being unique. Because of the gridded nature of the problem space, in reality only nx = ( (10n )1/2 )2 line segments were added. An example of an automatically generated problem space is shown in Figure 5. With this setup, the numerical time usage was measured by counting the number of atomic operations within both the algorithm and the skip lists. The algorithm was tested for n = 101 103.5 . At problem size n = 104 the algorithm crashed on both our laptop and on a node on the Janus super computer. This, however, is mostly due to some memory leaks that were problematic to patch. The results of the atomic operations measurements are shown in Figure 6. Our data showed performance that was very tightly bound to a run time of O(n2 log n). This

run time is both the worst- and average-case for this algorithm because all points are always added to A and E and all points are always visited to generate their individual visibility tree.

FIG. 6: Atomic operations of Lees visibility graph algorithm for increasing number of line segments n.

Further visual results of the algorithm running for n = 100 line segments is shown in Figure 7 and for n = 1000 line segments in Figure 8.

7 considered to use 3 atomic memory amounts. A memory counter was incremented for every new node created, and decremented for every node deleted. A secondary counter was used to track the maximum amount of memory used at any point in the algorithms progress. The results are shown in Figure 9. As expected, the memory usage was on the order of O(n).

FIG. 7: Generated visibility graph for n = 100 line segments.

FIG. 9: Measured space usage of Lees visibility graph algorithm. The upper and lower dotted line bounds are multiplied by constants of 3 and 7, respectively.

V.

CONCLUSIONS

FIG. 8: Generated visibility graph for n = 1000 line segments.

E.

Numerical Space Usage

There exists many additional optimization tweaks that could be applied to this algorithm. One such optimization is to limit the scan line rotation to only half the circle, from the observation that visibility between a pair is mutual. Other optimizations could be made in the geometric calculations such as studying the performance advantages between nding the distance using the line-of-sine method versus the intersection method and dealing with slopes of negative and positive innity. Lastly, the dynamic-valued skip list structure discussed in section IV. B. requires a large number of distance calculations at every rotation of the scan line, and could be reduced by only checking a vertices change in distance immediately around the skip lists chosen insertion point for a new line segment. While simple in explanation, it would be complicated in required modication to the skip list algorithm. In this paper we have explained, analyzed, proved and implemented D.T. Lees 1978 visibility graph algorithm. As explained in the introduction, faster algorithms have been developed that run on O(n2 ) time and other

The numerical space usage of this algorithm was measured by tracking the maximum number of nodes from both skip lists combined at any point in the algorithm. Here, we dene a node as a level in the skip list structure, such that a root with 3 levels is

8 optimizations have been discovered for special case problems where certain geometric tricks can be utilized. However, basic applications such as the shortest path planning problem with no more than order O(n3 ) line segments has been shown in this paper section to be feasible with this algorithm and in our experiments have generated visibility graphs in seconds.
Acknowledgments

This paper was written for Aaron Clausets Graduate Algorithms class at the University of Colorado Boulder.

[1] Burcin Cem Arabacioglu. Using fuzzy inference system for architectural space analysis. Appl. Soft Comput., 10(3):926937, June 2010. [2] Herbert Edelsbrunner and Leonidas J. Guibas. Topologically sweeping an arrangement. Journal of Computer and System Sciences, 38(1):165 194, 1989. [3] Robert W. Floyd. Algorithm 97: Shortest path. Commun. ACM, 5(6):345, June 1962. [4] Subir Kumar Ghosh and David M. Mount. An output sensitive algorithm for computing visibility graphs. In Proceedings of the 28th Annual Symposium on Foundations of Computer Science, SFCS 87, pages 1119, Washington, DC, USA, 1987. IEEE Computer Society. [5] P.E. Hart, N.J. Nilsson, and B. Raphael. A formal basis for the heuristic determination of minimum cost paths. Systems Science and Cybernetics, IEEE Transactions on, 4(2):100 107, july 1968. [6] Donald B. Johnson. A note on dijkstras shortest path algorithm. J. ACM, 20(3):385388, July 1973. [7] Sertac Karaman and Emilio Frazzoli. Sampling-based algorithms for optimal motion planning. Int. J. Rob. Res., 30(7):846894, June 2011.

[8] John Kitzinger and Computer Engineering. The visibility graph among polygonal obstacles: a comparison of algorithms, 2003. [9] Der-Tsai Lee. Proximity and reachability in the plane. PhD thesis, Champaign, IL, USA, 1978. AAI7913526. [10] Jae-Ha Lee, Sung Yong Shin, and Kyung-Yong Chwa. Visibility-based pursuit-evasion in a polygonal room with a door. In Proceedings of the fteenth annual symposium on Computational geometry, SCG 99, pages 281290, New York, NY, USA, 1999. ACM. [11] Tom as Lozano-P erez and Michael A. Wesley. An algorithm for planning collision-free paths among polyhedral obstacles. Commun. ACM, 22(10):560570, October 1979. [12] William Pugh. Skip lists: a probabilistic alternative to balanced trees. Commun. ACM, 33(6):668676, June 1990. [13] Emo Welzl. Constructing the visibility graph for n-line segments in o(n2) time. Information Processing Letters, 20(4):167 171, 1985.

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

C++ Code For Visibility Graph Implementation Index: vgraph.cpp skiplist.h line.h line.cpp point.h point.cpp geometry.h plot.m data.cvs

vgraph.cpp
#i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e CImg . h // I n c l u d e CImg l i b r a r y h e a d e r . <i o s t r e a m > l i n e . h p o i n t . h s k i p l i s t . h <cmath>

u s i n g namespace c i m g l i b r a r y ; u s i n g namespace s t d ; const const const const const const const u n s i g n e d c h a r WHITE [ ] = { 2 5 5 , 2 5 5 , 255 } ; u n s i g n e d c h a r GREY [ ] = { 1 0 0 , 1 0 0 , 100 } ; u n s i g n e d c h a r BLACK [ ] = { 0 , 0 , 0 } ; u n s i g n e d c h a r RED [ ] = { 2 5 5 , 0 , 0 } ; u n s i g n e d c h a r GREEN [ ] = { 0 , 2 5 5 , 0 } ; u n s i g n e d c h a r BLUE [ ] = { 0 , 0 , 2 5 5 } ; int s c r e e n s i z e = 800;

// // P r o t o t y p e s // v o i d vgraph ( d o u b l e o r d e r ) ; d o u b l e v e c t o r s A n g l e ( i n t x , i n t y , i n t basex , i n t b a s e y ) ; double d i s t a n c e ( Point a , Point b ) ; // // Main p r o c e d u r e // i n t main ( ) { c o u t << e n d l << e n d l << V i s i b i l i t y Graph by Dave Coleman << e n d l ; f o r ( d o u b l e o r d e r = 2 ; o r d e r < 3 ; o r d e r += 0 . 5 ) { vgraph ( o r d e r ) ; } r e t u r n EXIT SUCCESS ; } v o i d vgraph ( d o u b l e o r d e r ) { // V a r i a b l e s // Atomic o p e r a t i o n c o u n t e r at om i c = 0 ;

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 << e n 31 dl 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

Page 1 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph


47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

// G r a p h i c s : bool v i s u a l = true ; bool l i v e = true ; CImg<u n s i g n e d char > img ( s c r e e n s i z e , s c r e e n s i z e , 1 , 3 , 2 0 ) ; CImgDisplay d i s p ( img , V i s i b i l i t y Graph ) ; // D i s p l a y t h e m o d i f i e d image on t h e screen // L i n e s e gm e nt s : i n t s i z e = pow ( 1 0 . 0 , o r d e r ) ; int row col = sqrt ( s i z e ) ; int seg = row col row col ; // C o o r d i n a t e s : d o u b l e width = s c r e e n s i z e / r o w c o l ; // s i z e o f each g r i d box d o u b l e margin = 0 . 1 width ; // padding i n s i d e each box d o u b l e top , bottom , l e f t , r i g h t ; // c o o r d i n a t e s o f box with padding // G e n e r a t e s p a c e f o r SEG number o f l i n e s Line s e g s [ seg ] ; // Track what i n d e x we a r e on i n t index = 0 ; // Now g e n e r a t e s e g l i n e s e g me n ts f o r ( i n t x = 0 ; x < r o w c o l ; ++x ) { f o r ( i n t y = 0 ; y < r o w c o l ; ++y ) { top = y width + margin ; bottom = ( y+1) width margin ; l e f t = x width + margin ; r i g h t = ( x+1) width margin ; // C r e a t e l i n e segment i n box o f s i z e width width // x1 , y1 , x2 , y2 s w i t c h ( rand ( ) % 4 ) { c a s e 0 : // v e r t i c l e l i n e s e g s [ i n d e x ] = new L i n e ( l e f t , top , l e f t , bottom ) ; break ; c a s e 1 : // h o r i z o n t a l l i n e s e g s [ i n d e x ] = new L i n e ( l e f t , top , r i g h t , top ) ; break ; c a s e 2 : // d i a g o n a l l e f t t o r i g h t s e g s [ i n d e x ] = new L i n e ( l e f t , top , r i g h t , bottom ) ; break ; case 3: s e g s [ i n d e x ] = new L i n e ( l e f t , bottom , r i g h t , top ) ; break ; } i n d e x ++; } } // c o u t << SEGS << s e g << INDEX << i n d e x << e n d l ; / Line s e g s [ ] = { Line (280 ,300 ,330 ,120) Line (450 ,150 ,280 ,330) Line (400 ,150 ,401 ,190) Line (400 ,400 ,450 ,200) Line (350 ,350 ,350 ,450) Line (10 ,200 ,100 ,215) ,

, , , , ,

// // // // // //

0 1 2 3 4 5

first second third , l a t e r far right

Page 2 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph


// 6 // 7

Line (50 ,50 ,50 ,100) , Line (200 ,450 ,300 ,450) }; /

// R e u s a b l e p o i n t e r l o c a t i o n s Line l ; Point p ; int center id ; bool isPointA ; // V i s i t each v e r t e x once and p e r f o r m t h e v i s i b i l i t y a l g o r i t h m f o r ( i n t o u t e r = 0 ; o u t e r < 2 s e g ; ++o u t e r ) { ++at om ic ; // F i r s t o r s e c o n d number on each l i n e ? center id = outer / 2; // Garbage C o l l e c t i f ( outer ) { delete center ; delete center line ; } // c o u t << LINE ID : << c e n t e r i d << e n d l ; i f ( ! ( o u t e r % 2 ) ) // i s even { c e n t e r = new P o i n t ( s e g s [ c e n t e r i d ]>a>x , s e g s [ c e n t e r i d ]>a>y ) ; isPointA = true ; } e l s e // i s even { c e n t e r = new P o i n t ( s e g s [ c e n t e r i d ]>b>x , s e g s [ c e n t e r i d ]>b>y ) ; isPointA = f a l s e ; } // C en ter L i n e Calc : c e n t e r l i n e = new L i n e ( c e n t e r >x , c e n t e r >y , c e n t e r >x+1 , c e n t e r >y ) ; // Add p o i n t e r s t o a l l p o i n t s back t o p a r e n t l i n e c e n t e r >p a r e n t L i n e = s e g s [ c e n t e r i d ] ; // Draw s w e e p e r : // img . d r a w l i n e ( c e n t e r >x , c e n t e r >y , c e n t e r >x +200 , c e n t e r >y , RED) ; i f ( visual ) img . d r a w c i r c l e ( c e n t e r >x , c e n t e r >y , 6 , RED) ; / c o u t << LINE ID << c e n t e r i d << ; i f ( isPointA ) c o u t << A << e n d l ; else c o u t << B << e n d l ; / // D a t a s t r u c t u r e s : s k i p l i s t < P o i n t > a n g l e L i s t ; s k i p l i s t < L i n e > e d g e L i s t ; // Algorithm // Draw s e g me n ts and i n s e r t POINTS i n t o s k i p l i s t o r d e r e d by ANGLE f o r ( i n t i = 0 ; i < s e g ; ++i ) { ++at om ic ; l = segs [ i ] ;

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181

Page 3 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

182 183 184 185 186 // R e s e t v i s i t e d f l a g s 187 l > v i s i t e d = f a l s e ; 188 l > v i s i t e d S t a r t P o i n t = f a l s e ; 189 190 i f ( visual ) 191 img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , WHITE) ; 192 193 i f ( ! ( i == c e n t e r i d && i s P o i n t A ) ) // p o i n t i s not l i n e A 194 { 195 i f ( visual ) 196 img . d r a w c i r c l e ( l >a>x , l >a>y , 2 , WHITE) ; 197 198 // C a l c u l a t e t h e a n g l e from c e n t e r l i n e : 199 l >a> t h e t a = v e c t o r s A n g l e ( l >a>x , l >a>y , c e n t e r >x , c e n t e r >y ) ; 200 201 // S o r t t h e v e r t i c i e s : 202 a n g l e L i s t . add ( l >a ) ; 203 204 // c o u t << Added A f o r l i n e << i << t h e t a << l >a> t h e t a << e n d l ; 205 // c o u t << POINT ; l >a> p r i n t ( ) ; c o u t << e n d l ; 206 } 207 208 i f ( ! ( i == c e n t e r i d && i s P o i n t A == f a l s e ) ) // p o i n t i s not l i n e B 209 { 210 i f ( visual ) 211 img . d r a w c i r c l e ( l >b>x , l >b>y , 2 , WHITE) ; 212 213 // C a l c u l a t e t h e a n g l e from c e n t e r l i n e : 214 l >b> t h e t a = v e c t o r s A n g l e ( l >b>x , l >b>y , c e n t e r >x , c e n t e r >y ) ; 215 216 // S o r t t h e v e r t i c i e s : 217 a n g l e L i s t . add ( l >b ) ; 218 // c o u t << Added B f o r l i n e << i << t h e t a << l >b> t h e t a << e n d l ; 219 220 // c o u t << POINT ; l >b> p r i n t ( ) ; c o u t << e n d l ; 221 } 222 223 // c o u t << e n d l ; 224 } 225 226 227 // Test S k i p L i s t 228 // c o u t << Angle L i s t p o i n t s o r d e r e d CC from b a s e l i n e ; 229 // a n g l e L i s t . p r i n t A l l ( ) ; 230 231 232 // I n i t i a l i z e Edge L i s t Of L i n e s 233 f o r ( i n t i = 0 ; i < s e g ; ++i ) 234 { 235 ++at om ic ; 236 237 l = s e g s [ i ] ; // g e t n e x t l i n e t o c h e c k 238 239 // c h e c k i f t h e c u r r e n t l i n e i s c o n n e c t e d t o t h e c e n t e r p o i n t 240 i f ( l > i d == ( ( L i n e ) c e n t e r >p a r e n t L i n e )> i d ) 241 { 242 // one c e n t e r s l i n e 243 // c o u t << ONE CENTER S LINE ! ! ! << e n d l ; 244 } 245 else 246 { 247 // Check each l i n e and s e e i f i t c r o s s e s s c a n l i n e 248 double xi , y i ; 249
// Add p o i n t e r s t o a l l p o i n t s back t o p a r e n t l i n e l >a>p a r e n t L i n e = l ; l >b>p a r e n t L i n e = l ;

Page 4 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

250 251 // Now we know t h a t x i , y i i s on c e n t e r l i n e . 252 // Next we c h e c k i f X i s between a & b . We know a . x > b . x , t h u s : 253 i f ( l >a>x >= x i && l >b>x <= x i ) 254 { 255 // c h e c k t h a t x i > c e n t e r >x 256 i f ( x i >= c e n t e r >x ) 257 { 258 259 // I t d o e s i n t e r s e c t 260 e d g e L i s t . add ( l ) ; 261 262 // Mark a s opened , somewhere on l i n e 263 l > v i s i t e d = t r u e ; 264 265 // V i s u a l i z e : 266 i f ( visual ) 267 img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , GREEN) ; 268 } 269 } 270 } 271 } 272 273 if ( live ) 274 d i s p . d i s p l a y ( img ) ; 275 276 // c o u t << Edge L i s t : ; 277 // e d g e L i s t . p r i n t A l l ( ) ; 278 279 // Sweep 280 281 // s l e e p ( 1 ) ; 282 // u s l e e p ( 5 0 0 1 0 0 0 ) ; 283 f o r ( i n t i = 0 ; i < 2 s e g 1 ; ++i ) 284 { 285 ++at om ic ; 286 287 // c o u t << \ n \ n \ n STARTING NEW SWEEP \ n \ n \ n ; 288 289 // c o u t << SWEEP VERTEX << i << e n d l ; 290 // i f ( i > 0 ) 291 // b r e a k ; 292 293 // t a k e t h e f i r s t v e r t e x i n a n g u l a r o r d e r 294 p = a n g l e L i s t . pop ( ) ; 295 // c o u t << Sweep a t ; p> p r i n t ( ) ; 296 297 // Update t h e c e n t e r l i n e t o t h e sweep l o c a t i o n and update m, b 298 c e n t e r l i n e >b = p ; 299 c e n t e r l i n e >u p d a t e C a l c s ( ) ; 300 301 // Update c e n t e r p o i n t t o c o n t a i n t h e t a between b a s e l i n e and 302 // c u r r e n t p o i n t , s o t h a t our l i n e f u n c t i o n can c a c h e 303 c e n t e r > t h e t a = p> t h e t a ; 304 305 // d e c i d e what t o do with i t 306 l = ( L i n e ) p>p a r e n t L i n e ; // c a s t i t 307 // c o u t << \ t ; l > p r i n t ( ) ; 308 309 // c h e c k i f t h e c u r r e n t l i n e i s c o n n e c t e d t o t h e c e n t e r p o i n t 310 i f ( l > i d == ( ( L i n e ) c e n t e r >p a r e n t L i n e )> i d ) 311 { 312 // one c e n t e r s l i n e 313 // i g n o r e 314 } 315 e l s e i f ( l > v i s i t e d ) // remove i t from e d g e L i s t 316 { 317
l > c e n t e r i n t e r c e p t ( x i , y i ) ; // t h e s e a r e r e f e r e n c e p a r a m e t e r s

Page 5 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

318 319 i f ( ! l > v i s i t e d S t a r t P o i n t ) 320 { 321 l > v i s i t e d = f a l s e ; // a l l o w t h i s l i n e t o be v i s i s t e d a g a i n f o r i t s s t a r t 322


// c o u t << remove << e n d l ; point } // c h e c k i f i t s f i r s t i n t h e edge l i s t . i f ( e d g e L i s t . i s R o o t ( l > i d ) ) { // c o u t << Drawing L i n e << e n d l ; if i t is , i t s VISIBLE

i f ( visual ) img . d r a w l i n e ( c e n t e r >x , c e n t e r >y , p>x , p>y , BLUE ) ; } // remove // c o u t << Value : << l >v a l u e ( ) << << l > i d << e n d l ; e d g e L i s t . remove ( l >v a l u e ( ) , l > i d ) ; i f ( visual ) img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , WHITE) ; } e l s e // add i t t o edge l i s t { // c o u t << add << e n d l ; l > v i s i t e d = t r u e ; // mark i t a s h a v i n g been v i s i t e d somewhere l > v i s i t e d S t a r t P o i n t = t r u e ; // mark i t a s h a v i n g found t h e f i r s t v e r t e x // S t o r e d i s t a n c e o f l i n e from c e n t e r l > d i s t = d i s t a n c e ( p , c e n t e r ) ; e d g e L i s t . add ( l ) ; // c h e c k i f i t s f i r s t i n t h e edge l i s t . i f i t i s , i t s VISIBLE i f ( e d g e L i s t . i s R o o t ( l > i d ) ) { // c o u t << Drawing L i n e << e n d l ; i f ( visual ) img . d r a w l i n e ( c e n t e r >x , c e n t e r >y , p>x , p>y , BLUE ) ; } i f ( visual ) img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , GREEN) ; } i f ( visual ) img . d r a w c i r c l e ( p>x , p>y , 5 , GREY) ; // debug // c o u t << Edge L i s t : ; // e d g e L i s t . p r i n t A l l ( ) ; // a n g l e L i s t . p r i n t A l l ( ) ; // c o u t << e n d l << e n d l ; if ( live ) { d i s p . d i s p l a y ( img ) ; // u s l e e p ( 1 1 0 0 0 ) ; // s l e e p ( 1 ) ; } } // c o u t << b r e a k i n g << e n d l ; // b r e a k ; if ( live ) {

323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384

Page 6 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

385 386 } 387 // b r e a k ; 388 // img . f i l l ( 2 0 ) ; 389 // c o u t << o u t e r << e n d l ; 390 } 391 392 i f ( visual ) 393 { 394 // Redraw o b s t a c l e l i n e s j u s t f o r f u n : 395 f o r ( i n t i = 0 ; i < s e g ; ++i ) 396 { 397 l = segs [ i ] ; 398 399 img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , WHITE) ; 400 img . d r a w c i r c l e ( l >a>x , l >a>y , 2 , WHITE) ; 401 img . d r a w c i r c l e ( l >b>x , l >b>y , 2 , WHITE) ; 402 } 403 d i s p . d i s p l a y ( img ) ; 404 405 406 img . s a v e ( r e s u l t . png ) ; // s a v e t h e image 407 } 408 409 c o u t << s e g << , << at om ic << e n d l ; 410 411 i f ( visual ) 412 { 413 // Show window u n t i l u s e r i n p u t : 414 while ( ! disp . i s c l o s e d () ) { 415 i f ( d i s p . is keyESC ( ) ) 416 break ; 417 disp . wait ( ) ; 418 } 419 } 420 421 // Garabage c o l l e c t 422 // d e l e t e [ ] s e g s ; 423 // f r e e ( s e g s ) ; 424 } 425 426 // 427 // C a l c u l a t e Angle Btw 2 V e c t o r s 428 // 429 d o u b l e v e c t o r s A n g l e ( i n t x , i n t y , i n t basex , i n t b a s e y ) 430 { 431 // Convert i n p u t p o i n t x & y t o be v e c t o r s r e l a t i v e t o b a s e p o i n t 432 d o u b l e x2 = d o u b l e ( x b a s e x ) ; 433 d o u b l e y2 = d o u b l e ( y b a s e y ) ; 434 435 // Hard code s c a n l i n e t o p o i n t r i g h t : 436 d o u b l e x1 = s q r t ( x2 x2 + y2 y2 ) ; // make i t with r a t i o ? 437 d o u b l e y1 = 0 . 0 ; 438 439 // c o u t << x1 : << x1 << y1 : << y1 << e n d l ; 440 // c o u t << x2 : << x2 << y2 : << y2 << e n d l ; 441 442 d o u b l e s t u f f = ( ( x1 x2 ) +(y1 y2 ) ) / ( s q r t ( x1 x1+y1 y1 ) s q r t ( x2 x2+y2 y2 ) ) ; 443 // c o u t << S t u f f : << s t u f f << e n d l ; 444 445 // C a l c u l a t e a n g l e : 446 double r e s u l t = acos ( s t u f f ) ; 447 // c o u t << R e s u l t : << r e s u l t << e n d l ; 448 449 // Now add PI i f below m id dl e l i n e : 450 i f ( y >= b a s e y ) 451 r e s u l t = 2 M PI r e s u l t ; 452
// u s l e e p ( 1 1 0 0 0 ) ; d i s p . d i s p l a y ( img ) ;

Page 7 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph


453 454 455 456 457 458 459 460 461 462 463 464

// c o u t << R e s u l t : << r e s u l t 180/ M PI << d e g r e e s << e n d l ; return r e s u l t ; } // // D i s t a n c e Btw 2 P o i n t s // double d i s t a n c e ( Point a , Point b ) { r e t u r n s q r t ( pow ( b>x a>x , 2 . 0 ) + pow ( b>y a>y , 2 . 0 ) ) ; }

../visibility graph/vgraph.cpp

Page 8 of 22

Dave Coleman skiplist.h

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

1 2 3 4 2/2/2012 5 6 Implementation o f Skip L i s t s 7 / 8 9 #i n c l u d e <math . h> 10 #i n c l u d e < i o s t r e a m > 11 #i n c l u d e < c s t d l i b > 12 #i n c l u d e node . h 13 //#i n c l u d e p o i n t . h 14 u s i n g namespace s t d ; 15 16 // 17 // S k i p L i s t C l a s s 18 // 19 t e m p l a t e < c l a s s T> 20 class skiplist { 21 // used f o r t e s t i n g 22 public : 23 i n t maxLevel ; 24 25 private : 26 node<T> r o o t ; 27 28 // 29 // Get Random L e v e l 30 // 31 i n t getRandLevel ( ) 32 { 33 i n t randResult = 1; 34 int level = 0; 35 while ( randResult ) 36 { 37 38 r a n d R e s u l t = rand ( ) % 2 ; 39 i f ( randResult ) 40 { 41 ++l e v e l ; 42 } 43 44 i f ( l e v e l > maxLevel ) 45 { 46 r a n d R e s u l t = 0 ; // t o end t h e w h i l e l o o p 47 } 48 } 49 return l e v e l ; 50 51 } 52 // 53 // C r e a t e New Node 54 // 55 node<T> c r e a t e N o d e ( i n t l e v e l , i n t h e i g h t , T data ) 56 { 57 // Check i f we a r e below l e v e l 0 58 i f ( l e v e l < 0) 59 { 60 r e t u r n NULL; 61 } 62 e l s e // make a new node below 63 { 64 node<T> newNode = new node<T> () ; 65 newNode> l e v e l = l e v e l ; 66
/ S k i p L i s t CSCI 5454 A l g o r i t h m s Dave Coleman | d a v i d . t . c o l em a n @ c o l o r a d o . edu

Page 9 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

67 68 69 70 71 } 72 } 73 74 public : 75 76 // C o n s t r u c t o r : 77 s k i p l i s t () 78 { 79 r o o t = NULL; 80 maxLevel = 0 ; 81 82 s r a n d ( time (NULL) ) ; // s e e d t h e random g e n e r a t o r 83 } 84 // 85 // ADD 86 // 87 v o i d add ( T data ) 88 { 89 // c o u t << ADD: ; 90 // data . p r i n t ( ) ; 91 92 // S p e c i a l Cases 93 94 i f ( ! r o o t ) // no r o o t has been e s t a b l i s h e d y e t 95 { 96 r o o t = c r e a t e N o d e ( 0 , 0 , data ) ; 97 return ; 98 } 99 100 i f ( r o o t >data >v a l u e ( ) > data >v a l u e ( ) ) // new v a l u e g o e s b e f o r e r o o t 101 { 102 T temp data = r o o t >data ; 103 node<T> n = r o o t ; 104 105 f o r ( i n t l = maxLevel ; l >= 0 ; l ) 106 { 107 at om i c += 1 ; 108 // change t h e r o o t t o t h e new v a l u e 109 n>data = data ; 110 n = n>below ; 111 } 112 data = temp data ; 113 } 114 115 // R e g u l a r i n s e r t a f t e r r o o t 116 117 // Determine what l e v e l t h i s new node w i l l be a t 118 i n t l e v e l = getRandLevel ( ) ; 119 120 // I f new node i s a t whole new l e v e l , go ahead and update r o o t node t o be h i g h e r 121 i f ( l e v e l > maxLevel ) 122 { 123 maxLevel ++; 124 node<T> newRoot = new node<T> () ; 125 newRoot>data = r o o t >data ; 126 newRoot>n e x t = NULL; 127 newRoot>below = r o o t ; 128 newRoot> l e v e l = maxLevel ; 129 r o o t = newRoot ; 130 } 131 132 // C r e a t e t h e new node 133 node<T> newNode = c r e a t e N o d e ( l e v e l , l e v e l , data ) ; 134
newNode>n e x t = NULL; newNode>below = c r e a t e N o d e ( l e v e l 1 , h e i g h t , data ) ; newNode> h e i g h t = h e i g h t ; newNode>data = data ; r e t u r n newNode ;

Page 10 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

135 136 137 138 // Loop down t h r o u g h a l l l e v e l s 139 f o r ( i n t l = maxLevel ; l >= 0 ; l ) 140 { 141 at om ic += 1 ; 142 // move f o r w a r d u n t i l we h i t a v a l u e g r e a t e r than o u r s 143 w h i l e ( i >n e x t != NULL ) 144 { 145 at om i c += 1 ; 146 i f ( i >next >data >v a l u e ( ) > data >v a l u e ( ) ) // i n s e r t b e f o r e i . n e x t 147 { 148 break ; 149 } 150 i = i >n e x t ; 151 } 152 153 // Check i f we s h o u l d add a p o i n t e r a t t h i s l e v e l 154 i f ( l <= l e v e l ) 155 { 156 newNode>n e x t = i >n e x t ; 157 i >n e x t = newNode ; 158 159 // Now move t h e new node p o i n t e r one l e v e l down : 160 newNode = newNode>below ; 161 } 162 163 // Always move t h e i node p o i n t e r one l e v e l down : 164 i = i >below ; 165 } 166 167 } 168 // 169 // Find 170 // 171 bool f i n d ( double x ) 172 { 173 node<T> i = r o o t ; 174 175 // S p e c i a l c a s e : s k i p l i s t i s empty 176 i f ( ! root ) 177 { 178 return f a l s e ; 179 } 180 181 // S p e c i a l c a s e : c h e c k r o o t 182 i f ( r o o t >data >v a l u e ( ) == x ) 183 { 184 return true ; 185 } 186 187 f o r ( i n t l = maxLevel ; l >= 0 ; l ) 188 { 189 at om ic += 1 ; 190 // move f o r w a r d u n t i l we h i t a v a l u e g r e a t e r than o u r s 191 w h i l e ( i >n e x t != NULL ) 192 { 193 at om i c += 1 ; 194 if ( i >n e x t >data >v a l u e ( ) > x ) // x i s not found on t h i s l e v e l 195 { 196 break ; 197 } 198 else if ( i >next >data >v a l u e ( ) == x ) // b i n g o ! 199 { 200 return true ; 201 } 202
// Now add t h e node t o t h e l i s t node<T> i = r o o t ;

Page 11 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

203 204 } 205 206 // Always move t h e i node<T> p o i n t e r one l e v e l down : 207 i = i >below ; 208 } 209 210 return f a l s e ; 211 } 212 // 213 // REMOVE 214 // t h e i d i s t o c o n f i r m t h e c o r r e c t node , j u s t i n c a s e x i s not u n i q u e 215 // 216 b o o l remove ( d o u b l e x , i n t i d ) 217 { 218 node<T> i = r o o t ; 219 220 // S p e c i a l c a s e : remove r o o t 221 i f ( r o o t >data >v a l u e ( ) == x && r o o t >data > i d == i d ) 222 { 223 // Get l e v e l 0 o f r o o t 224 f o r ( i n t l = r o o t > l e v e l ; l > 0 ; l ) 225 { 226 at om i c += 1 ; 227 // c o u t << L e v e l << l << e n d l ; 228 i = i >below ; 229 } 230 231 // Check i f t h e r e a r e any more nodes 232 i f ( ! i >n e x t ) // t h e s k i p l i s t i s empty 233 { 234 r o o t = NULL; 235 maxLevel = 0 ; 236 237 return true ; 238 } 239 240 // Change v a l u e o f r o o t t o n e x t node 241 node<T> n = r o o t ; 242 node<T> nextNode = i >n e x t ; 243 244 f o r ( i n t l = maxLevel ; l >= 0 ; l ) 245 { 246 at om i c += 1 ; 247 // change t h e r o o t t o t h e new v a l u e 248 n>data = nextNode >data ; 249 250 // update n e x t p o i n t e r i f t h e n e x t n e x t e x i s t s 251 i f ( n>n e x t ) 252 { 253 n>n e x t = n>next >n e x t ; 254 } 255 256 // Move down t o n e x t l e v e l 257 n = n>below ; 258 } 259 260 return true ; 261 } 262 263 // Normal c a s e : remove a f t e r r o o t 264 b o o l found = f a l s e ; 265 266 f o r ( i n t l = maxLevel ; l >= 0 ; l ) 267 { 268 at om ic += 1 ; 269 // move f o r w a r d u n t i l we h i t a v a l u e g r e a t e r than o u r s 270
i = i >n e x t ;

Page 12 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

271 272 273 274 275 276 277 278 // p a s s t h r o u g h t h e p o i n t e r i f e x i s t s 279 i f ( i >n e x t ) 280 { 281 i >n e x t = i >next >n e x t ; 282 } 283 else 284 { 285 i >n e x t = NULL; 286 } 287 break ; 288 } 289 e l s e i f ( i >next >data >v a l u e ( ) > x ) // x i s not found on t h i s l e v e l 290 { 291 break ; 292 } 293 294 i = i >n e x t ; 295 } 296 297 // Always move t h e i node p o i n t e r one l e v e l down : 298 i = i >below ; 299 } 300 301 r e t u r n found ; 302 } 303 // 304 // POP FROM FRONT 305 // 306 T pop ( ) 307 { 308 node<T> i = r o o t ; 309 310 // S t o r e t h e f i r s t item on t h e l i s t t h a t we want t o l a t e r r e t u r n 311 T r e s u l t = r o o t >data ; 312 / 313 c o u t << POP WITH VALUE: << r o o t >v a l u e << ; 314 result . print () ; 315 c o u t << e n d l ; 316 / 317 318 // Check i f s k i p l i s t i s empty 319 i f ( ! root ) 320 { 321 c o u t << An e r r o r has o c c u r e d : s k i p l i s t i s empty ; 322 exit (1) ; 323 } 324 325 // Get l e v e l 0 o f r o o t 326 f o r ( i n t l = r o o t > l e v e l ; l > 0 ; l ) 327 { 328 at om ic += 1 ; 329 i = i >below ; 330 } 331 332 // Check i f t h e r e a r e any more nodes 333 i f ( ! i >n e x t ) // t h e s k i p l i s t i s empty 334 { 335 r o o t = NULL; 336 maxLevel = 0 ; 337 338
w h i l e ( i >n e x t != NULL ) { at om i c += 1 ; // remove t h i s one , c o n f i r m e d by i d i f ( i >next >data >v a l u e ( ) == x && i >next >data > i d == i d ) { found = t r u e ;

Page 13 of 22

Dave Coleman
return r e s u l t ;

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

339 340 341 // Change v a l u e o f r o o t t o n e x t node 342 node<T> n = r o o t ; 343 node<T> nextNode = i >n e x t ; 344 345 f o r ( i n t l = maxLevel ; l >= 0 ; l ) 346 { 347 at om ic += 1 ; 348 // change t h e r o o t t o t h e new v a l u e 349 n>data = nextNode >data ; 350 351 // update n e x t p o i n t e r i f t h e n e x t n e x t e x i s t s 352 i f ( n>n e x t ) 353 { 354 n>n e x t = n>next >n e x t ; 355 } 356 357 // Move down t o n e x t l e v e l 358 n = n>below ; 359 360 } 361 362 return r e s u l t ; 363 } 364 // 365 // I s Root 366 // 367 bool isRoot ( int id ) 368 { 369 370 i f ( ! r o o t ) // t h e r e i s no r o o t ! 371 { 372 s t d : : c o u t << t h e r e i s no r o o t ! << s t d : : e n d l ; 373 return f a l s e ; 374 } 375 r e t u r n ( r o o t >data > i d == i d ) ; 376 } 377 // 378 // PRINT ALL 379 // 380 void p r i n t A l l ( ) 381 { 382 s t d : : c o u t << s t d : : e n d l << LIST << s t d : : e n d l ; 383 384 // S p e c i a l c a s e : s k i p l i s t i s empty 385 i f ( ! root ) 386 { 387 s t d : : c o u t << << s t d : : e n d l ; 388 return ; 389 } 390 391 node<T> i = r o o t ; 392 393 // Get l e v e l 0 o f r o o t 394 f o r ( i n t l = r o o t > l e v e l ; l > 0 ; l ) 395 { 396 // c o u t << L e v e l << l << ; 397 // i . data . p r i n t ( ) ; 398 // c o u t << e n d l ; 399 i = ( i . below ) ; 400 } 401 // s t d : : c o u t << we a r e on l e v e l << i . l e v e l << s t d : : e n d l ; 402 403 // Hack : update r o o t 0 l e v e l with maxLevel count , b e c a u s e we don t update t h i s 404 // when g r o w i n g r o o t l e v e l s i z e 405 i . h e i g h t = maxLevel ; 406
}

Page 14 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph


407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437

int counter = 0; b o o l done = f a l s e ; w h i l e ( ! done ) { s t d : : c o u t << c o u n t e r ; f o r ( i n t l = i . h e i g h t ; l >= 0 ; l ) { s t d : : c o u t << | ; } s t d : : c o u t << << i . data >v a l u e ( ) << ; i . data > p r i n t ( ) ; c o u n t e r ++; i f ( i . next ) { node<T> i i = i . n e x t ; i = ii ; } else { done = t r u e ; } } s t d : : c o u t << << s t d : : e n d l << s t d : : e n d l ; } };

../visibility graph/skiplist.h

Page 15 of 22

Dave Coleman node.h


#i n c l u d e l i n e . h //

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

1 2 3

// Node C l a s s 4 // 5 t e m p l a t e < c l a s s T> c l a s s node { public : node below ; // node below i n tower node n e x t ; // n e x t node i n s k i p l i s t i n t l e v e l ; // l e v e l o f t h i s c u r r e n t node i n t h e i g h t ; // f u l l number o f l e v e l s i n tower T data ; };

6 7 8 9 10 11 12 13 14

../visibility graph/node.h

Page 16 of 22

Dave Coleman line.h

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

1 2 3 #i n c l u d e < i o s t r e a m > 4 #i n c l u d e p o i n t . h 5 #i n c l u d e geometry . h 6 #i n c l u d e <cmath> 7 8 c l a s s L i n e : p u b l i c Geometry 9 { 10 public : 11 Point a ; 12 Point b ; 13 b o o l v i s i t e d S t a r t P o i n t ; // has t h e b a s e / sweep l i n e c r o s s e d a t l e a s t one o f 14 // t h e v e r t i c i e s ? 15 bool v i s i t e d ; // has t h e sweep l i n e been on t h e l i n e ( a s in , maybe i t was i n i t on i t ) 16 17 int id ; 18 d o u b l e d i s t ; // d i s t a n c e from c e n t e r 19 d o u b l e t h e t a c a c h e ; // used f o r d e c i d i n g i f t h e d i s t c a c h e n e e d s t o be r e f r e s h e d 20 d o u b l e m; // s l o p e o f l i n e 21 d o u b l e y i n t e r c e p t ; // y i n t e r c e p t o f l i n e 22 23 Line ( ) ; 24 L i n e ( i n t x1 , i n t y1 , i n t x2 , i n t y 2 ) ; 25 Line ( ) ; 26 v i r t u a l void print ( ) ; 27 v i r t u a l double value ( ) ; 28 29 void updateCalcs ( ) ; 30 void distance ( ) ; 31 v o i d c e n t e r i n t e r c e p t ( d o u b l e &x i , d o u b l e &y i ) ; 32 }; 33 34 35 // This g l o b a l n e e d s t o be v i s i b l e t o c l a s s e s : 36 extern Point c e n t e r ; 37 extern Line c e n t e r l i n e ; 38 e x t e r n d o u b l e at om ic ; 39 40 #e n d i f 41
#i f n d e f LINE H INCLUDED #d e f i n e LINE H INCLUDED

../visibility graph/line.h line.cpp


#i n c l u d e l i n e . h Point c e n t e r ; Line c e n t e r l i n e ; d o u b l e at om ic ; u s i n g namespace s t d ; Line : : Line ( ) { c o u t << You a r e c a l l i n g t h e f u n c t i o n wrong ; exit (0) ; } L i n e : : L i n e ( i n t x1 , i n t y1 , i n t x2 , i n t y2 ) { // Order a and b such t h a t a . x > b . x i f ( x1 > x2 ) { a = new P o i n t ( x1 , y1 ) ; b = new P o i n t ( x2 , y2 ) ; }

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Page 17 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

22 23 24 25 26 27 // Change ID 28 static int id counter = 0; 29 i d = i d c o u n t e r ++; 30 31 // Keep t r a c k o f i t s v i s i t e d h i s t o r y 32 visited = false ; 33 visitedStartPoint = false ; 34 35 // c o u t << LINE << e n d l ; 36 updateCalcs ( ) ; 37 38 // c o u t << LINE << e n d l ; 39 40 // Used f o r c h e c k i n g i f we need t o r e f r e s h our d i s t a n c e amount 41 t h e t a c a c h e = 3 M PI ; // some a n g l e b i g g e r than 2PI , aka INF 42 // d i s t a n c e ( ) ; 43 44 // c o u t << END LINE \ n << e n d l ; 45 } 46 Line : : Line ( ) 47 { 48 // d e l e t e a ; 49 // d e l e t e b ; 50 } 51 void Line : : p r i n t ( ) 52 { 53 c o u t << L i n e : x1 : << a>x << y1 : << a>y << x2 : << b>x 54 << y2 : << b>y << \ t ID : << i d << e n d l ; 55 } 56 double Line : : value ( ) 57 { 58 // c a l c u l a t e d i s t a n c e from m i d p o i n t a t a g i v e n t h e t a , 59 // with r e s e p c t t o t h e b a s e l i n e 60 61 i f ( t h e t a c a c h e != c e n t e r > t h e t a ) // c h e c k i f our ca ch ed v e r s i o n i s s t i l l f r e s h enough 62 { 63 // c o u t << R e c a l c u l a i n g d i s t a n c e f o r l i n e << i d << e n d l ; 64 distance () ; 65 } 66 67 return dist ; 68 } 69 void Line : : updateCalcs ( ) 70 { 71 // Find S l o p e and y i n t e r c e p t o f t h i s l i n e f o r f u t u r e d i s t a n c e c a l c u l a t i o n s 72 d o u b l e denom = ( b>x a>x ) ; 73 i f ( denom == 0 ) 74 { 75 // c o u t << This program d o e s not s u p p o r t p e r f e c t l y v e r t i c l e l i n e s . << e n d l ; 76 // e x i t ( 0 ) ; 77 78 // P e r t u r b : 79 // b>x = b>x + 1 ; 80 denom = 0 . 0 0 0 0 0 0 0 0 1 ; // ( b>x a>x ) ; 81 } 82 m = ( b>y a>y ) /denom ; 83 84 // c o u t << m << M << e n d l ; 85 86 y i n t e r c e p t = a>y m a>x ; 87 // c o u t << y i n t e r c e p t << m << e n d l ; 88 } 89
else { b = new P o i n t ( x1 , y1 ) ; a = new P o i n t ( x2 , y2 ) ; }

Page 18 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

90 91 92 93 94 95 96 // c o u t << The i n t e r c e p t i s x : << x i << y : << y i << e n d l ; 97 // c o u t << M: << m << b : << y i n t e r c e p t << e n d l ; 98 99 // Now f i n d t h e d i s t a n c e between t h e s e two l i n e s : 100 d i s t = s q r t ( pow ( c e n t e r >x x i , 2 . 0 ) + pow ( c e n t e r >y y i , 2 . 0 ) ) ; 101 102 // c o u t << D i s t a n c e : << d i s t << e n d l << e n d l ; 103 t h e t a c a c h e = c e n t e r > t h e t a ; 104 } 105 106 v o i d L i n e : : c e n t e r i n t e r c e p t ( d o u b l e &x i , d o u b l e &y i ) 107 { 108 x i = d o u b l e ( y i n t e r c e p t c e n t e r l i n e > y i n t e r c e p t ) / d o u b l e ( c e n t e r l i n e > m m ) ; 109 y i = m x i + y i n t e r c e p t ; 110 } 111
void Line : : d i s t a n c e ( ) { // F i r s t f i n d t h e i n t e s e c t i o n o f t h i s l i n e and t h e sweep l i n e : double xi ; double yi ; c e n t e r i n t e r c e p t ( xi , y i ) ;

../visibility graph/line.cpp

Page 19 of 22

Dave Coleman point.h

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

#i f n d e f POINT H INCLUDED #d e f i n e POINT H INCLUDED #i n c l u d e < i o s t r e a m > #i n c l u d e geometry . h c l a s s P o i n t : p u b l i c Geometry { public : int x ; int y ; void parentLine ; i n t i d ; // f o r removing , comparing , e t c d o u b l e t h e t a ; // a n g l u l a r amount from b a s e l i n e Point ( ) ; Point ( i n t

x1 , i n t

y1 ) ;

v i r t u a l void print ( ) ; v i r t u a l double value ( ) ; }; #e n d i f

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

../visibility graph/point.h point.cpp


#i n c l u d e p o i n t . h

Point : : Point ( ) { static int id counter = 0; i d = i d c o u n t e r ++; } P o i n t : : P o i n t ( i n t x1 , i n t y 1 ) { x = x1 ; y = y1 ; Point ( ) ; } void Point : : p r i n t ( ) { s t d : : c o u t << P o i n t x : << x << y : << y << \ t ID : << i d << s t d : : e n d l ; } double Point : : value ( ) { // t h i s i s t h e a n g u l a r d i s t a n c e from t h e b a s e l i n e // f o r p o i n t . cpp , we j u s t c a c h e t h e i n i t i a l c a l c u l a t i o n return theta ; }

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

../visibility graph/point.cpp

Page 20 of 22

Dave Coleman geometry.h

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

#i f n d e f GEOMETRY H INCLUDED #d e f i n e GEOMETRY H INCLUDED c l a s s Geometry { public : // i n t i d ; // f o r removing , comparing , e t c v i r t u a l void print ( ) = 0 ; v i r t u a l double value ( ) = 0 ; }; #e n d i f

1 2 3 4 5 6 7 8 9 10 11 12 13 14

../visibility graph/geometry.h

Page 21 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

Matlab plot.m Used For Generating Plots


clear clc data = c s v r e a d ( data . c v s ) n = data ( : , 1 ) logger1 = 50.(n .2) . log ( n ) ; logger2 = 25.(n .2) . log ( n ) ; l o g l o g ( data ( : , 1 ) , data ( : , 2 ) , bo , . . . data ( : , 1 ) , l o g g e r 1 , k : , data ( : , 1 ) , l o g g e r 2 , k : )

s e t ( gca , F o n t S i z e , 1 4 ) l e g e n d ( Number o f l o o k u p s , O( n2 l o g n ) , L o c a t i o n , NorthWest ) x l a b e l ( Input s i z e , n ) y l a b e l ( Number o f o p e r a t i o n s , T ) t i t l e ( Atomic O p e r a t i o n s o f Lee V i s i b i l i t y Graph Algorithm ) ;

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

../visibility graph/plot.m Runtime Data Restuls


9 ,6026 25 ,62585 1 0 0 , 1 . 4 2 3 1 3 e+06 2 8 9 , 1 . 4 7 7 5 1 e+07 9 6 1 , 2 . 3 4 0 2 7 e+08 3 1 3 6 , 2 . 9 1 4 e+09

1 2 3 4 5 6

../visibility graph/data.cvs

Page 22 of 22

Вам также может понравиться