7

I wonder what are the advantages and disadvantages of these two algorithms. I want to write AddEmUp C++ solved, but I'm not sure which (IDA or DFID) algorithm should I use.

The best article I found is this one, but it seems too old - '93. Any newer?

I think IDA* would be better, but.. ? Any other ideas?

Any ideas and info would be helpful.

Thanks ! (:

EDIT: Some good article about IDA* and good explanation of the algorithm?

EDIT2: Or some good heuristic function for that game? I have no idea how to think of some :/

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
  • Isn't DFID just a special case of IDA* where the heuristic function is constantly 0? So essentially you're asking whether you should use a heuristic function. – huaiyuan Dec 06 '10 at 17:46
  • 1
    @huaiyuan: It's a special case, but not in any useful sense. – Fred Foo Dec 06 '10 at 18:26

3 Answers3

11

The Russel & Norvig book is an excellent reference on these algorithms, and I'll give larsmans a virtual high-five for suggesting it; however I disagree that IDA* is in any appreciable way harder to program than A*. I've done it for a project where I had to write an AI to solve a sliding-block puzzle - the familiar problem of having a N x N grid of numbered tiles, and using the single free space to slide tiles around until they are in ascending order.

Recall:

F(n) = g(n) + h(n).

TotalCost = PathCost + Heuristic.

g(n) = Path cost, the distance from the initial to the current state

h(n) = Heuristic, the estimation of cost from current state to end state. To be an admissible heuristic (and thus ensure A*'s optimality), you cannot in any case overestimate the cost. See this question for more info on the effects of overestimating/underestimating heuristics on A*.

Remember that Iterative Deepening A* is just A* with a limit on the F value of nodes you are allowed to traverse. This FLimit increases with each outer iteration; with each iteration you are deepening the search.

Here's my C++ code implementing both A* and IDA* to solve the aforementioned sliding block puzzle. You can see that I use a std::priority_queue with a custom Comparator to store Puzzle states in the queue prioritized by their F value. You will also note that the only difference between A* and IDA* is the addition of an FLimit check and an outer loop that increments this FLimit. I hope this helps shed some light on this subject.

Community
  • 1
  • 1
Aphex
  • 7,390
  • 5
  • 33
  • 54
  • @Aphex In your implementation, A* and the final iteration of IDA* uses the same space. The original proposed implementation (See http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.91.288 ), the author uses Depth-first search in each iteration of IDA* with the advantage that there is no need to store open and closed lists of A* (there is a visited list during DFS which needs to be stored if the graph is not a tree). – amit kumar Sep 17 '11 at 18:31
  • That is the idea of IDA*; the chance that you might find the solution within a certain (hopefully shallow) depth without having to traverse deeper nodes. What you and that article are describing appears to be IDDFS - Iterative Deepening Depth-First Search (also known as DFID) - not Iterative Deepening A*. – Aphex Sep 19 '11 at 14:40
  • @Aphex the article quoted is the original publication of IDA*. The algorithm was introduced because of its reduced memory use (which make it applicable to the particular problem tackled in the article, solving a Rubik's cube, whereas A* or an A* with a depth limit wouldn't). – Nestor Demeure Oct 28 '21 at 20:32
4

Check out Russell & Norvig, chapters 3 and 4, and realize that IDA* is hard to program correctly. You might want to try recursive best first search (RBFS), also described by R&N, or plain old A*. The latter can be implemented using an std::priority_queue.

IIRC, R&N described IDA* in the first edition, then replaced it with RBFS in the second. I haven't seen the third edition yet.

As regards your second edit, I haven't looked into the game, but a good procedure for deriving heuristics is that of relaxed problems. You take away the rules of the game until you derive a version for which the heuristic is easily expressed and implemented (and cheap to compute). Or, following a bottom-up approach, you check the main rules to see which one admits an easy heuristic, then try that and add in other rules as you need them.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • Thanks (: But it seems that IDA* is more appropriate for this game, if I'm not wrong. Due to my research, I keep believing that this is the correct algorithm for this problem. As you say it's very hard, I hope someone will convince me in the opposite.. :/ :) – Kiril Kirov Dec 06 '10 at 17:09
  • @Kiril: Have you tried implementing any search algorithm? Picking the right algorithm for this kind of task is not an exact science: you'll have to try several until you find one that works well. It may be that a simple algorithm is all you need. – Fred Foo Dec 06 '10 at 18:17
  • Argh, you're right. I haven't tried. But I don't have much time for testing, I just wondered if there's a recommended algorithm for that kind of games. AddEmUp seems (a littel) like 8-puzzle problem, which is most efficiently solved using IDA*. But you're right, I agree. – Kiril Kirov Dec 06 '10 at 18:27
  • "Most efficiently solved by IDA*" still doesn't mean much without specifying the heuristic. I recommend trying IDS (or DFID as your source calls it) on progressively harder instances until it breaks, then implement A* or RBFS if and when it does. There are very many choices to make when implementing search, which is why nobody wrote *the* library for it yet. – Fred Foo Dec 06 '10 at 18:31
  • thanks a lot for the information and for you help (: Appreciated. +1 for the attention, the explanations and suggesting R&N. 10q – Kiril Kirov Dec 07 '10 at 08:03
3

DFID is just a special case of IDA* where the heuristic function is the constant 0; in other words, it has no provision for introducing heuristics. If the problem is not small enough that it can be solved without using heuristics, it seems you have no choice but to use IDA* (or some other member of the A* family). That said, IDA* is really not that hard: the implementation provided by the authors of AIMA is only about half a page of Lisp code; I imagine a C++ implementation shouldn't take more than twice that.

huaiyuan
  • 26,129
  • 5
  • 57
  • 63