From: John on 21 Jan 2010 04:56 FindMaximum/NMaximize vs. Excel Solver I am looking at a simple model that calculates the best wagers to place on a set of 20 horses, where the goal is to maximize reward vs. risk. Since the bets need to be constrained, I can't use NMaximize. The probabilities are the "real" probabilities of the horses winning; odds are what would be available at the track. I have working versions in Excel and Mathematica, but the Mathematica implementation runs twice as slowly, and it seems that there must be a more elegant way to do it. The examples I've seen for FindMaximum use 3 or fewer variables and list them explicitly. I am mostly interested in understanding if this is the Mathematica way of doing this problem (as opposed to finding a really fast way to bet on horses). solveHorse[]:=Module [{probabilities,odds,totalWager=100,vars,f,inRange,sol}, probabilities={0.2,0.2,0.2,0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.1,0.1}; odds={7,5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,2,2,2,2}; inRange[x_]:=0<=x<=totalWager; f[a__Symbol]:=Module[{ep,var,ws,sp}, ws=List[a]; ep=MapThread[(#1*(1+#2)-totalWager)&,{ws,odds}]; sp= Dot[probabilities,ep]; var=((#-sp)^2)&/@ep; sp/Sqrt[Dot[probabilities,var]] ]; (* 23.08,25.64,25.64,25.64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.0,0.0 <-- Excel answer*) vars=Table[ToExpression["x"<>ToString[i]],{i,1,20}]; sol=FindMaximum[{f[vars]/.List->Sequence, (And@@inRange/@vars) && Total[vars]==totalWager }, vars,AccuracyGoal->6,PrecisionGoal->9,MaxIterations->1000]; Print["Final Rtn/SD: ",First[sol]]; If[#<10^-6,0,#]&/@vars/.Last[sol] ]; Timing[solveHorse[]] Final Rtn/SD: 0.444878 {5.28921, {23.0767,25.6411,25.6411,25.6411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
From: Bill Rowe on 22 Jan 2010 05:40 On 1/21/10 at 4:57 AM, jhurley13(a)gmail.com (John) wrote: >I am looking at a simple model that calculates the best wagers to >place on a set of 20 horses, where the goal is to maximize reward >vs. risk. Since the bets need to be constrained, I can't use >NMaximize. NMaximize allows constraints. For example consider the function x + 5 Sin[x] which has no global maximum and an infinite number of local maxima. To obtain a maximum for x between say 5 and 10 In[4]:= NMaximize[{x + 5 Sin[x], 5 < x < 10}, x] Out[4]= {12.9543,{x->8.05534}} Or for x between 20 and 25 In[5]:= NMaximize[{x + 5 Sin[x], 20 < x < 25}, x] Out[5]= {25.5207,{x->20.6217}} No constraints on x results in the following In[7]:= NMaximize[x + 5 Sin[x], x] Out[7]= {6.67113,{x->1.77215}}
From: John on 26 Jan 2010 06:24 I received an answer from Daniel Lichtblau at Wolfram, and posed this additional question: Stepping back, what would be the right syntax for NMaximize for this problem: w is the list of wagers to optimize, a list of 20 elements; each wager must be between 0 and 100; the sum of the wagers is 100 It seems gross to list out individual variables when Mathematica is so powerful at list processing. Thanks, John -------- His response was as follows, and was just what I was looking for, since I wanted the "Mathematica" way of doing it: It can be set up as below. Notice I do not explicitly list variables. probabilities = {0.2,0.2,0.2,0.2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.1,0.1}; len = Length[probabilities]; odds = {7,5,5,5,5,5,5,5,5,5,5,5,5,5,1,1,2,2,2,2}; vars = Array[w,len]; tot = 100; c1 = Map[#>=0&, vars]; ep = (vars(1+odds)-tot); sp = ep.probabilities; var = (ep-sp)^2; obj = sp / Sqrt[Dot[probabilities,var]]; Timing[NMaximize[{obj,Flatten[{c1,Total[vars]==tot}]}, vars]] That works, but takes around four times longer than FindMaximum. The speed of NMaximize is not troubling to me, but FindMaximum might be slow for this. That is, I'm not sure whether the timing is expected or indicates a speed bump. Daniel -------- In a later message, we were looking at timings: Daniel, Thank you so much for your reply. It not only answers my question, but reminds me how much I still need to learn about Mathematica. If nothing else, I have to take a long look at "a = b" vs. "a:=b". I was still curious about why it took so long, and found that simplifying obj helped speed things up by 20% or so: obj = sp/Sqrt[Dot[probabilities, var]] // Simplify; Timing[NMaximize[{obj, Flatten[{Total[vars] == tot, c1}]}, vars, AccuracyGoal -> 6, PrecisionGoal -> 9]] Just for fun, I tried the different methods available from NMaximize, and found: SimulatedAnnealing 19.2039 RandomSearch 1329.74 DifferentialEvolution 18.9437 NelderMead 99.743 Default 23.7308 FindMaximum 5.43854 If it is OK with you, I'd like to post your response back to the group since it helped me so much; I can attribute it to you or to an anonymous helper. Thanks again. John [...] That's fine with me. Possibly someone will get competitive and maybe figure out a tweak that makes FindMaximum or NMaximize handle this faster. For FindMaximum, I doubt it will be method-related because I believe that function has but one choice (interior point) when given constraints (unless everything is linear or, at worst, objective is quadratic). One possible improvement would be to maximize the square, since (I think) everything is nonnegative. Could use obj2, given as below. obj2 = Simplify[Rationalize[obj]^2, Assumptions -> Map[0 <= # <= 100 &, vars]] Daniel One other thing. If you get rid of variables that correspond to zero probability, the timings become tremendously faster. I do not think this type of smarts could be automated (in NMaximize or Findmaximum), unfortunately. Daniel ---------- I was still curious about why it took so long, and found that simplifying obj helped speed things up by 20% or so: obj = sp/Sqrt[Dot[probabilities, var]] // Simplify; Timing[NMaximize[{obj, Flatten[{Total[vars] == tot, c1}]}, vars, AccuracyGoal -> 6, PrecisionGoal -> 9]] Just for fun, I tried the different methods available from NMaximize, and found: SimulatedAnnealing 19.2039 RandomSearch 1329.74 DifferentialEvolution 18.9437 NelderMead 99.743 Default 23.7308 FindMaximum 5.43854 Thanks for the replies.
From: John on 26 Jan 2010 06:24 Bill, Thanks for the reply. I saw how to use NMaximize itself, but ran into problems with 20 variables and constraints. Daniel's answer showed me the syntax that I had not understood just from documentation. John
|
Pages: 1 Prev: Function and object naming conventions Next: Astrophysical Data Selection |