The pseudocode for the A* algortihm on wikipedia semms to not be right, but i somebody smarter than me probably made it, so i doubt that is true.
Im having trouble understanding how:
if tentative_gScore < gScore[neighbor]
can ever be true. I'll try to prove it here (also, current starts with being the start node, because it is the only thing in openSet at first):
tentative_gScore = distance(start, current) + distance(current, neighbor)
Because current is start, distance(start, current) is 0. therefore tentative_gScore is just:
tentative_gScore = distance(current, neighbor)
and if we replace current with start, and compare the two gScore's:
tentative_gScore = distance(start, neighbor)
gScore[neighbor] = distance(start neighbor)
I'm really having trouble seeing what i am misunderstanding, or is the pseudocode just wrong? afterall it is from wikipedia, and everyone can edit there.
The answer is that gScore[neighbor] is the best distance recorded so far to neighbor. But we have not yet recorded the possibility of passing through current. And so we may discover an improvement.
This is dramatically demonstrated at the start when gScore is given a default value of Infinity. That records the fact that we have NO routes to anything except start. And makes it really easy to find improvements!
The one important guarantee that the algorithm depends on is that, by the time that we actually make a node current, we have discovered the best possible route to it. But until that point we can continue to improve distances.
Related
I'm a computing science student and I currently have a subject about artificial intelligence. This subject covers various best-first search pathfinding algorithms, such as A* search.
My study material claims that it is usual to pick a heuristic following the next rule:
0 ≤ h(n) ≤ h(n)*
I understand this bit, but after that the material claims your heuristic should be optimistic or close to f(n). According to the material this should result in less nodes being expanded.
Why (and should you) you pick a heuristic as close as possible to f(n) and why does this result in (a lot) less nodes being expanded?
Thanks in advance for replying, you'll be helping me out so much for my next exam!
Example:
Find the shortest way to a specific field on a chess-board like field with obsticles.
Lets say you only have the possibility to go left right up or down.
A heuristic gives you a guess how many steps to the goal you will need for every one of the four possible fields you can go at every iteration.
Now your heuristic can be:
allways optimal: if thats the case you will allways go to the correct next field and initially find your best path.
allways lower or optimal: here it might occur that you go to the wrong field some time but if you reached your goal (or a view fields later) your algorithm will see that the path you found (or the actual heuristic) is greater than the heuristic of the field you should have gone before.
In other words: your heuristic gives you allways a lower or equal number than the actual steps you have to make. Hence if you find a path shorter or equal to all heuristics of fileds you didn't visit you can be sure your path is optimal.
"sometimes higher" if your heuristic gives you sometimes more steps than you would actually need you never can be sure that the path you have found is an optimal path!
So the worst thing to happen is an overestimation of the way by your heuristic because you might not find the optimal path. Therfore you have the condition 0 ≤ h(n) ≤ h(n)*
And the closer you hare to your optimal heuristic, the less "wrong fields" you visit in your search. And the less wrong fields you visit, the faster you are.
I am learning the Alpha-Beta pseudo code and I want to write a simplest pseudo code for Alpha Beta pruning.
I have written the pseudo code for Minimax:
function minimax(node, depth)
if node is a terminal node or depth ==0
return the heuristic value of node
else
best = -99999
for child in node
best = max(best, -minimax(child, depth-1))
return best
However, I don't know how to modify it into alpha-beta pruning. Can anyone help?
In Alpha-Beta, you keep track of your guaranteed score for one position. You can stop immediately if you found a move that is better than the score that the opponent already has guaranteed in its previous position (one move before).
Technically, each side keeps track of its lowerbound score (alpha), and you have access to the opponent's lowerbound score (beta).
The following pseudo-code is not tested, but here is the idea:
function alphabeta(node, depth, alpha, beta)
if node is a terminal node or depth ==0
return the heuristic value of node
else
best = -99999
for child in node
best = max(best, -alphabeta(child, depth-1, -beta, -alpha))
if best >= beta
return best
if best > alpha
alpha = best
return best
At the start of the search, you can set alpha to -INFINITY and beta to +INFINITY. Strictly speaking, the sketched algorithm is not alpha-beta but Negamax. Both are identical, so this is just an implementation detail.
Note that in Alpha-Beta, the move ordering is crucial. If most of the time, you start with the best move, or at least a very good move, you should see a huge improvement over Minimax.
An additional optimization to start with restricted alpha beta windows (not -INFINITY and +INFINITY). However, if your assumption turns out wrong, you have to restart the search with a more open search window.
I am trying to prove the following algorithm to see if a there exists a path from u to v in a graph G = (V,E).
I know that to finish up the proof, I need to prove termination, the invariants, and correctness but I have no idea how. I think I need to use induction on the while loop but I am not exactly sure how.
How do I prove those three characteristics about an algorithm?
Disclaimer: I don't know how much formal you want your proof to be and I'm not familiar with formal proofs.
induction on the while loop: Is it true at the beginning? Does it remain true after a step (quite simple path property)?
same idea, induction on k (why k+1???): Is it true at the beginning? Does it remain true after a step (quite simple path property)?
Think Reach as a strictly increasing set.
Termination: maybe you can use a quite simple property linked to the diameter of the graph?
(This question could probably be better answered elsewhere, on https://cstheory.stackexchange.com/ maybe?)
There is a lot of possibilities. For example, for a Breadth First Search, we note that:
(1) The algorithm never visits the same node twice.(as any path back must be >= the length that put it in the discovered pile already.
(2) At every step, it adds exactly one node.
Thus, it clearly must terminate on any finite graph, as the set of nodes which are discoverable cannot be larger than the set of nodes which are in the graph.
Finally, since, give a start node, it will only terminate when it has reached every node which is connected by any path to the start node, it will always find a path between the start and target if it exists.
You can rewrite these logical steps above in deeper rigour if you like, for example, by showing that the list of visited nodes is strictly increasing, and non convergent (i.e. adding one to something repeatedly tends to infinity) and the termination condition must be met at at most some finite value, and a non convergent increasing function always intersects a given bound exactly once.
BFS is an easy example because it has such simple logic, but proving these things for a given algorithm may be extremely tricky.
There's a map with points:
The green number next to each point is that point's ID and the red number is the bonus for that point. I have to find fastest cycle that starts and ends at the point #1 and that gains at least x (15 in this case) bonus points. I can use cities several times; however, I will gain bonus points only once.
I have to do this with the backtracking algorithm, but I don't really know where to start. I've stutied about it, but I can't see the connection between this and a backtracking.
The output would look like this:
(1,3,5,2,1) (11.813 length)
Backtracking is a technique applied to reduce the search space of a problem. So, you have a problem, you have a space with optimal and non-optimal solutions, and you have to pick up one optimal solution.
A simple strategy, in your problem, is to generate all the possible solutions. However, this solution would traverse the entire space of solutions, and, some times, being aware that no optimal solution will be found.
That's the main role of backtracking: you traverse the space of solutions and, when you reach a given point where you know no optimal answer will be achieved if the search continue on the same path, you can simply repent of the step taken, go back in the traversal, and select the step that comes right after the one you found to be helpless.
In your problem, since the nodes can be visited more than once, the idea is to maintain, for each vertex, a list of vertices sorted decreasingly by the distance from the vertex owner of the list.
Then, you can simply start in one of the vertices, and do the walk on the graph, vertex by vertex, always checking if the objective is still achievable, and backtracking in the solution whenever it's noticed that no solution will be possible from a certain point.
You can use a recursive backtracking algorithm to list all possible cycles and keep the best answer:
visitCycles(list<Int> cycleSoFar)
{
if cycle formed by closing (cycleSoFar) > best answer so far
{
best answer so far = cycle formed by closing (cycleSoFar)
}
if (cannot improve (cycleSoFar))
{
return
}
for each point that makes sense
{
add point to cycleSoFar
visitCycles(cycleSoFar)
remove point from cycleSoFar
}
}
To add a bit more detail:
1) A cycle is no good unless it has at least 15 bonus points. If it is any good, it is better than the best answer so far if it is shorter.
2) As you add more points to a cycle you only make it longer, not shorter. So if you have found a possible answer and cycleSoFar is already at least as long as that possible answer, then you cannot improve it and you might as well return.
3) Since you don't get any bonus points by reusing points already in the cycle, it doesn't make sense to try adding a point twice.
4) You may be able to speed up the program by iterating over "each point that makes sense" in a sensible order, for instance by choosing the closest point to the current point first. You might save time by pre-computing, for each point, a list of all the other points in ascending order of distance (or you might not - you might have to try different schemes by experiment).
Odd question here not really code but logic,hope its ok to post it here,here it is
I have a data structure that can be thought of as a graph.
Each node can support many links but is limited to a value for each node.
All links are bidirectional. and each link has a cost. the cost depends on euclidian difference between the nodes the minimum value of two parameters in each node. and a global modifier.
i wish to find the maximum cost for the graph.
wondering if there was a clever way to find such a matching, rather than going through in brute force ...which is ugly... and i'm not sure how i'd even do that without spending 7 million years running it.
To clarify:
Global variable = T
many nodes N each have E,X,Y,L
L is the max number of links each node can have.
cost of link A,B = Sqrt( min([a].e | [b].e) ) x
( 1 + Sqrt( sqrt(sqr([a].x-[b].x)+sqr([a].y-[b].y)))/75 + Sqrt(t)/10 )
total cost =sum all links.....and we wish to maximize this.
average values for nodes is 40-50 can range to (20..600)
average node linking factor is 3 range 0-10.
For the sake of completeness for anybody else that looks at this article, i would suggest revisiting your graph theory algorithms:
Dijkstra
Astar
Greedy
Depth / Breadth First
Even dynamic programming (in some situations)
ect. ect.
In there somewhere is the correct solution for your problem. I would suggest looking at Dijkstra first.
I hope this helps someone.
If I understand the problem correctly, there is likely no polynomial solution. Therefore I would implement the following algorithm:
Find some solution by beng greedy. To do that, you sort all edges by cost and then go through them starting with the highest, adding an edge to your graph while possible, and skipping when the node can't accept more edges.
Look at your edges and try to change them to archive higher cost by using a heuristics. The first that comes to my mind: you cycle through all 4-tuples of nodes (A,B,C,D) and if your current graph has edges AB, CD but AC, BD would be better, then you make the change.
Optionally the same thing with 6-tuples, or other genetic algorithms (they are called that way because they work by mutations).
This is equivalent to the traveling salesman problem (and is therefore NP-Complete) since if you could solve this problem efficiently, you could solve TSP simply by replacing each cost with its reciprocal.
This means you can't solve exactly. On the other hand, it means that you can do exactly as I said (replace each cost with its reciprocal) and then use any of the known TSP approximation methods on this problem.
Seems like a max flow problem to me.
Is it possible that by greedily selecting the next most expensive option from any given start point (omitting jumps to visited nodes) and stopping once all nodes are visited? If you get to a dead end backtrack to the previous spot where you are not at a dead end and greedily select. It would require some work and probably something like a stack to keep your paths in. I think this would work quite effectively provided the costs are well ordered and non negative.
Use Genetic Algorithms. They are designed to solve the problem you state rapidly reducing time complexity. Check for AI library in your language of choice.