Given an undirected graph, what would be an algorithm to find all polygons within such graph? Here is an example graph with polygons in colour.
Note that there is a polygon ABCIHGJKLMLKA, which includes the nodes KLM, but the polygon CDEG does not include F.
I have read of solutions to this problem, but without the leaf requirement that I have. Some axioms that exist in previous solutions is that each edge is only used twice, however dead-end edges would need to be traversed four times in total. That is, there exists a polygon that contains all the outer nodes ABCDEFGJKLMLKA, however it is discarded as it would be outward facing.
One solution to a similar problem, sans the leafs, is described here: http://blog.reactoweb.com/2012/04/algorithm-101-finding-all-polygons-in-an-undirected-graph/
UPDATE
It seems that the solution linked does not work as intended, an example of this is illustrated:
The algorithm would traverse the graph A-B-C-A-E-D-C, identifying the triangle ABC, but also the polygon CAEDC, which is not intended
UPDATE2
There is a simple solution to this problem actually: remove larger polygons which contain other polygon's points.
step | description
1a | while vertices with deg(v) = 0 exist
1b | mark vertices with deg(v) = 0 as leaf
|
2 | run algorithm on all vertices which are not marked as leaf
|
3a | for each vertex marked as leaf
3b | if vertex is inside a polygon
3c | check its edges // you have to decide what to do in which case
3d | adjust polygon
I will illustrate this with your example:
step | result
1a | find F and M
1b | mark F and M as leaf
1a | find L
1b | mark L as leaf
1a | find nothing: go to step 2
|
2 | finds polygons: AKJGHICB (1), CIHG (2), and CGED (3)
|
3a | we have F, M, and L
3b | check F:
| poly (1): cast ray: even result -> outside
| poly (2): cast ray: even result -> outside
| poly (3): cast ray: even result -> outside
| since F is always outside: no further action needed, unmark F
3b* | check M:
| poly (1): cast ray: odd result -> inside
| since M is inside a polygon: check how to add it
3c | check edge M-L:
| check if L is part of poly (1)
| if yes: add path to poly (1) (step 3d)
| if no: check if L is inside poly (1)
| -> no check L: odd result -> inside
| if inside: follow path, i.e. step 3c with edge L-K
| if outside: undefined behaviour
| -> inside
3c | check edge L-K:
| check if K is part of poly (1)
| -> yes: add path to poly
3d | Take poly (1) AKJGHICB
| replace K with KLK
| unmark K // note that K was never marked)
| remove K from path
| replace L with LML
| unmark L
| remove L from path
| unmark M // note that you should check if there are more
| // vertices to come for the replacement
| remove M from path
| poly (1) is now AKLMLKJGHICB
3a | we have no marked vertices left
| finish
* note that in step 3b we could first have found L/checked L. Then it would be like this:
3b | check L:
| poly (1): cast ray: odd result -> inside
| since L is inside a polygon: check how to add it
3c | check L-K (or M-L, that would work as above and eventually try L-K)
| check if K is part of poly (1)
| if yes: add path to poly (1)
| -> yes
3d | Take poly (1) AKJGHICB
| replace K with KLK
| unmark K
| remove K from path
| unmark L
| remove L from path
| poly (1) is now AKLKJGHICB
3a | we have M left // from now on a bit less detailed because it's the same again
3b | check M:
| poly (1): cast ray: odd result -> inside
| ...
3c | check M-L
| L is part of poly (1)
3d | replace L in the poly with LML and unmark L and M
| finish
This should be a rough idea of how an algorithm with the one you are already familiar with should work. However, it's probably open for many improvements.
Re AndreyT's suggestion to use a DCEL: the salient feature of the doubly-connected edge list representation is that, for each undirected edge, there are two list nodes, one for each direction. We refer to these nodes as darts and think of them as having a head and a tail. Given a dart (e.g., H->G, with tail H and head G), we can find the reverse dart (e.g., G->H) and the next dart with the same head in counterclockwise order (e.g., J->G). The DCEL can be constructed straightforwardly given a primitive that can be used to sort by angle (the easiest way is to sort by atan2(); the best is to find a determinant test that yields consistent results in the face of floating-point malfeasance).
The polygons (usually called faces) can be found by finding the permutation cycles of the permutation that maps each dart to the reverse of the next dart with the same head in counterclockwise order. For example, if we start with the dart C->D, then we follow the cycle
C->D (E->D is next) D->E (G->E is next) E->G (C->G is next) G->C (D->C is next) C->D
and recover the face C-D-E-G-C. Starting with A->B, we get
A->B B->C C->I I->H H->G G->J J->K K->L L->M M->L L->K K->A A->B,
which is the face A-B-C-I-H-G-J-K-L-M-L-K-A.
This method sort of requires a connected graph. (It will work on a disconnected graph, but it might not give the results that you want.) It also yields the infinite face, which you have indicated is undesirable. To find a dart on the infinite face (which can be used to identify it), find the vertex with the least y-coordinate, breaking ties by least x-coordinate. Then find the last dart with that head in counterclockwise order from the ray shooting straight rightward.
Related
I am currently working on a problem that involves calculating the Fourier Transform of a 2-dimensional Matrix using FFTW in conjunction with MPI.
According to the first section of this page of the FFTW documentation, computing the FT of a matrix requires a lot of communication among the launched processes when it is parallelized. For example, in the case of a matrix such as
1,2,3
4,5,6
7,8,9
the FFT of which we decided to compute with three processes, each process gets a chunk of this matrix so that the data is stored in the local memory of each process as P_0 [1,2,3], P_1 [4,5,6], P_3 [7,8,9].
After computing the initial Fourier Transform, a transposition is calculated which requires the communication of the computed data among the three processes as following:
P_0 -> P_1: 2
P_0 -> P_2: 3
P_1 -> P_0: 4
P_1 -> P_2: 6
P_2 -> P_0: 7
P_2 -> P_1: 8
Since this incurs a large overhead, the second section of the abovementioned FFTW documentation page suggests to calculate the transpose directly in the fourier space to drastically reduce the amount of cross-process communication required.
I am still unsure as to why exactly the calculation of a transpose is necessary in the first place, and how the data calculated from the different chunks of the matrix is merged in the end. Why is it enough to set the FFTW_MPI_TRANSPOSED_OUT and FFTW_MPI_TRANSPOSED_IN flags to not require cross process communication anymore, even though before the processes needed so much more data from all the other processes?
The 2D FFT is computed by first computing 1D FFTs over the rows of the array, then 1D FFTs over the columns (or the other way around, doesn't matter). The first transpose mentioned in the documentation is required to get the data for one column together in one process so that 1D FFT can be computed. The second transpose is required to get the resulting array in the right order again.
step 1:
| a b c | -> 1D FFT -> | A B C |
| d e f | -> 1D FFT -> | D E F | (each row is data belonging to one process)
| g h i | -> 1D FFT -> | G H I |
step 2:
| A B C | -> transpose -> | A D G |
| D E F | -> transpose -> | B E H | (inter-process communication)
| G H I | -> transpose -> | C F I |
step 3:
| A D G | -> 1D FFT -> | J M P |
| B E H | -> 1D FFT -> | K N Q |
| C F I | -> 1D FFT -> | L O R |
step 4:
| J M P | -> transpose -> | J K L |
| K N Q | -> transpose -> | M N O | (the actual 2D FFT of the initial array)
| L O R | -> transpose -> | P Q R |
If you are happy using the result of step 3 instead of that of step 4, then you don't need to do step 4, which saves a lot of communication time. Whether that result is useful or the transpose is needed depends on the application, and this is why the library allows you to make that choice.
Whether one specifies that the input or output is transposed affects the order of the array size passed into the function. In both cases, the last transpose is skipped:
Note that FFTW_MPI_TRANSPOSED_IN is completely equivalent to performing FFTW_MPI_TRANSPOSED_OUT and passing the first two dimensions to the planner in reverse order, or vice versa. If you pass both the FFTW_MPI_TRANSPOSED_IN and FFTW_MPI_TRANSPOSED_OUT flags, it is equivalent to swapping the first two dimensions passed to the planner and passing neither flag.
It is not possible to skip both transposes.
For example, to compute a convolution through the FFT, one would apply the forward FFT to an array, multiply with a kernel, then apply the inverse FFT. In this case, the multiplication works just as well with a transposed array, so we can use FFTW_MPI_TRANSPOSED_OUT for the forward FFT and FFTW_MPI_TRANSPOSED_IN for the inverse FFT. The final result would be identical to what we'd get if we didn't pass any flags and let all the transpositions happen, but it would be more efficient.
I am writing a class which stores an array of defined types. I am having problem -i think- with the syntax of my code. I want to get a defined type inside of array but my code keeps giving error.
I have already created a class, write down the array i need. i have tried already writing it these ways;
[|(Rook, Black, (Alive of (A, 1)))]
[|(Rook, Black, (Alive of A, 1))]
[|(Rook, Black, Alive of (A,1))]
[|(Rook, Black, Alive of A,1)]
[|(Rook, Black, (A,1))
but sadly, it shows my array as chess_piece * chess_colour * (chess_letter * int) or it gives operating error.
this is my defined type
type chess_letter = A | B | C | D | E | F | G | H
and chess_piece = King | Queen | Rook | Bishop | Knight | Pawn
and chess_colour = Black | White
and chess_position = Alive of chess_letter * int | Dead
array should include [|(chess_piece, chess_colour, chess_position)|]
The syntax for constructing a value of the variant Alive is:
Alive (A, 1)
of is only used in the type definition. And it dosn't make a difference whether it's inside or outside an array.
Also, none of your arrays are syntactically correct. The first four are missing a | before the terminating ], and the last is missing both.
I wanted to ask about Fibonacci heaps.
If I have this scenario:
A
|
B
Then, we add two more nodes C and D:
A
|\
B C
|
D
Now we delete B:
A
|
C
|
D
Now we add E and F.
I saw it creates a tree like that:
E
|\
F A
|
C
|
D
But I don't understand why E and F are connected with the tree. From what I read, we connect trees with the same rank (for example, a tree of one node with another tree of one node), am I wrong?
Thank you very much.
If you add the nodes C and D into the first Fibonacci heap, you would not end up with the tree you drew. Instead, you'd have this heap:
A C D
|
B
Remember that Fibonacci heaps lazily add each newly added value to the top-level list of trees and only coalesce things on a deletion. If you were to delete B, you'd promote it to the top level, like this:
A B C D
You'd then remove B:
A C D
Now, you'd scan the root list and coalesce the trees of the same order together. Let's suppose you scan the nodes in the order A, C, D. First, you'll coalesce A and C together, like this:
A D
|
C
At this point, no further coalesces will happen, since there's exactly one tree of each order.
If you then add in E and F, you'd put them at the top level, like this:
A D E F
|
C
So yes, you're right, those nodes shouldn't get added into the tree.
This is my first post in stackover flow.
Recently I started reading the book called "Algorithmic beauty of plants" where, in chapter 1, he explains L system. (You can read the chapter here).
So as I understand there are two types of L systems. Edge rewriting and Node rewriting.
Edge rewriting is relatively very simple. There is a initial starter polygon and a generator. Each edge(side) of the initial polygon will be replaced with the generator.
But this node rewriting is very confusing. From what I gathered, there are two or more rules and with each iteration replace the variables in the rules with their constant counterparts.
With turtle interpretation these are standard rules
F : Move turtle forward in current direction (initial direction is up)
+ : rotate turtle clock wise
- : rotate turtle anti clock wise
[ : Push the current state of the turtle onto a pushdown operations stack.
The information saved on the stack contains the turtle’s position and orientation,
and possibly other attributes such as the color and width of lines being drawn.
] : Pop a state from the stack and make it the current state of the turtle
So consider the example as shown in this website. http://www.selcukergen.net/ncca_lsystems_research/lsystems.html
Axiom : FX
Rule : X= +F-F-F+FX
Angle : 45
so at n=0 (ignore the X in axiom)
its just F that means a straight line pointing up.
at n=1
replace X in axiom with rule
F+F-F-F+F (ignoring the X in the end again)
output is this
http://www.selcukergen.net/ncca_lsystems_research/images/noderewrite.jpg
a simple example with one rule is ok. but in the book "Algorithmic beauty of plants" at page 25 there are some rules I'm not sure how to interpret.
X
X = F[+X]F[-X]+X
F = FF
See this image.
https://lh6.googleusercontent.com/g3aPb1SQpvnzvDttsiiBgiUflrj7R2V29-D60IDahJs=w195-h344-no
at n=0
just 'X'. not sure what this means
at n=1
applying rule 1 (X->F[+X]F[-X]+X) : F[+]F[-]+ ignoring all X. this is just a straight line.
applying rule 2 (F->FF) : FF[+]FF[-]. this is just a straight line.
Final output should be turtle moving four times in up direction as for my understanding. Or at most the final output should contain just four lines.
I found a online L-system generator which i thought will help me in understanding this better so i inputted the same values and here is how the output looks like at n=1
https://lh6.googleusercontent.com/-mj7x0OzoPk4/VK-oMHJsCMI/AAAAAAAAD3o/Qlk_02_goAU/w526-h851-no/Capture%2B2.PNG
output is definitely not a straight line and worst part it has 5 lines that means there should be 5 F in the final output equation.
Help me understanding this node rewriting. Without understanding this i cant read further into the book.
Sorry for the long post, and for links in pre tag. i cant post more than 2 links.
Thanks for having patience of reading it from top to bottom.
L systems are very simple and rely on text substitutions.
With this starting information:
Axiom : FX
Rule : X= +F-F-F+FX
Then basically, to produce the next generation of the system you take the previous generation and for each character in it you apply the substitutions.
You can use this algorithm to produce a generation:
For each character in the previous generation:
Check if we have a substitution rule for that character
YES: Append the substitution
NO: Append the original character
Thus:
n(0) = FX
+-- from the X
|
v---+---v
n(1) = F+F-F-F+FX
^
+- the original F
If you had this start instead:
Axiom : ABA
Rule : A = AB
Then you would have this:
+--------+
| |
n(0) = ABA |
| | |
| ++ |
| | |
vv vv |
n(1) = ABBAB |
^ |
+-------+
Basically:
For every A in generation X, when producing generation X+1, output AB
For every other character without a rule, just output that character (this handles all the B's)
This would be a system that doubles in length for every generation:
Axiom : A
Rule : A = AA
would create:
n(0) = A
n(1) = AA
n(2) = AAAA
n(3) = AAAAAAAA
Problem:
There is a table with below constraints:
a) it has 2 row only.
b) and n col. so basically its 2xN table but N is a power of two.
c) its short ends are joint together you can move from last element of the row to the first element of row if first element is not visited.
Now you are given 2 initial position i1 and i2 for ants and final destination f1 and f2. Now ant have to reach f1 and f2, but either of the ant can reach either of point . example if i1 reach f2 and i2 have to reach f1.
Allowed moves:-
1) Ant can move horizontally and vertically only no diagonal movement.
2) each cell can be visited at most by one ant and all the cell must be visited in the end.
Output:- path traced by two ants if all the cell are marked visited else -1. Need complexity for the algorithm also.
Max flow can be used to compute two disjoint paths, but it is not possible to express the constraint of visiting all squares in a generic fashion (it's possible that there's a one-off trick). This dynamic programming solution isn't the slickest, but the ideas behind it can be applied to many similar problems.
The first step is to decompose the instance recursively, bottoming out with little pieces. (The constraints on these pieces will become apparent shortly.) For this problem, the root piece is the whole 2-by-n array. The two child pieces of the root are 2-by-n/2 arrays. The four children of those pieces are 2-by-n/4 arrays. We bottom out with 2-by-1 arrays.
Now, consider what a solution looks like from the point of view of a piece.
+---+-- ... --+---+
A | B | | C | D
+---+-- ... --+---+
E | F | | G | H
+---+-- ... --+---+
Squares B, C, F, G are inside the piece. Squares A, E are the left boundary. Squares D, H are the right boundary. If an ant enters this piece, it does so from one of the four boundary squares (or its initial position, if that's inside the piece). Similarly, if an ant leaves this piece, it does so to one of the four boundary squares (or its final position, if that's inside the piece). Since each square can be visited at most once, there is a small number of possible permutations for the comings and goings of both ants:
Ant 1: enters A->B, leaves C->D
Ant 2: enters E->F, leaves G->H
Ant 1: enters A->B, leaves G->H
Ant 2: does not enter
Ant 1: enters A->B, leaves C->D, enters H->G, leaves F->E
Ant 2: does not enter
Ant 1: enters A->B, leaves F->E, enters H->G, leaves C->D
Ant 2: does not enter
...
The key fact is that what the ants do strictly outside of this piece has no bearing on what happens strictly inside. For each piece in the recursive decomposition, we can compute the set of comings and goings that are consistent with all squares in the piece being covered. For the 2-by-1 arrays, this can be accomplished with brute force.
+---+
A | B | C
+---+
D | E | F
+---+
In general, neither ant starts or ends inside this piece. Then the some of the possibilities are
Ant 1: A->B, B->E, E->F; Ant 2: none
Ant 1: A->B, B->C, F->E, E->D; Ant 2: none
Ant 1: A->B, B->C; Ant 2: D->E; E->F
Ant 1: A->B, B->C, D->E, E->F; Ant 2: none .
Now, suppose we have computed the sets (DP tables hereafter) for two adjacent pieces that are the children of one parent piece.
1|2
+---+-- ... --+---+---+-- ... --+---+
A | B | | C | D | | E | F
+---+-- ... --+---+---+-- ... --+---+
G | H | | I | J | | K | L
+---+-- ... --+---+---+-- ... --+---+
1|2
Piece 1 is to the left of the dividing line. Piece 2 is to the right of the dividing line. Once again, there is a small number of possibilities for traffic on the named squares. The DP table for the parent piece is indexed by the traffic at A, B, E, F, G, H, K, L. For each entry, we try all possibilities for the traffic at C, D, I, J, using the children's DP tables to determine whether the combined comings and goings are feasible.