4310_COMP_SCI_X_0006 Assignment 1

Assignment 1

Part 1 Pathfinding

Pathfinding is the problem of finding a path between two points on a plane. It is a fundamental task in robotics and AI. Perhaps the most obvious usage of pathfinding is in computer games, when an object is instructed to move from its current position to a goal position, while avoiding obstacles (e.g., walls, enemy fire) along the way.

Q1703105484

1 1 1 1 1 1 4 7 8 X

1 1 1 1 1 1 1 5 8 8

1 1 1 1 1 1 1 4 6 7

1 1 1 1 1 X 1 1 3 6

1 1 1 1 1 X 1 1 1 1

1 1 1 1 1 1 1 1 1 1

6 1 1 1 1 X 1 1 1 1

7 7 1 X X X 1 1 1 1

8 8 1 1 1 1 1 1 1 1

X 8 7 1 1 1 1 1 1 1


Pathfinding in commercial games is frequently accomplished using search algorithms1. We consider a simplified version in this assignment. The following shows a 2D map drawn using ASCII characters:

Given a start position and an end position on the map, our aim is to find a path from the start position to the end position. The character 'X' denotes an obstacle that cannot be traversed by a path, while the digits represent the elevation at the respective positions.

* * * 1 1 1 4 7 8 X

1 1 * 1 1 1 1 5 8 8

1 1 * * * * * * * 7

1 1 1 1 1 X 1 1 * 6

1 1 1 1 1 X 1 * * 1

1 1 1 1 1 1 1 * 1 1

6 1 1 1 1 X 1 * * *

7 7 1 X X X 1 1 1 *

8 8 1 1 1 1 1 1 1 *

X 8 7 1 1 1 1 1 1 *


Any position is indicated by the coordinates (i, j), where i is the row number (ordered top to bottom) and j is the column number (ordered left to right). For example, the top left position is (1, 1), the bottom right is (10, 10), while the position with elevation 3 is (4, 9). Given start position (1, 1) and end position (10, 10), a possible path is:

Note that we use 4-connectedness for paths, which means any two points on the path are only connected if they are vertically or horizontally (but not diagonally) adjacent.

Problem Formulation

Following the lecture notes, we formulate the problem as follows:

States: Any obstacle-free position (i, j) on the map.

Initial States: A position (i0, j0) given by the user.

Actions: Since we consider 4-connectedness, only four actions are available: Up, down, left and right (your program must expand each node in this order). Available actions for positions adjacent to the map boundary or obstacles are reduced accordingly.

Transition Model: Moving left moves the current position to the left, etc.

Goal Test: Check if the current state is the end position (i*, j*) given by the user.


Path Cost: Given a map M and a Path P{(i0, j0), (i1, j1), ... (iN, jN)}, the cost of the path is calculated as:

where

and M(a, b) is the elevation at the position (a, b). In words, the cost of a path is the sum of the costs between adjacent points in the path, and the cost between adjacent points is 1 plus the difference between the elevation of the two points if we climb "uphill" or simply 1 if we stay "level" or slide "downhill".

This means shorter paths which avoid climbing cost less. As an example, the cost in the path in the previous page is 25. What is the optimal (i.e., cheapest) path?

Your Tasks

Solve this pathfinding task using three different methods: Breadth First Search (BFS)

Uniform Cost Search (UCS) A* Search (A*)

You should base your program on the pseudocode GRAPH-SEARCH in the lecture slides, and carefully think about the appropriate data structures to use. A* search requires a heuristic. In this assignment, you must implement two such heuristics.

The Euclidean distance between current position and end position.

The Manhattan distance between the current position and end position.

For the map above with start position (1, 1) and end position (10, 10), your program should help you answer these questions:

  1. Are the paths returned by the three methods different?
  2. What about the optimality of the returned paths?
  3. Which method is the most computationally and memory efficient?
  4. Do the two heuristics for A* Search provide different solutions?
  5. Does checking for repeated states matter in this problem?

Deliverables

Write your pathfinding program in Python 3.6.9 in a file called pathfinder.py. Your program must be able to run as follows:

>>> python pathfinder.py [map] [algorithm] [heuristic] The inputs to the program are as follow:

[map] specifies the path to the map, which is a text file formatted according to this example:

10 10

1 1

10 10

1 1 1 1 1 1 4 7 8 X

1 1 1 1 1 1 1 5 8 8

1 1 1 1 1 1 1 4 6 7

1 1 1 1 1 X 1 1 3 6

1 1 1 1 1 X 1 1 1 1

1 1 1 1 1 1 1 1 1 1

6 1 1 1 1 X 1 1 1 1

7 7 1 X X X 1 1 1 1

