Algorithm Series 14: Wolves, sheep, vegetables and farmers cross the river problem __ algorithm

Source: Internet
Author: User
Tags bool case statement

Algorithm go action iterator struct fun

Title Description: farmers need to send wolves, sheep, vegetables and themselves to the other side of the river, only the farmer can row, and the boat is relatively small, except the farmer can only transport one thing at a time, there is a thorny problem, that is, if there is no farmer to watch, sheep will eat food, the wolf eats sheep. Consider a way for farmers to safely arrange these things and to cross the river with him.

This topic examines people's fast logic and short-term memory. Analysis, in the Wolf-"sheep-" food chain, "sheep" in the key position, the guiding ideology to solve the problem is to "sheep" and "wolf" and "food" is always in isolation, that is, "sheep" should always be taken across the river. Take a look at the answer:

The farmer took the sheep across the river

Farmer returns

The farmer took the wolf across the river

The farmer returned with the sheep

The farmer takes the vegetable across the river

Farmer returns

The farmer took the sheep across the river

< end >

Look at one more answer:

The farmer took the sheep across the river

Farmer returns

The farmer takes the vegetable across the river

The farmer returned with the sheep

The farmer took the wolf across the river

Farmer returns

The farmer took the sheep across the river

< end >

The problem is all around the sheep.

There are two answers mentioned above, so how many answers is there in this question? The answer also requires a computer to carry out a poor lift. The key to solving this problem with a computer is the state traversal, which is the state traversal mentioned in the article "algorithm series-three buckets of water", which is a finite state machine in the final analysis. Farmers, wolves, sheep and vegetables depending on their positional relationship, there can be many states, but the total number of States is still limited, and our algorithm is to traverse between these finite states until we find a "path" that transitions from the initial state to the terminating state, and according to the requirements of the topic, this "path" Should be in a legal state for each state.

Whether it is a state modeling or a state conversion algorithm, it is more simple than "8 liters of water with three buckets". The first is the state, the farmer, the Wolf, the sheep and the dish as four separate item, their state is very simple, either is the river, either does not cross the river, at any time each item state only one. If "Here" means not to cross the river, with "there" means that has crossed the river, with [Farmers, wolves, sheep, vegetables] Four yuan to indicate the state of a moment, then the state space of the subject is [Here,here,here,here] as the root of a state tree, When a leaf node of this state tree is a state [There,there,there,there], then the state sequence between the root and the leaf node is a solution to this problem.

The state conversion algorithm of the topic is still a depth-first search for all states in the state space, because wolves, sheep and vegetables do not row, so the state conversion algorithm is also very simple, do not need to be like "three buckets with 8 liters of water" problem should be arranged in a way to determine the conversion method (inverted water action), There are only 8 kinds of fixed state conversion operations (cross-river Movement), respectively:

The farmer crossed the river alone;

The farmer took the wolf across the river;

The farmer took the sheep across the river;

The farmer took the dish across the river;

The farmer returned alone;

The farmer returned with the wolf;

The farmer returned with the sheep;

The farmer returned with a vegetable;

The breadth of the subject of the search boundary is the 8 actions, in turn, the 8 actions can be converted to a maximum of 8 new states, each new state can be converted to a maximum of 8 new state, the formation of each state node has 8 (up to 8) child nodes of the state tree (eight fork tree). The core of the algorithm is the depth-first traversal of the state tree, which outputs a set of results when a state satisfies the end state.

It is important to note that not every action can get a new state, such as "Farmers with wolves across the river" this action, for those wolves have been on the other side of the river is invalid, unable to get a new state, so the eight-tree is not full of trees. In addition, the legitimate judgment of the subject's requirements can also cut off many invalid states. The last point to note is that even if there is a valid state, there will be repetition, and in the process of a deep traversal, if a duplicate state may lead to an infinite loop, the repeated state is "pruned".

Program implementation first to describe the state model, the state of this algorithm is defined as:

ItemState struct

34 {

35 ...

Farmer,wolf,sheep,vegetable State;

Action curaction;

35 ...

45};

The algorithm needs to save all the legal states on the current search path in the process of exhaustive, considering the depth-first algorithm, stack is the best choice, but the stack does not provide a linear traversal of the interface, in the output and to determine whether there is a duplicate state, the need for linear traversal of the saved state path, Therefore, this algorithm does not use the stack, but uses the Deque (double-ended queue).

