This is the second of three projects based on the GusAir case study, which is described in the background document. For this project, your goal flows from the following paragraph of that document:
Because dynamic pricing is considerably more complex than a fixed price, GusAir doesn't want to base its business model on dynamic pricing without some idea how much more revenue they could expect to generate. Thus, we have been asked to compare the revenue expected from optimal dynamic pricing with that from an optimally chosen fixed price.
Some results from our class discussion on 2009-09-28 will be helpful to you: the Python code for a dynamic programming approach to calculating the expected revenue for a given fixed price, and a revised version that chooses its own fixed price so as to maximize the expected revenue. (That latter program also includes an improvement from 2009-09-30: it returns the optimal fixed price along with the corresponding expected revenue.)
As we discussed on 2009-09-30, dynamic pricing entails selecting a price for each individual combination of hours remaining and seats remaining (at least where the hours and seats are nonzero). This implies reorganizing the loops in the program, so that the loop that tries possible prices is on the inside of the nesting rather than the outside.
Just like the fixed-price version should return the optimal fixed price along with the corresponding revenue, your dynamic pricing version should return the optimal pricing schedule along with the corresponding revenue. That way, your deliverables can go beyond just a comparison of the expected revenue using dynamic pricing versus static pricing—you can show how the increased expected revenue would be achieved. By a pricing schedule, I mean that your program should produce a table showing what the optimal price is for each combination of hours remaining and seats remaining. Returning the corresponding table of expected revenues, one for each combination of hours and seats, would be good too. Using tuples, there are two possibilities for what you could return, both reasonable: a table of (price, expected revenue) pairs, or a pair of two separate tables, one of prices and the other of expected revenues. The sections below on extra credit opportunities and project report expectations address the question of how you should convey your table of optimal prices to our clients.
Each of the following can earn you up to 10 percentage points of extra-credit:
How do your results (for both static and dynamic pricing) change if you make the customers' willingness to pay time-dependent? One approach to modeling time-dependent willingness to pay would be to change the formula for probability of purchase by replacing the constant 200 with some function of the time. For example, if at some particular number of hours remaining you think prices could be raised 20% without hurting the probability of sale, then you could arrange that the function returns 240 rather than 200 after that time. (You should consider what a plausible form would be for the function; a step from 200 to 240 may not make the most sense.)
To give a more complete understanding of the table of optimal prices, use Python's csv module to write out the full 672 by 30 table of prices and then use some external tool to produce a visualization of the table. Your visualization could be a surface plot, contour plot, or grid of color patches. The table is only 672 by 30, rather than 673 by 31, because you should exclude the cases where 0 hours and/or 0 seats are left. No well-defined optimal price exists in those cases.
Your project report will be graded based on the following expectations. Ten percent of your grade will come from each of these ten areas.
You are to state what problem you have solved, in language that would be clear to a mathematically literate reader who is not familiar with the project assignment. This requires you to succinctly summarize in your own words some of the material in the GusAir background document.
You are to explain the role that dynamic programming plays in our new approach to calculating the revenue-optimizing fixed price and its associated revenue. For example, what are the problem dimensions? What feature of the problem makes the calculation naturally be tree-recursive? How is a table constructed so as to avoid the tree recursion?
You are to compare and contrast the two dynamic-programming procedures, one for fixed price and one for dynamic pricing.
You are to explain the approach you took to selecting different prices to try in order to find which one yields the greatest expected revenue. You should explain why you chose this approach, which will presumably entail briefly comparing it with alternatives. I will not be impressed by an explanation that you chose to search starting from 0 and continuing until the revenue decreases "because that's what we did in class." Also, you should be sure to address the question of whether the same search process that makes sense for finding an optimal fixed price also makes sense for use in each circumstance of time and seats with dynamic pricing.
Your program should generate a table showing the optimal ticket price for each combination of time and seats remaining. There is no need to print this whole table out, so long as your code calculates it. However, to give some idea of the sort of data contained in the table, you should give some sample prices. For example: at the beginning of the month, with all 30 seats available and all 672 hours left in which to sell them, what will the price be? If all 30 seats are still unsold when there are 300 hours remaining, how much will the price be? On the other hand, if at the 300-hour point only one seat remains, how high will the price be? And what if at the very last hour, there are still seats left; how low will the price be?
You are to explain how you gained confidence in your program's results. This should start with a comparison of your fixed-price results with those you previously calculated using a different approach. You should also explain why this checking of your dynamic-programming approach to fixed-price optimization yields some increased confidence in your dynamic-programming approach to dynamic pricing. You should also check the reasonableness of your answers; not only whether the prices lie within a reasonable range, but also whether the trends make sense. If you hold time fixed and change the supply of available seats, how should the price vary? Does it? If you hold the supply of seats fixed and change the time remaining in which customers can demand those seats, how should the price vary? Does it? When would price be unaffected by the availability of more seats? Does your program exhibit that behavior as well? The foregoing questions all concern price trends; what about the expected revenue?
Your code should have all numerical parameters clearly separated out and named, so that if our clients were to change their mind about such things as the plane size, ticket sale period, or demand model, all that would need changing are the values of a few descriptively named variables that are set at the top of the script.
Your code should be divided up into cohesive procedures, each focused on a particular aspect of the problem solution. The procedures should coupled together by well-defined interfaces. That is, the coupling should be through meaningful arguments and return values, which should be documented in the procedures' documentation strings. There should not be any coupling through modification of global variables. (The only global variables should be for the problem's parameters, which are not modified during the program's execution.)
Your procedures should not only be free of bugs, but also as simple and clear as reasonably can be achieved.
Your project report should use devices such as section headings to provide a clear organizational structure. Despite containing all of the explanatory information mentioned earlier, your report should still make it easy for our clients to find the answer to their original question.