8 8 1 1 1 1 1 1 1 1

X 8 7 1 1 1 1 1 1 1

The first line indicates the size of the map (rows, columns), while the second and third line represent the start and end positions respectively. The map then follows where all elevation values are integers from 0 to 9 inclusive.

[algorithm] specifies the search algorithm to use, with the possible values of bfs, ucs, and astar. [heuristic] specifies the heuristic to use for A* search, with the possible values of euclidean and manhattan. This input is ignored for BFS and UCS.

* * * 1 1 1 4 7 8 X

1 1 * 1 1 1 1 5 8 8

1 1 * * * * * * * 7

1 1 1 1 1 X 1 1 * 6

1 1 1 1 1 X 1 * * 1

1 1 1 1 1 1 1 * 1 1

6 1 1 1 1 X 1 * * *

7 7 1 X X X 1 1 1 *

8 8 1 1 1 1 1 1 1 *

X 8 7 1 1 1 1 1 1 *


Your program must then print to standard output the path returned by the search algorithm in the following format:

where the path is indicated by asterisks *, superimposed on the original map beginning from the start position and leading to the end position. Do not include extraneous spaces or other characters in the output.

If the given map or problem does not have a feasible path, your program must print: null

Again, do not include extraneous spaces or other characters in the output.

Python Libraries

