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.
Related
Given a collection of points on a 2D plane, I want to find collections of X points that are within Y of each other. For example:
8|
7| a b
6|
5| c
4|
3| e
2| d
1|
-------------------------
1 2 3 4 5 6 7 8 9 0 1
a, b, c and d are points on the 2D plane. Given arguments of 3 for the number of points (X) and 3 for the distance (Y), the algorithm would return [[a, b, c]]. Some examples:
algorithm(X = 3, Y = 3) returns [[a, b, c]]
algorithm(X = 2, Y = 3) returns [[a, b, c], [d, e]] -- [a, b, c] contains at least two points
algorithm(X = 4, Y = 3) returns [] -- no group of 4 points close enough
algorithm(X = 5, Y = 15) returns [[a, b, c, d, e]]
Constraints:
x and y axis (the numbers above) are both 10,000 units long
there are 800 points (a, b, c, d etc) on the graph
I don't think it matters, but I'm using JavaScript
Things I've tried:
I actually care about outputting new points that are close to more than one input point, so I tried iterating on a grid and 'looking around' it using Pythagoras to find each point a given distance away. This is too slow given the total area. See the source here.
You can also see the data size in real data test.
DBSCAN, which seems to have a different purpose - I know how big I want my cluster size to be.
I'm currently trying to compare points to each other and build up close pairs, then close triplets, etc, until the end, but this seems to be going down a bit of an inefficiency hole also. I'm going to continue and try some kind of hashing or dictionary to avoid these loops.
With only 800 points, you can probably just build the graph by comparing each pair, then run Bron--Kerbosch to find maximal cliques. Here's a legit-seeming Javascript implementation of that algorithm: https://github.com/SeregPie/almete.BronKerbosch
Consider the following example:
I have a list of 5 items, each with their occurrence with either 1 or 0:
{a, b, c, d, e}
The restricted combinations are as follows:
the occurrence of a, c, and e cannot be 1 at any given time.
the occurrence of b, d, and e cannot be 1 at any given time.
basically, if found in database that occurrence of a and c is already 1, and if a given input is e (giving e an occurrence of 1) is not allowed (clause 1) or vice versa.
another example, d and e has an occurrence of 1 respectively in the database, a new input of b will not be allowed (following clause 2).
An even more solid example:
LETTER | COUNT(OCCURRENCE)
------------------------------
a | 1
b | 1
c | 1
d | 0
e | 0
Therefore, a new input of e would be rejected because of the violation of clause 1.
What is the best algorithm/practice for this solution?
I thought of having many if-else statements, but that doesn't seem efficient enough. What if I had a dynamic list of elements instead? Or at least have a better extensibility to this piece of program.
As mentioned by BKassem(I think) in the comments(removed for whatever reason).
The algorithm for this scenario:
(count(a) * count(c) * count(e)) == 0 //proceed to further actions
Worked flawlessly!
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.
Is there a classical algorithm to solve the following problem.
Assume the union find algorithm without existential quantifiers
has the following input:
x1 = y1 /\ .. /\ xn = yn
It will then build some datastructure u, so that I can check
u.root(x)==u.root(y), to decide whether x and y are in the same
subgraph.
The input can be characterized by the following grammar:
Input :== Var = Var | Input /\ Input
Assume now we also allow existential quantifiers:
Input :== Var = Var | Input /\ Input | exists Var Input
What union find algorithm could deal with such an input.
I am still assuming that the algorithm builds some datastructure
u, where I can check via u.root(x)==u.root(y) whether x and
y are in the same subgraph.
Additionally u.root(x) should throw an exception when used
with a bound variable. These variables should all have been
eliminated and not anymore part of datastructure. Means
the subgraph should have been accordingly reduced, without
changing the validity of the result.
Bye
Here is a sketch of an algorithm. It will traverse the AST, and
feed a special union find algorithm. First the traversal:
traverse((X = Y)) :- add_conn(X, Y).
traverse(exists(X,I)) :- push_var(X), traverse(I), pop_var_remove_conn(X).
traverse((A /\ B)) :- traverse(A), traverse(B).
The special union find algorithm works with a list. This list defines
the weight of the nodes, the head of list has weight 0, the second element
weight 1, etc... add_conn(X,Y) first computes X'=root(X) and Y'=root(Y). The
less weighted of X' and Y' is connected to the more weighted one.
push_var(X) adds X to the front of the list. Making it the less weighted
node. pop_var_remove_conn(X) removes X again from the list, and removes a
possibly established connection from X to some other node as well.
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.