Download presentation
Presentation is loading. Please wait.
1
Comments on the “Three Piles” Problem
29-May-18
2
My timings Solved 10000 problems of size 5 in 15 milliseconds.
Average time per problem: ms. Solved 200 problems of size 10 in 16 milliseconds. Average time per problem: 0.08 ms. Solved 200 problems of size 15 in 718 milliseconds. Average time per problem: 3.59 ms. Solved 200 problems of size 20 in milliseconds. Average time per problem: ms. Solved 100 problems of size 25 in milliseconds. Average time per problem: ms.
3
Timing graph
4
General approach The “Three Piles” problem can be solved by a backtracking algorithm Roughly, the algorithm goes like this: boolean solve(int numbersPlaced) { if (numbersPlaced== all the numbers) return true; for (each pile p) { if can put the next number, numbersPlaced+1, into pile p { put it in pile p if (solve(numbersPlaced+1)) return true else take the number out again } return false }
5
Problems with this algorithm
It’s much easier for the programmer if the method returns a boolean, but the user demands a solution The method requires some data structures (say, arrays or stacks) to keep working information in We can’t set this information up inside a recursive method We don’t want to hassle the user with extra junk that is only needed to make the algorithm work Solution: Provide a facade method to: Provide a simplified interface to the user Initialize any needed data structures Call the “real” recursive method with whatever parameters are convenient for the programmer, not the user
6
The facade method The user wants to do this: So you do this:
solution = solve(problem) where solution is some data structure containing your results In the code below, I called this data structure a “Solution,” but it might be implemented by (for example) an int[][] So you do this: Solution solve(int[] problem) { Solution solution; // maybe an int[][] // Create the “Solution” data structure and any other data // structures and initializations that you need put problem[0] into your solution pile if (reallySolve(problem, solution, 0, other stuff)) { return solution; } else return null; // Much better than returning a bad solution! }
7
The real recursive method
boolean reallySolve(problem, solution, nextNumber, ...) { if nextNumber == problem size, return true** for each pile p, if we can put nextNumber into pile p { put it in the pile if (reallySolve(problem, solution, nextNumber+1, ...)) return true; else take the number back out again } } return false } ** If some problems may be unsolvable , you should check the “solution” at this point and return false if it doesn’t work
8
Backtracking in general
Solution solve(Problem p) { create object to hold solution; do any other initializations you need; if (solve(p, solution, other stuff)) return solution; else return null; } private boolean solve(Problem p, Solution s, other stuff) { if problem is already solved, return true; for each of the choices available to you { make a choice; if (solve(simpler version of p, s, other stuff)) return true; else undo this choice; // can sometimes be implicit } return false; }
9
Summary The notion of a facade is this:
The code has a complex interface and requires lots of initializations and global structures The user wants a simple and easy to use interface Create a facade to stand between the user and the ugly code and present a simpler interface
10
The End
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.