/*********************************************************************
* Author: Isai Damier
* Title: Path of Optimum Grid Harvest
* Project: geekviewpoint
* Package: algorithms
*
* Statement:
* Given n boxes of avocados tightly arranged in a h*w grid, and given
* that you may only move down or to the right, amass the maximum
* number of avocados and show the path taken.
*
* Time-complexity: O(n)
*
* Dynamic Programming Strategy:
*
* The solution to this problem is exactly as describe in the Optimum
* Grid Harvest implementation -- plus one more step.
* http://www.geekviewpoint.com/java/dynamic_programming/grid_harvest.
*
* To find the optimum number of avocados we keep moving down and
* to the right from the first cell A[0][0] to the last cell A[h][w].
* For the second phase, to find the optimal path, simply do the reverse
* with V[1..h][1..w]. That is, we walk from V[h][w] to V[0][0] by
* moving left and up, always toward the maximum.
*
**********************************************************************/
public List<Integer> gridHarvestPath(int[][] grid) {
if (null == grid) {
return null;
}
//exactly as simple gridHarvest problem
int[][] value = new int[grid.length][grid[0].length];
int xMax = grid.length - 1;
int yMax = grid[0].length - 1;
for (int x = 0; x <= xMax; x++) {
for (int y = 0; y <= yMax; y++) {
amass(grid, x, y, value);
}
}
//trace the boxes selected
List<Integer> path = new ArrayList<Integer>();
path.add(grid[xMax][yMax]);
int x = xMax;
int y = yMax;
while (x > 0 && y > 0) {
if (value[x][y - 1] < value[x - 1][y]) {
path.add(grid[--x][y]);
} else {
path.add(grid[x][--y]);
}
}
while(x > 0){
path.add(grid[--x][y]);
}
while(y > 0){
path.add(grid[x][--y]);
}
return path;
}
private void amass(int[][] grid, int x, int y, int[][] value) {
if (0 < x && 0 < y) {
value[x][y] = grid[x][y] + Math.max(value[x - 1][y], value[x][y - 1]);
} else if (0 < x) {
value[x][y] = grid[x][y] + value[x - 1][y];
} else if (0 < y) {
value[x][y] = grid[x][y] + value[x][y - 1];
} else {
value[x][y] = grid[x][y];
}
}
package algorithm.programming.dynamic;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.*;
public class HarvestingTest {
/**
* Test of gridHarvestPath method, of class Harvesting.
*/
@Test
public void testGridHarvestStaircasePath() {
System.out.println("gridHarvestPath");
int[][] grid = {
{51, 42, 33, 25, 18},
{13, 21, 34, 55, 89},
{82, 63, 45, 27, 11},
{13, 17, 19, 23, 29}
};
Harvesting instance = new Harvesting();
List expResult = Arrays.asList(29,11,89,55,34,33,42,51);
List result = instance.gridHarvestPath(grid);
assertEquals(expResult, result);
}
/**
* Test of gridHarvestPath method, of class Harvesting.
*/
@Test
public void testGridHarvest7Path() {
System.out.println("gridHarvestPath");
int[][] grid = {
{51, 92, 93, 97, 98},
{13, 21, 34, 55, 89},
{82, 63, 45, 27, 11},
{13, 17, 19, 23, 29}
};
Harvesting instance = new Harvesting();
List expResult = Arrays.asList(29,11,89,98,97,93,92,51);
List result = instance.gridHarvestPath(grid);
assertEquals(expResult, result);
}
/**
* Test of gridHarvestPath method, of class Harvesting.
*/
@Test
public void testGridHarvestLPath() {
System.out.println("gridHarvestPath");
int[][] grid = {
{51, 42, 33, 25, 18},
{93, 21, 34, 55, 89},
{92, 63, 45, 17, 11},
{93, 67, 59, 23, 29}
};
Harvesting instance = new Harvesting();
List expResult = Arrays.asList(29,23,59,67,93,92,93,51);
List result = instance.gridHarvestPath(grid);
assertEquals(expResult, result);
}
}