im not too sure how to implement this...
I need to create a weighted directed graph based on the water jug problem from the movie Die Hard 3 (http://www.wikihow.com/Solve-the-Water-Jug-Riddle-from-Die-Hard-3).
I need to create nodes for all the possible moves (fill, empty, pour). After i need to find the shortest path to the solution. But i am have trouble creating this graph. I am using my own created linked list/node.
Any help with the algorithm to create this graph would be great. Thanks.
ex) given 3 gallon, 5 gallon. Get 4 gallons in the 5 gallon jug. I need to create a graph of all the possible moves to get to 4 gallons. Each different gallon represents a different node.
Happy Thanksgiving =)
Presumably each node holds two positive integers -- number of gallons in the 3-gal jug, number of gallons in the 5-gal jug. Arcs, aka edges (directed), are the "moves" (and labeled with the action the arc represents) -- apparently you also have an unnamed tap handy, since you can always fill either of the jugs; you can also always empty a jug away (so you also have a sink); and so forth (other moves all involve moving water from one gallon to the other, until either the first one is empty, or the second one is full). It's no doubt better to avoid generating legal but useless arcs ("moves"), such as "filling" a jug that's already full, or undoing a move you just made (such as emptying a jug you just filled from the tap), though adding such arcs will only mean a little more work, not an incorrect solution.
So start with (0, 0) -- both jugs full, as you have at the start. Clearly the two arcs from here take you to (3, 0) and (0, 5) respectively (filling one or the other from the tap), and so on. Hope this helps!
At each step you have 6 different options
1.A=full
2.B=full
3.A->B
4.B->A
5.A=0
6.B=0
And here you go.
Put states in lookup table and check that none of solution will repeat. This is also stopping condition.
size of lookup table is A * B, and calculating hash is just A*vol(B)+B
In table[A*vol(B)+B] save from witch position you came from.
Make initialisation of table elements on -1 (i supose that first index is 0 in your language)
Related
I have a set of 2D points where all values are integers. No points are identical. I want to draw polylines/paths/whatever through all the points with a few restrictions:
1: A line should always move in the positive x-direction. p1.x < p2.x < ...
2: Lines may never cross each other.
3: All polylines needs to begin at x = 0 and end at x-max.
4: It should use as few polylines as possible (or a number defined by me).
I have attached an image of a sample set of points. And a hand made solution I drew with a pencil and ruler.
It's trivial to find a solution by hand, but I have no idea how to describe my process in logical terms. I don't need an optimal solution (whatever that means). It doesn't need to be fast.
Point set (Disregard colors)
Connected Points
My current solution is to step through the set along the x-axis and then try all viable combinations and choosing the one with the lowest total vertical movement. This works in some cases but not all. And it seems to over-complicate the problem.
My next idea is to do a brute force approach with backtracking when collisions occour. But that also seems a bit much.
For anyone wondering the points are actually notes on sheet music. The x-axis is time and the y-axis is pitch. The polylines represent the movement of robotic fingers playing a piano.
We will find a solution which uses the minimum number of robotic fingers (least number of polylines). The trick is to consider your input as a Partially ordered set (or poset). Each point in your input is an element of the poset, and with the relation (p1.x, p1.y) < (p2.x , p2.y) if and only if p1.x < p2.x. This basically means that two points which have the same x-coordinate are incomparable with each other.
For now, let us forget this constraint: "Lines may never cross each other". We'll get back to it at the end.
What you are looking for, is a partition of this poset into chains. This is done using Dilworth's Theorem. It should be clear that if there are 5 points with the same x-coordinate, then we need at least 5 different polylines. What Dilworth's says is that if there is no x-coordinate with more than 5 points on it, then we can get 5 polylines (chains) which cover all the points. And it also gives us a way to find these polylines, which I'm summarizing here:
You just create a bipartite graph G = (U,V,E) where U = V = Set of all input points and where (u,v) is an edge in G if u.x < v.x. Then find a maximum matching, M, in this graph, and consider the set of polylines formed by including u and v in the same polyline whenever there is an edge (u,v) in M.
The only issue now, is that some of these polylines could cross each other. We'll see how to fix that:
First, let us assume that there are only two polylines, L1 and L2. You find the first instance (minimum x-coordinate) of their crossing. Suppose the two line segments which cross each other are AB and CD:
We delete AB and CD and instead add AD and CB:
The polylines still cross each other, but their point of crossing has been delayed. So we can keep repeating this process until there is no crossing left. This takes at most n iterations. Thus we know how to 'untangle' two polylines.
[The edge case of B lying on the segment CD is also handled in the exact same way]
Now, suppose we have k different polylines which the maximum matching has given us: L1, L2, ..., Lk. WLOG, let us assume that at x = 0, L1's y-coordinate is lower than L2's y-coordinate, which is lower than L3's and so on.
Take L1 and find the first time that it crosses with any other polyline. At that crossing, applying the swapping operation as above. Keep repeating this, until L1 does not cross with any other polyline. Now, L1 is at the 'bottom', and doesn't cross with any other line. We now output L1 as one of the final polylines, and delete it from our algo. We then repeat the same process with L2, and after outputting it, delete it, and repeat with L3, and so on.
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.
I'm trying to understand the paper "Clipping of Arbitrary Polygons with Degeneracies" by E. L Foster and J. R. Overfelt [1], which claims to extend the classic Greiner-Hormann polygon clipping algorithm by handling of degeneracies.
However, I ran into some difficulties with the procedure they describe. Consider the situation depicted on Figure 6(c) and suppose the polygons are oriented in the same way. Start the labeling phase from the I5 (as opposed from I1, as they do): for both subject polygon S and clipping polygon C, I5 has previous and next labels (on, on). Therefore, according to Table 1, first remove the intersection flag (1), then label current and neighbor nodes as "in/in" (2). This agrees with the Example. Next, I6 has (in/out) for S, and (in/on) for C. Table 1 says "en/en" (or "ex/ex", not clear whether "prev" applies to columns or rows). Then, Table 2 says, remove intersection "en/en" and label "in" (presumably "in/in") [2]. But the example states "ex/en", and not "in/in".
Please, can anyone explain to me why is this happening? How to arrive at "ex/en"? Does it really matter, where I start the labeling phase?
[1] https://github.com/erichlf/PolyClipping/blob/master/Paper/PolyClip.pdf
[2] They also say "the entry/exit flag is set to be equal to the previous node’s entry/exit flag" which by luck also happens to be "in/in" but it is not very clear how does the Table 2 relates to this rule.
It appears that this is a mistake in the paper. Labeling based on Table 1 would first give ex/ex and then based on table 2 would produce out/out. The case where we go in->on or even ex->on is more complicated than the explanation in the paper.
What appears to work would be if the intersection is in->on check the neighbor and if the neighbor is not in->on then label the current as the opposite of the neighbor. So in the case of I6 we would label it as ex/en. Now if we had a case where both the neighbor and current were in->on we would want to check the next point in the sequence, i.e. I2 and S2. If both points in the sequence are on then remove this intersection and label as (in,in). Otherwise the label should be en if this next point is in and ex if the next point is out.
The case where we go from out->on would be the opposite.
I hope this answers your question.
I'm trying to find a solution for pathfinding in a trains game where there are different kinds of bifurcations. I want the train to go from one rail to another, everything is implemented except the pathfinding.
I need to get a list of rails so the train can follow. Now, the problem is how do I get the list.
I've tried A*, didn't work because it stops searching if the node (rail) is already visited. This is a problem, because maybe the way to reach a point is by travelling through the longest route.
Tried flood fill, this time made it not stop searching if already visited, the problem is how do I reconstruct the path and how does it choose that it can't go backwards again.
The thing is that there are cases in which the train must go through a rail multiple times to reach its destination.
Any ideas?
Starting point is A, end B. As you see the green path is the way it should travel. The balck circle are the rails which the train will step more than once, in this case 2 times.
And obviously, you need to come from 2 black to get to 3 red. You can't just go 1black->2red->1red->3red.
Looking at this picture
It appears your problem would be represented well by a directed graph. Give each stop and each junction two nodes in the graph, one for each direction of the train. Dijkstra's algorithm works perfectly on directed graphs, so once you have the problem in that form, the rest is easy.
So for example, in the picture above, starting from A, we move to junction 1. From there, there's only one place to move to, junction 2, so there'd be an arrow from A --> junction 1 and an arrow from junction 1 --> junction 2. Regardless of which choice you make, you end up at junction 1, but moving in the other direction, so we create a separate node from there. From there, you have the option of going to A or B.
Notice that I removed one of the J1's, since it is superfluous (there's only one place to go).
If the train can stop and turn around at stops like A, we can connect those two nodes by edges in both directions, or just combine them into one node.
You can give the edges weights to specify distances.
Flood fill should really do the thing (I used it in a similar case) - but you only need to work with switches and segments carefully.
Algorithms should be allowed to pass the same segment in different direction, but not in the same. I.e. each segment really should be regarded as two separate.
to reconstruct the path you should assign numbers to segments while flooding them, so that each reached from N-1 is marked with N - then while move backward, tracking segments should be done so that numbers steadily decrease by one.
It is really kind of BFS.
There is a square grid with obstacles. On that grid, there are two members of a class Person. They face a certain direction (up, right, left or down). Each person has a certain amount of energy. Making the persons turn or making them move consumes energy (turning consumes 1 energy unit, moving consumes 5 energy units).
My goal is to make them move as close as possible next to each other (expressed as the manhattan distance), consuming the least amount of energy possible. Keep in mind there are obstacles on the grid.
How would I do this?
I would use a breadth-first search and count a minimal energy value to reach each square. It would terminate when the players meet or there is no more energy left.
I'll make assumptions and remove them later.
Assuming the grid is smaller than 1000x1000 and that you can't run out of energy..:
Assuming they can't reach each other:
for Person1,Person2, find their respective sets of reachable points, R1,R2.
(use Breadth first search for example)
sort R1 and R2 by x value.
Now go through R1 and R2 to find the pair of points that are closest together.
hint: we sorted the two arrays so we know when points are close in terms of their x coordinate. We never have to go further apart on the x coordinate than the current found minimum.
Assuming they can reach each other: Use BFS from person1 until you find person2 and record the path
If the path found using BFS required no turns, then that is the solution,
Otherwise:
Create 4 copies of the grid (call them right-grid, left-grid, up-grid, down-grid).
the rule is, you can only be in the left grid if you are moving left, you can only be in the right grid if you are moving right, etc. To turn, you must move from one grid to the other (which uses energy).
Create this structure and then use BFS.
Example:
Now the left grid assumes you are moving left, so create a graph from the left grid where every point is connected to the point on its left with the amount of energy to move forwards.
The only other option when in the left-grid is the move to the up-grid or the down-grid (which uses 1 energy), so connect the corresponding gridpoints from up-grid and left-grid etc.
Now you have built your graph, simply use breadth first search again.
I suggest you use pythons NetworkX, it will only be about 20 lines of code.
Make sure you don't connect squares if there is an obstacle in the way.
good luck.