MDeath-Kid

- M I T & Y
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

USACO 1.4 Search Techniques - 翻译

Posted on 2011-11-16 10:16  MDeath-Kid  阅读(347)  评论(0编辑  收藏  举报

译文 by MDK on 2011.11.16 8:28
Search Techniques

搜索技术

Sample Problem: n Queens [Traditional]

Place n queens on an n x n chess board so that no queen is attacked by another queen.

例子:n 皇后问题

把n个皇后放在 n * n 的棋盘里面,是得每对皇后不会互相攻击.

Depth First Search (DFS)

The most obvious solution to code is to add queens recursively to the board one by one, trying all possible queen placements. It is easy to exploit the fact that there must be exactly one queen in each column: at each step in the recursion, just choose where in the current column to put the queen.

DFS:

最容易想到的是递归的在棋盘上放皇后,尝试每个可以放的地方.很显然发现没列有且只能有一个(皇后):在每步的递归可以选现有的一列.

伪代码:

1 search(col)
2     if filled all columns
3         print solution and exit
4   for each row
5       if board(row, col) is not attacked
6            place queen at (row, col)
7            search(col+1)
8            remove queen at (row, col)

Calling search(0) begins the search. This runs quickly, since there are relatively few choices at each step: once a few queens are on the board, the number of non-attacked squares goes down dramatically.

调用 search(0) 开始搜索,这个跑的很快,因为每步几乎没有可选择的:棋盘上有一些皇后,不能互相攻击的地方急剧下降.

This is an example of depth first search, because the algorithm iterates down to the bottom of the search tree as quickly as possible: once k queens are placed on the board, boards with even more queens are examined before examining other possible boards with only k queens. This is okay but sometimes it is desirable to find the simplest solutions before trying more complex ones.

这是一个深搜的例子,因为算法会尽可能快的迭代到末尾:一旦 k 皇后在棋盘上,().. .. (大概意思是放入更多的皇后之前会检查有 k 皇后的棋盘有没有多余的地方),这是可取的,有时这个会找到最简单的答案,然后在去找更复杂的答案.

Depth first search checks each node in a search tree for some property. The search tree might look like this:

深搜相当于在搜索树上检查每个节点,搜索树可能会像这个:

The algorithm searches the tree by going down as far as possible and then backtracking when necessary, making a sort of outline of the tree as the nodes are visited. Pictorially, the tree is traversed in the following manner:

搜索算法会在这个树上走得尽可能的深,并且在必要的时候回溯,在一棵树的轮廓的节点上的访问.下面这棵树形象的描述了访问的方式.

Complexity

Suppose there are d decisions that must be made. (In this case d=n, the number of columns we must fill.) Suppose further that there are C choices for each decision. (In this case c=n also, since any of the rows could potentially be chosen.) Then the entire search will take time proportional to cd, i.e., an exponential amount of time. This scheme requires little space, though: since it only keeps track of as many decisions as there are to make, it requires only O(d) space.

复杂度

假设每次有 d 个决定.(例子上 d = n,必须被填满的列数.) 假设每个决定最多有 C 个选择.(例子上 c = n,因为所有的行都得被填满.)那么完整的搜索大概会用 cd 次,指数型的时间.这个方法几乎不需要空间,因为:他能保存每次做决定的记录,这需要O(d)空间.

Sample Problem: Knight Cover [Traditional]

Place as few knights as possible on an n x n chess board so that every square is attacked. A knight is not considered to attack the square on which it sits.

例子:Knight Cover

在一个 n * n 的棋盘上放入尽可能少的骑士,使得每一块都受到攻击。骑士在的一个格不考虑攻击。

Breadth First Search (BFS)

In this case, it is desirable to try all the solutions with only k knights before moving on to those with k+1 knights. This is called breadth first search. The usual way to implement breadth first search is to use a queue of states:

BFS

在这个例子中,他需要尝试所有 k 个骑士的可行解法,然后在考虑到 k + 1 个骑士的解放上。这叫做 广搜。这个方法通常用一个广搜的队列保存状态。

1 process(state)
2     for each possible next state from this one
3         enqueue next state
4 search()
5     enqueue initial state
6     while !empty(queue)
7         state = get state from queue
8         process(state)

This is called breadth first search because it searches an entire row (the breadth) of the search tree before moving on to the next row. For the search tree used previously, breadth first search visits the nodes in this order:

这个叫做广搜因为他在搜索树上搜索每个完整的行(宽度),然后再搜索下面的一行。在搜索树被用之前,广搜访问节点按照这种顺序。

It first visits the top node, then all the nodes at level 1, then all at level 2, and so on.

首先是top node,然后是所有在 level 1 上的node,然后是 level 2上的,等等。

Complexity

Whereas depth first search required space proportional to the number of decisions (there were n columns to fill in the n queens problem, so it took O(n) space), breadth first search requires space exponential in the number of choices.

If there are c choices at each decision and k decisions have been made, then there are c k possible boards that will be in the queue for the next round. This difference is quite significant given the space restrictions of some programming environments.

[Some details on why ck: Consider the nodes in the recursion tree. The zeroeth level has 1 nodes. The first level has c nodes. The second level has c2 nodes, etc. Thus, the total number of nodes on the k-th level is ck.]

复杂度

DFS需要的空间是做决定的个数(比如n列皇后问题,他就用了O(n)的空间),BFS需要的空间是做选择的次数。

如果有 C 个选择在每个决定的时候 并且有 k 个决定。那么有c k 可能boards

Depth First with Iterative Deepening (ID)

An alternative to breadth first search is iterative deepening. Instead of a single breadth first search, run D depth first searches in succession, each search allowed to go one row deeper than the previous one. That is, the first search is allowed only to explore to row 1, the second to row 2, and so on. This ``simulates'' a breadth first search at a cost in time but a savings in space.

ID DFS 迭代加深搜索

广搜的一种代替叫迭代加深搜索。不同于于单一的BFS,在D深度第一次搜索成功,ID允许每次搜索比上次搜索更深一层。就是说,第一次搜索运行深度为1,第二次允许为2,等等。他模仿了广搜的时间但是节省了空间。

1 truncated_dfsearch(hnextpos, depth)
2     if board is covered
3         print solution and exit
4     if depth == 0
5         return
6     for i from nextpos to n*n
7         put knight at i
8         truncated_dfsearch(i+1, depth-1)
9         remove knight at i
10 dfid_search
11     for depth = 0 to max_depth
12        truncated_dfsearch(0, depth)

Complexity

The space complexity of iterative deepening is just the space complexity of depth first search: O(n). The time complexity, on the other hand, is more complex. Each truncated depth first search stopped at depth k takes ck time. Then if d is the maximum number of decisions, depth first iterative deepening takes c0 + c1 + c2 + ... + cd time.

If c = 2, then this sum is cd+1 - 1, about twice the time that breadth first search would have taken. When c is more than two (i.e., when there are many choices for each decision), the sum is even less: iterative deepening cannot take more than twice the time that breadth first search would have taken, assuming there are always at least two choices for each decision.

复杂度

空间O(N)。

时间复杂度c0 + c1 + c2 + ... + cd 。(译者:每次比上次加深一次,相当于多次已知深度的DFS)。

Which to Use?

Once you've identified a problem as a search problem, it's important to choose the right type of search. Here are some things to think about.

 

译文 by MDK on 2011.11.16 10:00

应用?

一旦你确定某个题目是搜索题,选哪种搜索很重要。我们马上说这些。

In a Nutshell
Search Time Space When to use
DFS O(ck) O(k) Must search tree anyway, know the level the answers are on, or you aren't looking for the shallowest number.
BFS O(cd) O(cd) Know answers are very near top of tree, or want shallowest answer.
DFS+ID O(cd) O(d) Want to do BFS, don't have enough space, and can spare the time.

d is the depth of the answer
k is the depth searched
d <= k

(各种总结和比较)

Remember the ordering properties of each search. If the program needs to produce a list sorted shortest solution first (in terms of distance from the root node), use breadth first search or iterative deepening. For other orders, depth first search is the right strategy.

If there isn't enough time to search the entire tree, use the algorithm that is more likely to find the answer. If the answer is expected to be in one of the rows of nodes closest to the root, use breadth first search or iterative deepening. Conversely, if the answer is expected to be in the leaves, use the simpler depth first search.

Be sure to keep space constraints in mind. If memory is insufficient to maintain the queue for breadth first search but time is available, use iterative deepening.

 

记得每个搜索节点的顺序。如果程序需要产生一个列表序的最短方案(从节点到根节点的距离),用BFS或者ID。对于其他的,DFS比较合适。

如果这没有足够的时间去搜索完整个搜索树,用最可能的算法找到答案。如果答案预计是在最接近根的一行节点时,用BFS或ID。反之,如果在叶子节点,就用DFS。

牢记空间的限制,如果内存不足以维持BFS搜索的队列,但是时间可用,那就用ID。

Sample Problems  例子
Superprime Rib [USACO 1994 Final Round, adapted]

A number is called superprime if it is prime and every number obtained by chopping some number of digits from the right side of the decimal expansion is prime. For example, 233 is a superprime, because 233, 23, and 2 are all prime. Print a list of all the superprime numbers of length n, for n <= 9. The number 1 is not a prime.

For this problem, use depth first search, since all the answers are going to be at the nth level (the bottom level) of the search.

Betsy's Tour [USACO 1995 Qualifying Round]

A square township has been partitioned into n 2 square plots. The Farm is located in the upper left plot and the Market is located in the lower left plot. Betsy takes a tour of the township going from Farm to Market by walking through every plot exactly once. Write a program that will count how many unique tours Betsy can take in going from Farm to Market for any value of n <= 6.

Since the number of solutions is required, the entire tree must be searched, even if one solution is found quickly. So it doesn't matter from a time perspective whether DFS or BFS is used. Since DFS takes less space, it is the search of choice for this problem.

Udder Travel [USACO 1995 Final Round; Piele]

The Udder Travel cow transport company is based at farm A and owns one cow truck which it uses to pick up and deliver cows between seven farms A, B, C, D, E, F, and G. The (commutative) distances between farms are given by an array. Every morning, Udder Travel has to decide, given a set of cow moving orders, the order in which to pick up and deliver cows to minimize the total distance traveled. Here are the rules:

  • The truck always starts from the headquarters at farm A and must return there when the day's deliveries are done.
  • The truck can only carry one cow at a time.
  • The orders are given as pairs of letters denoting where a cow is to be picked up followed by where the cow is to be delivered.

Your job is to write a program that, given any set of orders, determines the shortest route that takes care of all the deliveries, while starting and ending at farm A.

Since all possibilities must be tried in order to ensure the best one is found, the entire tree must be searched, which takes the same amount of time whether using DFS or BFS. Since DFS uses much less space and is conceptually easier to implement, use that.

Desert Crossing [1992 IOI, adapted]

A group of desert nomads is working together to try to get one of their group across the desert. Each nomad can carry a certain number of quarts of water, and each nomad drinks a certain amount of water per day, but the nomads can carry differing amounts of water, and require different amounts of water. Given the carrying capacity and drinking requirements of each nomad, find the minimum number of nomads required to get at least one nomad across the desert.

All the nomads must survive, so every nomad that starts out must either turn back at some point, carrying enough water to get back to the start or must reach the other side of the desert. However, if a nomad has surplus water when it is time to turn back, the water can be given to their friends, if their friends can carry it.

Analysis: This problem actually is two recursive problems: one recursing on the set of nomads to use, the other on when the nomads turn back. Depth-first search with iterative deepening works well here to determine the nomads required, trying first if any one can make it across by themselves, then seeing if two work together to get across, etc.

Addition Chains

An addition chain is a sequence of integers such that the first number is 1, and every subsequent number is the sum of some two (not necessarily unique) numbers that appear in the list before it. For example, 1 2 3 5 is such a chain, as 2 is 1+1, 3 is 2+1, and 5 is 2+3. Find the minimum length chain that ends with a given number.

Analysis: Depth-first search with iterative deepening works well here, as DFS has a tendency to first try 1 2 3 4 5 ... n, which is really bad and the queue grows too large very quickly for BFS.

 

译文 by MDK on 2011.11.16 10:14

 

每次翻译到中间就巨累,好多翻译不通顺,只能大概自己理解意思,大家凑合着看看英文看看翻译吧,等USACO做完了在回来改。