The core of the algorithm is the Processstate () function, and the processstate () function traverses the state tree by recursive invocation of itself, with the following code:

291 void Processstate (deque<itemstate>& states)

292 {

293 ItemState current = States.back (); /* Start every time from the current state */

294 if (current. Isfinalstate ())

295 {

296 Printresult (states);

297 return;

298}

299

ItemState Next;

301 for (int i = 0; i < Action_count; ++i)

302 {

303 if (Actmap[i].processfunc (current, next))

304 {

305 if (Iscurrentstatevalid (next) &&! Isprocessedstate (states, Next))

306 {

307 States.push_back (next);

308 processstate (states);

309 States.pop_back ();

310}

311}

312}

313}

The parameter states is a list of all States on the state path of the current search, so the Processstate () function first determines whether the last state of the state list is final or not, and if so, the search path can be a solution, so call Printresult () The function prints the result, followed by a return that terminates the search on the set search path. If the final state has not been reached, then the new state is obtained from the 8 fixed cross-river movements, and the search continues from the newly state. In order to avoid the long switch...case statement, the program algorithm uses the table-driven method, puts the processing function of the 8 fixed cross-crossing action in a map table, and replaces the Switch...case statement with a simple look-up table. The contents of the mapping table are as follows:

279 actionprocess Actmap[action_count] =

280 {

281 {farmer_go, Processfarmergo},

282 {farmer_go_take_wolf, Processfarmergotakewolf},

283 {farmer_go_take_sheep, processfarmergotakesheep},

284 {farmer_go_take_vegetable, processfarmergotakevegetable},

285 {farmer_back, processfarmerback},

286 {farmer_back_take_wolf, processfarmerbacktakewolf},

287 {farmer_back_take_sheep, processfarmerbacktakesheep},

288 {farmer_back_take_vegetable, processfarmerbacktakevegetable}

289};

The processing function in the table is very simple, which is to get a new state according to the current state and the cross-river movement, if the cross-river action is contradictory with the current state, then the return fails to Farmer_go_take_wolf action corresponding to the processing function Processfarmergotakewolf () For example, look at the code for the Processfarmergotakewolf () function:

  182 bool processfarmergotakewolf (const itemstate& Current, ItemS tate& next)

  183 {

  184     if ((Current.farmer! = here) | | (Current.wolf! = here))

  185         return false;

  186 

  187     next = current;

  188 

  189     next.farmer    = there;

  190     next.wolf      = there;

  191     next.curaction = Farmer_go_take_wolf;

  192 

  193     return true;

  194 }

        when the corresponding processing function of the cross-river operation returns successfully, indicating that a new state can be obtained without contradiction, it is necessary to check the legality of the new state, first of all to check whether the problem is satisfied, For example, wolves and sheep cannot be alone and sheep and vegetables cannot be left alone, and so on, this check is done in the Iscurrentstatevalid () function. Next is to check whether the new state and the state path has been processed on the state has a duplicate, this check is done by the isprocessedstate () function, isprocessedstate () function is very simple, is to traverse the states, and the new state compared whether there is the same state, The code is as follows:

131 bool Isprocessedstate (deque<itemstate>& states, itemstate& newstate)

132 {

133 Deque<itemstate>::iterator it = find_if (States.begin (), States.end (),

134 bind2nd (Ptr_fun (issameitemstate), newstate));

135

136 return (It! = States.end ());

137}

Run the program and the result is:

Find Result 1:

Unknown action, item states is:0 0 0 0

Farmer take sheep go on river, item states is:1 0 1 0

Farmer go back, item states is:0 0 1 0

Farmer take Wolf go through river, item states is:1 1 1 0

Farmer take sheep go back, item states is:0 1 0 0

Farmer take vegetable go on river, item states is:1 1 0 1

Farmer go back, item states is:0 1 0 1

Farmer take sheep go on river, item states is:1 1 1 1

Find Result 2:

Unknown action, item states is:0 0 0 0

Farmer take sheep go on river, item states is:1 0 1 0

Farmer go back, item states is:0 0 1 0

Farmer take vegetable go on river, item states is:1 0 1 1

Farmer take sheep go back, item states is:0 0 0 1

Farmer take Wolf go through river, item states is:1 1 0 1

Farmer go back, item states is:0 1 0 1

Farmer take sheep go on river, item states is:1 1 1 1

It seems that there are only two outcomes.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.