How do I find the optimal path through a grid? - java

Overview of the problem: You are a truffle collector, and are given a grid of numbers representing plots of land with truffles on them. Each plot has a certain number of truffles on it. You must find the optimal path from the top of the grid to the bottom (the one that collects the most truffles). Importantly, you can start from any cell in the top row. When you are at a cell, you can move diagonally down to the left, directly down, or diagonally down to the right. A truffle field might look like this:
The truffle fields also do not have to be square. They can have any dimensions.
So, I have created an iterative algorithm for this problem. Essentially, what I have done is iterate through each cell in the top row, finding the greedy path emanating from each and choosing the one with the largest truffle yield. To elaborate, the greedy path is one in which at every step, the largest value that can be reached in the next row from the current cell is chosen.
This algorithm yields the correct result for some truffle fields, like the one above, but it fails on fields like this:
This is because when the algorithm hits the 100 in the third column, it will go directly down to the 3 because it is the largest immediate value it can move to, but it does not consider that moving to the 2 to the left of it will enable it to reach another 100. The optimal path through this field obviously involves both cells with a value of 100, but the greedy algorithm I have now will never yield this path.
So, I have a hunch that the correct algorithm for this problem involves recursion, likely recursive backtracking in particular, but I am not sure how to approach creating a recursive algorithm to solve it. I have always struggled with recursion and find it difficult to come up with algorithms using it. I would really appreciate any ideas you all could provide.
Here is the code. My algorithm is being executed in the findPath method: https://github.com/jhould007/Programming-Assignment-3/blob/master/Truffle.java.

You could use recursion, but there's a simple iterative fix to your approach as well.
Instead of the top row, start with the bottom one. Create a 1D array values and initialise it with the values of the bottom row.
Start iterating curr_row from row max_row-1 to 0. For each iteration, create a temporary array temp and initialise it with 0's.
For a row curr_row in the iteration, value[i] represents the max value that you can get if you start from row curr_row+1 (basically the next row) and column i.
To update temp in each iteration, we just need to pick the best path from the next row, which can be fetched from values array.
for column in range [0, max_column]:
temp[column] = truffle_value[column] + max(value[column], value[column+1], value[column-1])
// since temp holds the values for the next iteration in our loop
value = temp
In the end, the answer will simply be max(values).

Related

All combinations of 2d array chess game

I am making a program that is calculating the number of possible solutions of a chess game with only bishops and queens. The user can put in the number of queens and bishops, as well as the size of the chess board (rows & columns).
I will call any set of positions for the bishops and the queens on the board a combination. A combination counts as a solution if all squares are attacked (Chess domination problem).
So for example, if the user gives 1 Queen and 3 Bishops, on a 5x5 chess board, a possible solution can be:
- - B - -
- - - - -
- B Q B -
- - - - -
- - - - -
Now i have trouble making a program that finds all the possible positions of a given set of pieces, without duplicates. Duplicates can occur because the user can give a multiple number of bishops for example. The solution needs to be recursive.
You don't show your current solution, but I /assume/ you pick each square for the first piece, then pick each square for the second piece , and continue if the square is still unoccupied. Then repeat for the third, etc.
If the first and second piece are the same type, then this will cause a duplication. First piece in first position, second in second vs first in second position, second in first.
If you have two pieces of the same type, you can just impose an ordering on your positioning the second piece: Do not place the second identical piece at a lower index than the first. This avoids the duplication, but still visits every permutation of positions. You can impose this ordering on more of the same types of piece.
When you have a different type of piece, the two orderings become distinct. If the first and second are different piece types, then First piece in first position, second in second vs first in second position, second in first are distinct cases. However, when you put down the second instance of the new type, you can apply the ordering rule against the first one.
[Alternatively, you can insist that the second piece is placed before the first piece - the outcome is the same]
As a second optimisation, you can observe that if you have 3 bishops and the third must be placed after the other 2, then the first cannot be placed in the last or penultimate squares, so you can optimise your placement of the first one very slightly.
This becomes more complex when this is the second type of piece, and it is possibly not worth doing.
A third optimisation is to keep a list of the available squares. Once a piece is put down, its square is removed from the list, so the list is shorter for placing the next piece, and you don't have to "fail" when you try and put the queen on top of a bishop, as you won't try. You can use the length of this list to simplify the second optimisation.
You can do some clever tricks with std::list::splice to mean that you don't reallocate or duplicate this list as you recurse through the pieces and positions.

Optimizing heap structure for heapsort