You are allowed to use Python standard libraries to write your pathfinding program (see https://docs.python.org/3/library ) for the components that make up the Python v3.6.9 standard libraries). In addition to the standard libraries, you are allowed to use NumPy. Note that the marking program will not be able to run your program to completion if other third party libraries are used.

Submission

You must submit your program files on Gradescope. Instructions on accessing Gradescope and submitting assignments are provided at https://helpgradescope.com/article/5d3ifaeqi4-student- canvas . Please use the course code 6ZWNXV to enrol in the course.

WARNING

There are two submission locations, one for undergraduates and one for graduates.

For undergraduates, please submit your pathfinding program (pathfinder.py) to Assignment 1 - UG

Assessment

The code will be compiled and run on several test problems. If it passes all tests, you will receive 15% (undergraduates), or 12% (postgraduates) of the overall course mark. There are no manual marks for style or commenting.

Using other Source Code

You may not use other source code for this assignment. You should personally and carefully implement the search algorithms to fully understand the concept.

Due Date

This assessment's Due Date is specified on MyUni.

Part 2: Pathfinding by direct optimisation (Post-Graduates Only)

For postgraduate students, completing this section successfully will give you the remaining 3% of the marks.

Algorithm 1

1: input Initial path P0, initial temperature Tini, final te mperature Tfin,

cooling rate α, segment length d.

2: output Optimised path P

3: Intitialise T Tini, P P0 4: while T > Tfin do

5:  Ph rand-local-adjust(P, d)

6: Δg g(P) - g(Ph) 7:  if Δg > 0 then 8: P Ph

9:  else

10:      With probability eΔg/t, P Ph

11: end if /* Record T and g(P) here for bookkeeping.*/ 12: T ← αT

13: end while

14: return P


Here we shall attempt to directly optimise the path instead of step-by-step searching. We consider the simulated annealing algorithm shown below. For more background on simulated annealing, see Section 4.1 of Russell and Norvig (3rd ed.)

The algorithm receives as input a feasible (but non-optimal) path joining a start position and an end position on the map. The core idea is to iteratively perform random local adjustments to the path, and accept the new path if the adjustments improve the path cost (defined above), or accept it probabilistically if the cost is not improved. The process is repeated until the annealing temperature T falls below a small value Tfin given by the user. The temperature reduction is conducted as T = αT, where 0 < α < 1 is the cooling rate (also supplied by the user). See Section 4.1 of Russell and Norvig (3rd ed.) for more details.

Algorithm 2

input Path P, segment length d. output Adjusted path Ph

Random pick a point (u, v) on P.

Pick as (x, y) the point of d positions away from (u, v) alon g P towards the end position.

If such a point does not exist, use the end posi tion for (x, y)

Find a random path S joining (u, v) and (x, y) using randomi sed BFS (see text below)

Replace path segment in P between (u, v) and (x, Y) with S. S tore the new path as Ph

return Ph


The main body of the algorithm is conceptually simple - the hardest part is the routine to perform the random adjustments. Fortunately we can rely on the BFS program written in the previous section. The method is shown below in Algorithm 2. Note that the adjustments cannot make the path infeasible (i.e., any resulting path still joins the original start position and end position required by the user).

To perform randomised BFS, only a minor tweak to the original BFS algorithm is required - the order of actions for expanding each node in the search tree is randomised every time. For example, while in the original BFS, the order was always fixed as UDLR (up, down, left, right), we randomise this at every instance to be LURD, DLUR, etc. The following shows randomised adjustments with d = 5, and (u, v) = (8, 1) and (x, y) = (10, 4).

* 1 8 1 1 2 4 7 8 X  * 1 8 1 1 2 4 7 8 X  * 1 8 1 1 2 4 7 8 X

* 1 1 5 1 5 1 5 8 8  * 1 1 5 1 5 1 5 8 8  * 1 1 5 1 5 1 5 8 8

* 4 2 2 1 6 1 4 6 7  * 4 2 2 1 6 1 4 6 7  * 4 2 2 1 6 1 4 6 7

* 5 1 7 0 3 5 1 1 6  * 5 1 7 0 3 5 1 1 6  * 5 1 7 0 3 5 1 1 6

* 7 8 1 2 6 8 1 5 1  * 7 8 1 2 6 8 1 5 1  * 7 8 1 2 6 8 1 5 1

* 7 4 1 1 4 2 2 4 2  * 7 4 1 1 4 2 2 4 2  * 7 4 1 1 4 2 2 4 2

* 5 1 2 1 2 7 5 1 6  * 5 1 2 1 2 7 5 1 6  * 5 1 2 1 2 7 5 1 6

* 7 1 3 4 2 0 4 2 1  * * 1 3 4 2 0 4 2 1  * 7 1 3 4 2 0 4 2 1

* * 1 1 1 5 1 1 9 1  8 * 1 1 1 5 1 1 9 1  * * * * 1 5 1 1 9 1

X * * * * * * * * *  X * * * * * * * * *  X 8 7 * * * * * * *

Your Tasks

2 1 8 1 1 2 4 7 8 X

3 1 1 5 1 5 1 5 8 8

4 4 2 2 1 6 1 4 6 7

8 5 1 7 0 3 5 1 1 6

3 7 8 1 2 6 8 1 5 1

2 7 4 1 1 4 2 2 4 2

6 5 1 2 1 2 7 5 1 6

7 7 1 3 4 2 0 4 2 1

8 8 1 1 1 5 1 1 9 1

X 8 7 1 3 1 7 1 0 0


Implement simulated annealing for path optimisation. As a sanity check, test your program on the following map with start position (1, 1) and end position (10, 10), with the initial path given by your (deterministic) BJFS method from the previous section.

Use parameter values Tini = 10, Tfin = 0.001, α = 0.99, and d = 5. Your program should help you answer the following questions:

  1. Does simulated annealing find the optimal path every time?
  2. How important is it to be able to accept an inferior path? Investigate by disabling Step 10 in Algorithm 1.
  3. How sensitive is the performance to the parameter settings? Investigate by changing the values of Tini, Tfin, α and d.

Deliverables

Write your simulated annealing pathfinder program in Python 3 in a file called sapathfinder.py. Your program must be able to be run as follows:

>>> python sapathfinder.py [map] [init] [tini] [tfin] [alpha] [d]

The test program will assume that you would use the same programming language as in Part 1, and that you have a working program (pathfinder.py) for the tasks in Part 1.

The inputs/options to the program are as follows:

[map] specifies the path to the map as formatted in Part 1

[init] specifies the path to an initial path, encoded according to the output of the program (as per Part 1)

[tini] and [tfin] specify the intial and final temperature respectively. [alpha] specifies the cooling rate

[d] specifies the segment length for random local path adjustments.

* 1 8 1 1 2 4 7 8 X

* 1 1 5 1 5 1 5 8 8

* 4 2 2 1 6 1 4 6 7

* 5 1 7 0 3 5 1 1 6

* 7 8 1 2 6 8 1 5 1

* 7 4 1 1 4 2 2 4 2

* * * * 1 2 7 5 1 6

7 7 1 * 4 2 0 4 2 1

8 8 1 * 1 5 1 1 9 1

X 8 7 * * * * * * *

T = 10.000000, cost = 38

T = 9.900000, cost = 44

T = 9.801000, cost = 42

.

.

.

T = 5.151371, cost = 40

T = 5.099857, cost = 40

T = 5.048859, cost = 41

.

.

.

T = 0.001014, cost = 23

T = 0.001004, cost = 23


Your program must then print to standard output the optimised path, as well as the evolution of the temperature and path cost, in the manner of this example:

Do not include extraneous spaces or other characters in the output.

Submit your program in the same way as the submission for Part 1. For postgraduates, please submit your pathfinding programs (pathfinder.py and sapathfinder.py) to Assignment 1 - PG. The due date, late submission and code re-use are the same as Part 1.

你可能感兴趣的:(c++,python)