Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jun 1st, 2008, 3:59 PM   #1
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Posts: 1,825
Rep Power: 5 Sane will become famous soon enough
SMAC #1 [05-08] - Hurtles (Senior)

Attached to this post is the test data for Hurtles (Senior).


This problem requires a solution in Dynamic Programming.

If we think recursively, there are n hurtles, each with an option of jump or not jump. Obviously, this makes 2^n different choices if we were to brute force this recursively.

For n=100, 2^{100} is too large of a number to brute force. Those who might attempt a well-coded brute force solution could get it to work for n<20, and be awarded up to 75 points.

int hurtle(int h, int left) {
    if(left < 0) return INFINITY;
    if(h == n) return 0;
    return min( hurtle(h+1, left - energy[h]), 
                hurtle(h+1, left) + times[h] );
}


So now, what do we do if we want a solution that will score full points?

First, let's see why exactly this is a bad solution. If you think back to the fibonacci sequence, and its recursive function, why is it bad?

int fib(int n) {
    if(n == 0) return 0;
    if(n == 1) return 1;
    return fib(n-1) + fib(n-2);
}

This recursive function will usually fail for anything larger than around 30. And why? Because we are doing the same calculations over and over and over.

Say we call fib(8):

fib(8) calls fib(7) and fib(6)
fib(7) calls fib(6) and fib(5)
fib(6) calls fib(5) and fib(4)
fib(5) calls fib(4) and fib(3)
fib(4) calls fib(3) and fib(2)
fib(3) calls fib(2) and fib(1)
fib(2) calls fib(1) and fib(0)
fib(3) calls fib(2) and fib(1)
...
Continuing on for many more iterations...



Repeated calls are happening all over the place, and these redundant calculations cause it to take exponential time.

How do we solve the problem of repeated calculations (also known as repeated subproblems)? You simply solve them in order.

int fib(int n) {
    if(n>=200) return -1;
    int fibs[200];
    fibs[0] = 0;
    fibs[1] = 1;
    for(int i=2; i<=n; i++) 
        fibs[i] = fibs[i-1] + fibs[i-2];
    return fibs[n];
}

This new fibonacci function is dramatically improved from O(k^n) to O(n) time.

This is perhaps one of the simplest examples of Dynamic Programming. A recursive function can be converted into an iterative DP function if and only if its subproblems can be uniquely identified and solved in the correct order.

Let's identify the subproblem for Hurtles:

Let h be the hurdle such that all hurdles from h .. n remain unused.
Let e represent the joules of energy remaining.
Then Penalty(h, e) represents the minimum time penalty for this subproblem.

After a little bit of thought, we come to this formula:

Penalty(h, e) = min( 
    Penalty(h+1, e - energy[h]), 
    Penalty(h+1, e) + times[h] 
);

Now, the somewhat startling observation is, this is exactly the same as the recursive function developed earlier in this post! This is actually characteristic of any DP program that you may see in time.

Now, what about the order that we solve each subproblem in? That would be from right to left for each hurdle (since each subproblem relies on h+1). And from 0 .. max energy for each joule of energy (since each subproblem relies on less energy than currently held).

So where fibonacci numbers can be reduced to a DP problem that requires a 1-dimensional array, this problem can be reduced to a DP problem that requires a 2-dimensional array. We simply walk through each subproblem, and use our recursive formula to solve the problems in the correct order.

n is the number of hurdles
j is the maximum energy

for(h=n-1; h>=0; h--) {
    for(e=0; e<=j; e++) {
        if(e >= energy[h]) Penalty[h][e] = min(Penalty[h+1][e-energy[h]],
                                               Penalty[h+1][e]+times[h]); 
        else Penalty[h][e] = Penalty[h+1][e]+times[h];
    }
}

If you just squint your eyes a little bit, you'll see it still looks like our recursive function developed earlier. The only difference is it's much smarter about how much work it does. It only solves each subproblem once, and there's a maximum n*j subproblems. That makes this solution O(nm) or 100*10,000 = 1,000,000, which is very fast for even the worst case.

Here is the official solution, written in C:

C Syntax (Toggle Plain Text)
  1. #include <stdio.h>
  2. #define MAXN 101
  3. #define MAXJ 10001
  4. #define min(a,b) ((a)<(b)?(a):(b))
  5.  
  6. int energy[MAXN];
  7. int times[MAXN];
  8. int n, j;
  9.  
  10. int best[MAXN][MAXJ] = {0}; // best[h][e] : The minimum time penalty given hurdles 'h .. n' and 'e' joules remaining
  11.  
  12. int main() {
  13. int h, e;
  14.  
  15. freopen("hurtles.in", "rt", stdin);
  16. freopen("hurtles.out", "wt", stdout);
  17.  
  18. scanf("%d %d", &n, &j);
  19. for(h=0; h<n; h++) scanf("%d %d", &energy[h], &times[h]);
  20.  
  21. for(h=n-1; h>=0; h--) { // Solve hurdles right to left
  22. for(e=0; e<=j; e++) { // Solve energy from 0 .. max energy
  23. if(e >= energy[h]) best[h][e] = min(best[h+1][e-energy[h]], best[h+1][e]+times[h]);
  24. else best[h][e] = best[h+1][e] + times[h];
  25. }
  26. }
  27.  
  28. printf("%d\n", best[0][j]);
  29. return 0;
  30. }
Attached Files
File Type: zip hurtles.zip (3.8 KB, 1 views)

Last edited by Sane; Jun 1st, 2008 at 4:12 PM.
Sane is offline   Reply With Quote
Reply

Bookmarks

Tags
smac senior solutions

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
SMAC #1 [05-08] - Results Sane Software Design and Algorithms 6 Jun 2nd, 2008 4:56 PM
Ideas for my Senior Project? joshbax88 Java 1 Apr 26th, 2008 5:57 AM
Architect / Senior Programmer : Asp.net / C# techsupport C# 3 Mar 7th, 2006 9:47 AM
Senior Capstone-Spying Screen Saver Hounder Project Ideas 23 Dec 16th, 2005 7:00 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 6:33 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC