This is great, but the Github literate Haskell code looks so much better (cleaner, syntax highlighting, etc.) than your blog formatting - I found the code fragments impossible to read.
Is this considered a nice Haskell style for this kind of programs? If so, I prefer how LP looks in Python. If someone is interested, my presentation slides:
Note this presentation was given to an audience that mostly knew ILP and has used it before for combinatorial optimization, so I'm not gentle with theory. It's just to show that Python is a little nicer than Java to do it.
IMHO, his Haskell style is a little weird and not really the typical (or the best). The dailyCost function is a particularly ghastly example of bad layout and visual code organization.
Then there are things like
map (\(x,y) -> x) reservationFixedCosts
instead of
map fst reservationFixedCosts
I'm also not a big fan of extensive use of list comprehensions; I'd prefer using "map" instead wherever I can.
The whole thing could definitely look much cleaner.
It's throwaway code written for a blog post, and could certainly be cleaned up.
However, Python code to solve the same problem would probably look very similar to the Haskell code. The initial example given in that presentation has only 4 variables and 4 constraints (slide 5), I have 15 and 27.
Once you get to bigger problems, python code winds up looking similarly ugly. See lines 14-15 in that presentation. As the problems get bigger, your code isn't representing the LP problem. It's translating a small problem specification into a much bigger LP problem.
Indeed, with type information you can do quite sophisticated embedded DSLs that heavily reuse the host language's infrastructure for variables, control and types.
So no need for the LpVariable stuff, for example, and you get type safety.
An example of an SMT solver DSL, which:
* reuses Haskell's type checker to check the types of the embedded language,
* uses Haskell's polymorphism to add polymorphism to the underlying language
* and the host language's variables as target language variables.
Linear Programming is one of those things that's usually underrated (and sometimes overrated)
But I would probably not use Haskell and just create the problem as a text file in whatever format GLPK accepts - probably a derivative of 'the standart format' (which is bad for very complex problems, still)
I'd write the program anyway, however - the text file would actually be quite large. This problem has 15 variables and 27 constraints (if I counted correctly). Your plain text input to glpk would be at least 43 lines long (counting the objective function), compared to about 30 lines of haskell.
If your usage pattern varied daily (e.g., one pattern for monday, a different one for tuesday), your input would become even bigger. The only modification to the haskell code would be:
main = do
printLPSolution (Map.fromList [ ("mon_0", 12.2), ("mon_1", 25.1), ("mon_2", 53.5),
("tues_0", 15.8), ("tues_1", 33.9), ("tues_2", 76.2),
...
])
Cool that they're using Haskell for something.
But this would be much better done in Mathematica, Octave, R or Macsyma. It's an operations research optimization problem and all of those environments have packages for OR.
I'd be very surprised if it was as easy to set up the problem in R or Macsyma. In those languages, you'd probably need to write loops to generate your constraints (but maybe I'm wrong, I'm no R-expert).
Well, my experience is in mathematica. Which has operations research functions built right in. Point being, there are systems where this is already a solve problem, where you can get your answer in a minute or two.
So you'd simply do Minimize[function, {variables/constraints}] and then get on with your day.
If Mathematica is so easy, I'd love to see a significantly simpler version of the same problem written in it. But I have absolutely no idea how I'd write that simpler version.
The vast majority of the code I wrote is setting up the problem (which has 15 vars and 27 constraints), not solving it. I.e., those list comprehensions are a way of writing 9 constraints on a single line.
To demonstrate mathematica is easier, you need to demonstrate that it's similarly easy to translate the problem from a verbal specification to an LP problem. Solving LP is the easy part.
There are packages in R that use GLPK api calls so it would be made simpler. See Rglpk http://cran.r-project.org/web/packages/Rglpk/index.html. But if one is originally coding in a particular langauge (in this case Haskell) then I would think coding within that language would be easier.
The literate Haskell version on Github:
https://github.com/stucchio/Cloud-capacity-planning/blob/mas...