I have a board game for mobile application shown in this link: http://i45.tinypic.com/23u8u1h.png
The starting point can be any cell. the winner is the one who connects his/her vertically (green player) or horizontally (red player).
The nodes are the colored cells. The white cells can be considered weight maybe? I am not sure how to implement it, but when I think of Dijkstra algorithm, I believe that it would take a lot of time to compute till it comes with the correct answer when the board is in this state: http://i50.tinypic.com/35ivofd.png (I have to apply the algorithm on those four green cells)
I want an algorithm that tells me that " http://i48.tinypic.com/28c2ijl.png " black, brown, blue and purple paths are the shortest one within reasonable of time.
Thanks in advance.
I think Dijkstra will work just fine here, especially in conjuction with Union Find algorithm used to connect fields adjacent to each other and filled with color other than white. Edges leading to white fields cost 1, edges leading to own fields cost 0 and edges leading to enemy fields cost infinity (e.g. mn). Then, you aren't going to run Dijkstra on nodes representing individual fields, but on unions of these fields (clusters of non-white colored fields).
Dijkstra will work here in approximately O(mn log^2(mn)), where n and m are dimensions of the board, and Union Find will work in O(log mn) time with simple optimalizations, mentioned at the bottom of the linked article.
Related
I need to map blue objects to red ones by distance. The center of each object is known. The yellow and green objects, if they are shown, are hints. They help to decide which red object is more important.
For example, in the situation shown in image below:
The bottom blue object should be mapped to the bottom most right red object since both green and yellow objects are very close to that red object.
The right blue object should be mapped to top-right red object since it's closer to it.
I have a naive solution, but I'm not quite sure what to do instead of "????" below
Do you have any suggestions?
My naive solution in sort of pseudo-code:
for each BLUE:
find group P=(YELLOW_BLUE, GREEN_BLUE and RED_BLUE) when each object in P is the closest to BLUE
vector<RED> redCandidates
for each O in P:
if O is YELLOW OR O is GREEN
find closest RED to O
insert RED to redCandidates
if size of redCandidates is 0 -> return RED_BLUE
else if size of redCandidates is 1 -> return redCandidates[0] since hint has more weight to the decision
else if size of redCandidates is > 1 -> ????
UPDATE1
After looking into Minimum Cost Flow problem suggested by #ldog, I decided to use Hungarian Algorithm. I created bipartite graph where each blue node is connected to each red node and the weights on the edges are the distance between blue and red.
Now, before I solve the graph, I need to apply rewards on the edges where yellow/green are close to red. I don't quite understand how to do that.
Let's say distance between blue 1 and the red 4 is D_1_4 = 10 and the distance between the yellow hint 11 and the red 4 is D_4_11 = 3. So, because D_1_4 > D_4_11, should I just add reward to the edge 1_4? Or, should I add the reward to each edge that enters node 4, meaning edges 1_4, 2_4 and 3_4?
It seems your question is not fully formed and you are looking for a decent formulation of the things that you expressed in words.
Here are some suggestions:
Use intersection over union for dealing with how to assign similarity for overlapping areas.
There are many ways you could try to make what you expressed in words quantified, and therefore able to be optimized. One reasonable way to quantify what you expressed in words is as a minimization problem I will discuss below.
The minimization should assign one blue box to exactly one red box (given what you told me.) The green and yellow boxes are hints and are not included in this constraint, they are simply used to modify which red box is preferential over others. To formalize what you described in words, we have the set of red boxes R and the set of blue boxes B. There are m red boxes and n blue boxes with m >= n. Each pairing of blue box i with red box j has a preference w_{ij} (this preference is pre-calculated accounting for the hint boxes as well as spatial proximity.)
We wish to compute:
max \sum_{i<j} w_{ij}x_{ij}
such that
\sum_{k} x_{ik} = 1, \sum_{l} x_{lj} = 1, x_{ik} \in {0,1}
The variable x_{ij} is 1 if and only if blue box i is assigned to red box j, it is 0 otherwise.
This problem (is Totally Unimodular) and can be solved in polynomial time. In fact, it can be solved as an instance of the common Minimum Cost Flow problem. To do this, define a node in a graph for each blue box i, and a node in a graph for each red box j. Connect each blue node to each red node (directed blue->red) with an edge with weight -w_{ij} and capacity 1. Connect each blue node to the source (directed source -> blue) with an edge of capacity 1 and weight 0. Connect each red node to the sink (directed red->sink) with an edge of capacity 1 and weight 0. Give the source a supply of n and the sink a demand of n. Compute the Minimum Cost Flow on this graph (see for example lemon) and the resulting flow yields the maximum solution (alternatively minimum flow.)
Having described this in detail, I see this is already a common approach [1] to solve exactly problems like yours. Here is an implementation.
YMMV depending on how good you make your weights to be. You may want to try a machine learning approach to determine optimal weights using a ground truth dataset and an iterative refinement. The refinement can be computed for a fixed set of blue and red ground truth boxes by refining the weights w_{ij} until all other possible assignments other than the ground truth have a lower score of the optimization than the ground truth. This can be done iterative using any max-margin learning framework or technique, combined with the method I described above (and apparently is described in [1].)
[1] Zhang, Li, Nevatia: Global data association for multi-object tracking using network flows, CVPR (2008).
I'm developing a game similar to Pacman: consider this maze:
Each white square is a node from the maze where an object located at P, say X, is moving towards node A in the right-to-left direction. X cannot switch to its opposite direction unless it encounters a dead-end such as A. Thus the shortest path joining P and B goes through A because X cannot reverse its direction towards the rightmost-bottom node (call it C). A common A* algorithm would output:
to get to B from P first go rightward, then go upward;
which is wrong. So I thought: well, I can set the C's visited attribute to true before running A* and let the algorithm find the path. Obviously this method doesn't work for the linked maze, unless I allow it to rediscover some nodes (the question is: which nodes? How to discriminate from useless nodes?). The first thinking that crossed my mind was: use the previous method always keeping track of the last-visited cell; if the resulting path isn't empty, you are done. Otherwise, when you get to the last-visited dead-end, say Y, (this step is followed by the failing of A*) go to Y, then use standard A* to get to the goal (I'm assuming the maze is connected). My questions are: is this guaranteed to work always? Is there a more efficient algorithm, such as an A*-derived algorithm modified to this purpose? How would you tackle this problem? I would greatly appreciate an answer explaining both optimal and non-optimal search techniques (actually I don't need the shortest path, a slightly long path is good, but I'm curious if such an optimal algorithm running as efficiently as Dijkstra's algorithm exists; if it does, what is its running time compared to a non-optimal algorithm?)
EDIT For Valdo: I added 3 cells in order to generalize a bit: please tell me if I got the idea:
Good question. I can suggest the following approach.
Use Dijkstra (or A*) algorithm on a directed graph. Each cell in your maze should be represented by multiple (up to 4) graph nodes, each node denoting the visited cell in a specific state.
That is, in your example you may be in the cell denoted by P in one of 2 states: while going left, and while going right. Each of them is represented by a separate graph node (though spatially it's the same cell). There's also no direct link between those 2 nodes, since you can't switch your direction in this specific cell.
According to your rules you may only switch direction when you encounter an obstacle, this is where you put links between the nodes denoting the same cell in different states.
You may also think of your graph as your maze copied into 4 layers, each layer representing the state of your pacman. In the layer that represents movement to the right you put only links to the right, also w.r.t. to the geometry of your maze. In the cells with obstacles where moving right is not possible you put links to the same cells at different layers.
Update:
Regarding the scenario that you described in your sketch. It's actually correct, you've got the idea right, but it looks complicated because you decided to put links between different cells AND states.
I suggest the following diagram:
The idea is to split your inter-cell AND inter-state links. There are now 2 kinds of edges: inter-cell, marked by blue, and inter-state, marked by red.
Blue edges always connect nodes of the same state (arrow direction) between adjacent cells, whereas red edges connect different states within the same cell.
According to your rules the state change is possible where the obstacle is encountered, hence every state node is the source of either blue edges if no obstacle, or red if it encounters an obstacle (i.e. can't emit a blue edge). Hence I also painted the state nodes in blue and red.
If according to your rules state transition happens instantly, without delay/penalty, then red edges have weight 0. Otherwise you may assign a non-zero weight for them, the weight ratio between red/blue edges should correspond to the time period ratio of turn/travel.
Suppose some figure on the squared paper. Sides of the figure go straight on the lines of squared paper. Figure may have any (not even convex) shape. How to find the maximum number of dominoes (1x2 rectangular) that can be placed in that figure. It is not allowed to put domino over another one. It is allowed to put domino only in such way, when its sides fall exactly on the lines of squared paper.
Looks like the maximum cardinality matching problem in a bipartite graph. The squares are the vertices and the dominoes are the edges that belong to the matching.
To see that the graph is bipartite, imagine the squares are checkerboard-painted. Black ones only neighbour white ones and vice versa.
You can classify squares by the number of neighbor free squares as type 0, 1, 2, 3 or 4.
I believe that should work:
find a type 1 square, place there a domino in the only possible way and repeat
else, find a free corner formed by two contiguous type 2 and type 3 squares, place there a domino and go to 1
else, place a domino in any type 2 square and go to 1
you are done
Introduction
As part of a larger program (related to rendering of volumetric graphics), I have a small but tricky subproblem where an arbitrary (but finite) triangular 2D mesh needs to be labeled in a specific way. Already a while ago I wrote a solution (see below) which was good enough for the test meshes I had at the time, even though I realized that the approach will probably not work very well for every possible mesh that one could think of. Now I have finally encountered a mesh for which the present solution does not perform that well at all -- and it looks like I should come up with a totally different kind of an approach. Unfortunately, it seems that I am not really able to reset my lines of thinking, which is why I thought I'd ask here.
The problem
Consider the picture below. (The colors are not part of the problem; I just added them to improve (?) the visualization. Also the varying edge width is a totally irrelevant artifact.)
For every triangle (e.g., the orange ABC and the green ABD), each of the three edges needs to be given one of two labels, say "0" or "1". There are just two requirements:
Not all the edges of a triangle can have the same label. In other words, for every triangle there must be two "0"s and one "1", or two "1"s and one "0".
If an edge is shared by two triangles, it must have the same label for both. In other words, if the edge AB in the picture is labeled "0" for the triangle ABC, it must be labeled "0" for ABD, too.
The mesh is a genuine 2D one, and it is finite: i.e., it does not wrap, and it has a well-defined outer border. Obviously, on the border it is quite easy to satisfy the requirements -- but it gets more difficult inside.
Intuitively, it looks like at least one solution should always exist, even though I cannot prove it. (Usually there are several -- any one of them is enough.)
Current solution
My current solution is a really brute-force one (provided here just for completeness -- feel free to skip this section):
Maintain four sets of triangles -- one for each possible count (0..3) of edges remaining to be labeled. In the beginning, every triangle is in the set where three edges remain to be labeled.
For as long as there are triangles with non-labeled edges:Find the smallest non-zero number of unallocated edges for which there are still triangles left. In other words: at any given time, we try to minimize the number of triangles for which the labeling has been partially completed. The number of edges remaining will be anything between 1 and 3. Then, just pick one such triangle with this specific number of edges remaining to be allocated. For this triangle, do the following:
See if the labeling of any remaining edge is already imposed by the labeling of some other triangle. If so, assign the labels as implied by requirement #2 above.
If this results in a dead end (i.e., requirement #1 can no more be satisfied for the present triangle), then start over the whole process from the very beginning.
Allocate any remaining edges as follows:
If no edges have been labeled so far, assign the first one randomly.
When one edge already allocated, assign the second one so that it will have the opposite label.
When two edges allocated: if they have the same label, assign the third one to have the opposite label (obviously); if the two have different labels, assign the third one randomly.
Update the sets of triangles for the different counts of unallocated edges.
If we ever get here, then we have a solution -- hooray!
Usually this approach finds a solution within just a couple of iterations, but recently I encountered a mesh for which the algorithm tends to terminate only after one or two thousands of retries... Which obviously suggests that there may be meshes for which it never terminates.
Now, I would love to have a deterministic algorithm that is guaranteed to always find a solution. Computational complexity is not that big an issue, because the meshes are not very large and the labeling basically only has to be done when a new mesh is loaded, which does not happen all the time -- so an algorithm with (for example) exponential complexity ought to be fine, as long as it works. (But of course: the more efficient, the better.)
Thank you for reading this far. Now, any help would be greatly appreciated!
Edit: Results based on suggested solutions
Unfortunately, I cannot get the approach suggested by Dialecticus to work. Maybe I did not get it right... Anyway, consider the following mesh, with the start point indicated by a green dot:
Let's zoom in a little bit...
Now, let's start the algorithm. After the first step, the labeling looks like this (red = "starred paths", blue = "ringed paths"):
So far so good. After the second step:
And the third:
... fourth:
But now we have a problem! Let's do one more round - but please pay attention on the triangle plotted in magenta:
According to my current implementation, all the edges of the magenta triangle are on a ring path, so they should be blue -- which effectively makes this a counterexample. Now maybe I got it wrong somehow... But in any case the two edges that are nearest to the start node obviously cannot be red; and if the third one is labeled red, then it seems that the solution does not really fit the idea anymore.
Btw, here is the data used. Each row represents one edge, and the columns are to be interpreted as follows:
Index of first node
Index of second node
x coordinate of first node
y coordinate of first node
x coordinate of second node
y coordinate of second node
The start node is the one having index 1.
I guess that next I should try the method suggested by RafaĆ Dowgird... But perhaps I ought to do something completely different for a while :)
If you order the triangles so that for every triangle at most 2 of its neighbors precede it in the order, then you are set: just color them in this order. The condition guarantees that for each triangle being colored you will always have at least one uncolored edge whose color you can choose so that the condition is satisfied.
Such an order exists and can be constructed the following way:
Sort all of the vertices left-to-right, breaking ties by top-to-bottom order.
Sort the triangles by their last vertex in this order.
When several triangles share the same last vertex, break ties by sorting them clockwise.
Given any node in the mesh the mesh can be viewed as set of concentric rings around this node (like spider's web). Give all edges that are not in the ring (starred paths) a value of 0, and give all edges that are in the ring (ringed paths) a value of 1. I can't prove it, but I'm certain you will get the correct labeling. Every triangle will have exactly one edge that is part of some ring.
Let's say you have a grid like this (made randomly):
Now let's say you have a car starting randomly from one of the while boxes, what would be the shortest path to go through each one of the white boxes? You can visit each white box as many times as you want and can't jump over the black boxes. The black boxes are like walls. In simple words you can move from white box to white box only.
You can move in any direction, even diagonally.
Two subquestions:
Assume you know the position of all black boxes before moving.
Assume you only know the position of a black box when you are in a white box adjacent to it.
You should model the problem as a complete graph where the distance between two nodes (white boxes) is the length of the shortest path between those nodes. Those path lengths can be calculated by the Floyd-Warshall algorithm. Then, you can treat it as "Traveling salesman", like glowcoder wrote.
EDIT: to make it more clear: you can describe each "interesting" path through the maze by a sequence of different white boxes. Because if you have an arbitrary path visiting each white box, you can split it up into sub-paths each one ending at a new white box not visited so far. Each of this sub-paths from white box A to B can be replaced by a shortest sub-path from A to B, that's why you need the shortest-paths-between-all-pairs-of-nodes matrix.
This seems to be an NP-Complete problem.
Hamiltonian Path in grid graph is NP-Complete has been shown here: Hamilton Paths in Grid Graphs.
Note grid graph = subgraph of the complete grid.
Of course, I haven't read that paper, so confirm it first, especially the diagonal movement allowed part.
Doc has got it. I'll add that the black boxes only change the distance between all pairs of white boxes. Further elaboration - if there's a black box on the diagonal between any two white boxes (easily checked), you need to calculate a shortest path to get the distance. Once you have a distance matrix, then solve a TSP or a Hamiltonian Path by solving a TSP after creating a dummy node with length zero to all other nodes.
The key is that in order to formulate and solve the TSP (or any problem formulation for that matter), you MUST have a distance matrix to start with. The distance matrix isn't specified at the start so it must be developed from scratch.
while the TSP based heuristic is a reasonable approach, it's not clear it gives the optimal answer. The problem (as Moron points out) is the spanning trail problem, and in the link provided in the comment, there are many special cases for which there are linear time optimal solutions. One catch that makes the OP's problem different from the grid graph formulation used in the cited paper is the ability to traverse diagonally, which changes the game quite a bit.
This is similar to the Knights Tour problem, where a typical solution evaluates all possible routes originating from the starting square. When a tour cannot be completed, then backtracking is used to return to back up on previous decisions. Your problem is more relaxed since you can visit squares more than once. The Knights tour and Travelling Saleman problems typically require visiting each square exactly once.
See http://en.wikipedia.org/wiki/Knight's_tour
Try building it as a graph (where each node has at most 8 other nodes) and treat it like the http://en.wikipedia.org/wiki/Travelling_salesman_problem