I'm implementing heapsort using a heap. To do this each value to be sorted is inserted. The insertion method calls heapifyUp() (aka siftUp) so this means each time another value is inserted heapifyUp is called. Is this the most efficient way?
Another idea would be to insert all elements, and then call heapifyUp. I guess heapifyUp would have to be called on each one? Is doing it like this better?
Inserting each element will build the heap in O(n log n) time. Same thing if you add all the elements to an array and then repeatedly call heapifyUp().
Floyd's Algorithm builds the heap bottom-up in O(n) time. The idea is that you take an array that's in any order and, starting in the middle, sift each item down to its proper place. The algorithm is:
for i = array.length/2 downto 0
{
siftDown(i)
}
You start in the middle because the last length/2 items in the array are leaves. They can't be sifted down. By working your way from the middle, up, you reduce the number of items that have to be moved.
Example of the difference
The example below, turning an array of 7 items into a heap, shows the difference in the amount of work done.
The heapifyUp() method
[7,5,6,1,2,3,4] (starting state)
Start at the end and bubble items up.
Move 4 to the proper place
[7,5,4,1,2,3,6]
[4,5,7,1,2,3,6]
Move 3 to its place
[4,5,3,1,2,7,6]
[3,5,4,1,2,7,6]
Move 2 to its place
[3,2,4,1,5,7,6]
[2,3,4,1,5,7,6]
Move 1 to its place
[2,1,4,3,5,7,6]
[1,2,4,3,5,7,6]
The heap is now in order. It took 8 swaps, and you still have to check 4, 2, and 1.
Floyd's algorithm
[7,5,6,1,2,3,4] (starting state)
Start at the halfway point and sift down. In a 0-based array of 7 items, the halfway point is 3.
Move 1 to its place
[7,5,6,1,2,3,4] (no change. Remember, we're sifting down)
Move 6 to its place
[7,5,3,1,2,6,4]
Move 5 to its place
[7,1,3,5,2,6,4]
[7,1,3,4,2,6,5]
Move 7 to its place
[1,7,3,5,2,6,4]
[1,2,3,5,7,6,4]
And we're done. It took 5 swaps and there's nothing else to check.

efficient algorithm to check if there exists a row and a column with same values?

I am trying to solve this problem using the least running time.
If we're given a 2D array, we need to return x if there exists a row where all values equal x, and there is a column where all values equal x.
For example, for the following 2d array,
0 3 1
2 3 1
1 1 1
we are supposed to return 1 since the last row and last column are all of same value 1. If no such number exists, we can return -1.
I know there are many ways to solve the problem and most of them are of O(n^2), I'm wondering if there is an efficient way(i.e O(n)) to find such value. (where n represents the number of cells in this array)
Ok, you clarified that you consider O(n) to be the number of values in the 2D array.
I'll outline the approach in pseudo-code, which you can translate to either Java or C++, whichever is your preference. Your question is tagged with both, and the pseudocode is trivial enough to be directly translatable into either C++ or Java. Or Perl. Or Python...
Part 1
Let's start with the first, easy step, how to check whether there's any row that contains the same value. The pseudocode for this is elementary:
start with the 0th row, n=0
check if matrix[n][0] through [n][m-1] (where m is the number of columns in the matrix) contain the same value. If so, you found it.
otherwise, increment n, to go to the next row, until you reach the bottom of the matrix.
You should be able to understand that. This is basic, elementary "Computer Science 101" stuff.
Part 2
Now, let's modify this pseudocode to simultaneously check the columns as well. Modify the above pseudocode as follows.
Create two one-dimensional vectors, call the first one top_values, or something, whose size is m, the number of columns in your matrix. Call the second one flags, it's a vector of boolean flags, also their size is m.
When you scan the 0th row, in the pseudocode given in the first part, copy the values from the 0th row, into top_values. That is, copy matrix[0][x] into top_values[x]. Also set flags[x] to true (you can initialize all flags to true even before you scan the 0th row, it doesn't matter).
When you scan each one of the remaining rows, using the pseudocode given in Part 1, compare matrix[y][x] (where y is the row# you're scanning) against top_values[x]. If they are not the same, set flags[x] to false.
At the end of the pseudocode from part 1, check your flags vector. If any value in it is still true, there's a column in your matrix whose values are the same.
Your homework assignment is to make a slight tweak to the above pseudocode to also tell you which value is the same, in some row or column.

Why is this called backtracking?

I have read in Wikipedia and have also Googled it,
but I cannot figure out what "Backtracking Algorithm" means.
I saw this solution from "Cracking the Code Interviews"
and wonder why is this a backtracking algorithm?
Backtracking is a form of recursion, at times.
This boolean based algorithm is being faced with a choice, then making that choice and then being presented with a new set of choices after that initial choice.
Conceptually, you start at the root of a tree; the tree probably has some good leaves and some bad leaves, though it may be that the leaves are all good or all bad. You want to get to a good leaf. At each node, beginning with the root, you choose one of its children to move to, and you keep this up until you get to a leaf.(See image below)
Explanation of Example:
Starting at Root, your options are A and B. You choose A.
At A, your options are C and D. You choose C.
C is bad. Go back to A.
At A, you have already tried C, and it failed. Try D.
D is bad. Go back to A.
At A, you have no options left to try. Go back to Root.
At Root, you have already tried A. Try B.
At B, your options are E and F. Try E.
E is good. Congratulations!
Source: upenn.edu
"Backtracking" is a term that occurs in enumerating algorithms.
You built a "solution" (that is a structure where every variable is assigned a value).
It is however possible that during construction, you realize that the solution is not successful (does not satisfy certain constraints), then you backtrack: you undo certain assignments of values to variables in order to reassign them.
Example:
Based on your example you want to construct a path in a 2D grid. So you start generating paths from (0,0). For instance:
(0,0)
(0,0) (1,0) go right
(0,0) (1,0) (1,1) go up
(0,0) (1,0) (1,1) (0,1) go left
(0,0) (1,0) (1,1) (0,1) (0,0) go down
Oops, visiting a cell a second time, this is not a path anymore
Backtrack: remove the last cell from the path
(0,0) (1,0) (1,1) (0,1)
(0,0) (1,0) (1,1) (0,1) (1,1) go right
Oops, visiting a cell a second time, this is not a path anymore
Backtrack: remove the last cell from the path
....
From Wikipedia:
Backtracking is a general algorithm for finding all (or some) solutions to some computational problem, that incrementally builds candidates to the solutions, and abandons each partial candidate c ("backtracks") as soon as it determines that c cannot possibly be completed to a valid solution.
Backtracking is easily implemented as a recursive algorithm. You look for the solution of a problem of size n by looking for solutions of size n - 1 and so on. If the smaller solution doesn't work you discard it.
That's basically what the code above is doing: it returns true in the base case, otherwise it 'tries' the right path or the left path discarding the solution that doesn't work.
Since the code above it's recursive, it might not be clear where the "backtracking" comes into play, but what the algorithm actually does is building a solution from a partial one, where the smallest possible solution is handled at line 5 in your example. A non recursive version of the algorithm would have to start from the smallest solution and build from there.
I cannot figure out what "backtracking algorithm" means.
An algorithm is "back-tracking" when it tries a solution, and on failure, returns to a simpler solution as the basis for new attempts.
In this implementation,
current_path.remove(p)
goes back along the path when the current path does not succeed so that a caller can try a different variant of the path that led to current_path.
Indeed, the word "back" in the term "backtracking" could sometimes be confusing when a backtracking solution "keeps going forward" as in my solution of the classic N queens problem:
/**
* Given *starting* row, try all columns.
* Recurse into subsequent rows if can put.
* When reached last row (stopper), increment count if put successfully.
*
* By recursing into all rows (of a given single column), an entire placement is tried.
* Backtracking is the avoidance of recursion as soon as "cannot put"...
* (eliminating current col's placement and proceeding to the next col).
*/
int countQueenPlacements(int row) { // queen# is also queen's row (y axis)
int count = 0;
for (int col=1; col<=N; col++) { // try all columns for each row
if (canPutQueen(col, row)) {
putQueen(col, row);
count += (row == N) ? print(board, ++solutionNum) : countQueenPlacements(row+1);
}
}
return count;
}
Note that my comment defines Backtracking as the avoidance of recursion as soon as "cannot put" -- but this is not entirely full. Backtracking in this solution could also mean that once a proper placement is found, the recursion stack unwinds (or backtracks).
Backtracking basically means trying all possible options. It's usually the naive, inefficient solutions to problems.
In your example solution, that's exactly what's going on - you simply try out all possible paths, recursively:
You try each possible direction; if you found a successful path - good. if not - backtrack and try another direction.

2D Matrix using Singly Linked Lists in Java

I am having a hard time of how to approach the problem of creating a 2D matrix in Java using a Singly Linked List as the underlying data structure. The goal is to have the user input the number of rows and columns and we create this matrix and the user has the option to display, insert, fill, or compute the row and column sums. Each node in the matrix should have a right pointer and a down pointer (when applicable). If you could help me out, I'd really appreciate it.
EX) Display function of a 2x3 matrix should look something like this
00->01->02
10->11->12
00 should point down to 10, 01 to 11 and 02 to 12
hopefully that visual representation helps
Thanks!
If node in your list have references to more than two elements (previous and next), it is not a list, it's more complicated data structure.
For your problem I recommend you to create function, which allows you to transfer Cartesian coordinates into linear coordinates. Then add elements into list by linear coordinates (I think, ArrayList is more suitable for you). Technically, your matrix will be stored in a single list.
Implementation of a simple singly linked list should be easily available online. A few modifications are needed in the linked list (Assuming singly here means unidirectional, right and down, but not left and up):
1. You'll need to two variables, to keep track of rows and columns.
2. You'll need a size variable, increment it after each element is added.
3. Modify the add method, so that whenever the size is > column (when a column fills up), point your down pointer of above node to the adding node, node[size-column].down = thisNode. (assuming you insert them column by column)
4. Display method should be pretty easy, iterate through column, if index > column, move to a new line.
5. Compute Row/Column sums by iterating through .next/ .down, (while hasnext, sum += next)
You can find the solution code for this problem here:
https://github.com/manoj7shekhawat/dataStructures/blob/master/Examples/Chap05/matrix/matrixApp.java

Categories

Resources