Application Center - Maplesoft

App Preview:

Optimal Speed of an 18-Wheeler

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application



Optimal Speed of an 18-Wheeler 

by J. Schattman
Sir John A. Macdonal Secondary School, Waterloo, Canada

Problem description 

Suppose you manage a trucking company that delivers goods between two cities.  You want to maximize profits by choosing the best cruising speed of your trucks on the highway. Driving faster increases the number of goods your company can deliver per week (and thus, your revenue) but also increases your fuel costs because of the lower efficiency of the trucks at higher speeds.  


In this application, we use real fuel-economy data to build a mathematical model for determining the optimal speed.  We'll solve the model graphically, and then analytically using calculus. 


At the end just for fun, you can use dials to adjust the parameters of the problem, and the speedometer will display the optimal speed.  


ButtonUnits:-AddUnit(CAD, context=CA 


Define the variables 

Independent variable 

s = cruising speed of the truck `/`(`*`(km), `*`(hour)) 



d = distance of the delivery route km 

r = revenue earned per delivery (Canadian $) 

f = cost per litre of diesel fuel (
w = weight of the truck plus its cargo (kg) 


Dependent variables 

e = fuel economy of the truck, as a function of s and w `*`(Litres, `*`(`/`(`+`(`*`(100, `*`(km)))))) 

p = profit earned per hour of driving, as a function of s, d, r, f, w and e  


Build a mathematical model 

We seek to maximizep = `+`(`*`(Revenue, `*`(per, `*`(hour))), `-`(`*`(Fuel, `*`(cost, `*`(per, `*`(hour)))))) (3.1)  


Revenue per hour is just `/`(`*`(r, `*`(s)), `*`(d)).  This is easiest to see by cancelling units, as illustrated below. 

`/`(`*`(r, `*`(Unit('CAD'), `*`(s, `*`(Unit(`/`(`*`('km'), `*`('hour'))))))), `*`(d, `*`(Unit('km'))))`+`(`/`(`*`(`/`(1, 3600), `*`(r, `*`(s, `*`(Units:-Unit(`/`(`*`('USD'), `*`('s'))))))), `*`(d)))`/`(`*`(r, `*`(s, `*`(Units:-Unit(`/`(`*`('CAD'), `*`('hour')))))), `*`(d)) 



Fuel cost per hour is just `+`(`*`(`/`(1, 100), `*`(f, `*`(e, `*`(s))))).  (We divide by 100 because e is measured in Litres per 100 km.) 


`+`(`*`(`/`(1, 100), `*`(f, `*`(Unit(`/`(`*`('CAD'), `*`('L'))), `*`(e, `*`(Unit(`/`(`*`('L'), `*`('km'))), `*`(s, `*`(Unit(`/`(`*`('km'), `*`('hour')))))))))))`+`(`*`(`/`(1, 360000), `*`(f, `*`(e, `*`(s, `*`(Units:-Unit(`/`(`*`('USD'), `*`('s')))))))))`+`(`*`(`/`(1, 100), `*`(f, `*`(e, `*`(s, `*`(Units:-Unit(`/`(`*`('CAD'), `*`('hour'))))))))) 


Thus, we have 

p = `+`(`/`(`*`(r, `*`(s)), `*`(d)), `-`(`*`(`/`(1, 100), `*`(f, `*`(e, `*`(s)))))) (3.2)



If e were constant, then the optimal strategy would be to drive as fast as possible and hope the police aren't looking.  (This assumes `>`(`+`(`/`(`*`(r), `*`(d)), `-`(`*`(`/`(1, 100), `*`(f, `*`(e))))), 0).)  But as we will see in the next section, e falls drastically with s, and so we will need to curb our aggressive driving habits if we wish to maximize profits. 


Estimating e using real data 

In this section, we use data from the 2004 report "Factors Affecting Truck Fuel Economy", published by Goodyear Inc., to estimate mpg(s), the fuel economy of a typical 18-wheeler in mpg as a function of speed.  We'll then use mpg(s) to derive kpl(s), the fuel economy in km/L, by converting to Canadian units.  Finally, we'll obtain e(s) by inverting kpl(s) and multiplying by 100. 


Estimating e in American units 

According to the Goodyear report:

  • The optimal fuel economy of an 18-wheeler is achieved at a speed of 55 mph.

  • At 55 mph, a 25,000-lb truck on a flat road gets about 5.7 mpg.  

  • For every 1000-lb increase in load, fuel efficiency drops by about `/`(1, 60) mpg.

  • Aerodynamic drag on the truck increases exponentially with its speed.  As a result, for every 5 mph increase in speed above 55 mph, fuel economy drops by about 8%.


Letting w represent the weight in pounds, points 1-3 imply that

mpg(55) = `+`(5.7, `-`(`*`(`/`(1, 60), `*`(`*`(`+`(w, `-`(25000)), `/`(1, 1000))))))  


which simplifies to  

mpg(55) = `+`(6.116666667, `-`(`*`(`/`(1, 60000), `*`(w)))) (4.1.1)


To account for point 4 above, we just multiply mpg(55) = `+`(5.7, `-`(`*`(`/`(1, 60), `*`(`*`(`+`(w, `-`(25000)), `/`(1, 1000)))))) by `^`(.92, `*`(`+`(s, `-`(55)), `/`(1, 5))), obtaining

mpg(s) = `*`(`+`(6.116666667, `-`(`*`(`/`(1, 60000), `*`(w)))), `*`(`^`(.92, `*`(`+`(s, `-`(55)), `/`(1, 5))))) 


where we assume that `>=`(s, `+`(`*`(55, `*`(Unit(`/`(`*`('miles'), `*`('hour'))))))) 

Converting to Canadian/European units 

Maple can save us a great deal of drudgery here with the handy Replace Units menu option (Right-click/Units/Replace Units). 


`+`(`*`(6.116666667, `*`(Unit(`/`(`*`('miles'), `*`('gallon'))))))`+`(`*`(2.600462344, `*`(Units:-Unit(`/`(`*`('km'), `*`('L')))))) 


`+`(`-`(`*`(`/`(60000.0), `*`(Unit(`/`(`*`('miles'), `*`('gallon', `*`('po', `*`('und')))))))))`+`(`-`(`*`(0.1562135725e-4, `*`(Units:-Unit(`/`(`*`('km'), `*`('L', `*`('kg')))))))) 

`+`(`-`(`*`(55.0, `*`(Unit(`/`(`*`('miles'), `*`('hour')))))))`+`(`-`(`*`(88.51392000, `*`(Units:-Unit(`/`(`*`('km'), `*`('h'))))))) 

`+`(`*`(5, `*`(Unit(`/`(`*`('miles'), `*`('hour'))))))`+`(`*`(`/`(25146, 3125), `*`(Units:-Unit(`/`(`*`('km'), `*`('h')))))) 

`/`(25146, 3125)8.0467 


With these conversions, we may now assume that s is measured in km/h and w is measured in kg in the following formula 

kpl(s) = `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `*`(`+`(s, `-`(88.51392)), `*`(`/`(8.0467)))))) 


which simplifies to  

kpl(s) = `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734))))) (4.2.1)


Finally, we have e = `+`(`/`(`*`(100), `*`(kpl(s)))) 



e = `+`(`/`(`*`(100), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734))))))) (4.2.2)


Exploring the model 

Substituting this estimate for e into p = `+`(`/`(`*`(r, `*`(s)), `*`(d)), `-`(`*`(`/`(1, 100), `*`(f, `*`(e, `*`(s)))))), our formula for hourly profit becomes 

p = `+`(`/`(`*`(r, `*`(s)), `*`(d)), `-`(`/`(`*`(f, `*`(s)), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734)))))))) (5.1)



A numerical example 

Assuming r = $1,500, d = 500 km, f = $1.35/L, and w = 60000 kg, equation eval(p = `+`(`/`(`*`(r, `*`(s)), `*`(d)), `-`(`*`(`/`(1, 100), `*`(f, `*`(e, `*`(s)))))), e = `+`(`/`(`*`(100), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)... becomes  

p = `+`(`*`(3, `*`(s)), `-`(`/`(`*`(.3852365132, `*`(s)), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)))))))) (5.1.1)

0 = `+`(3, `-`(`/`(`*`(.3852365132), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s))))))), `-`(`/`(`*`(0.3991902304e-2, `*`(s)), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s))))))))[[s = 120.0682877]]Plot_2d



In this case, the optimal speed would be 120 km/hour.  It doesn't always pay to drive as fast as possible! 


In search of a general formula 

Let's try to maximize p generally in terms of r, d, f and w.  

p(s) = `+`(`/`(`*`(r, `*`(s)), `*`(d)), `-`(`/`(`*`(f, `*`(s)), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734)))))))) (5.2.1)


Differentiating with respect to s, we getdiff(p(s), s) = `+`(`/`(`*`(r), `*`(d)), `-`(`/`(`*`(0.1036221170e-1, `*`(f, `*`(s))), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734)))))))...
diff(p(s), s) = `+`(`/`(`*`(r), `*`(d)), `-`(`/`(`*`(0.1036221170e-1, `*`(f, `*`(s))), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734)))))))... (5.2.2)


We set the RHS to zero and try to solve for s, but there is no closed-form solution! 

0 = `+`(`/`(`*`(r), `*`(d)), `-`(`/`(`*`(0.1036221170e-1, `*`(f, `*`(s))), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734))))))), `-`(`/`(`*...
0 = `+`(`/`(`*`(r), `*`(d)), `-`(`/`(`*`(0.1036221170e-1, `*`(f, `*`(s))), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734))))))), `-`(`/`(`*...



Warning, solutions may have been lost


Not that we expected one anyway!  The product of an exponential term with a linear term (note s in the numerator) usually spells doom for algebraic solutions, and this function is no exception.  (We were able to solve the problem in Equation expand(eval(p = `+`(`/`(`*`(r, `*`(s)), `*`(d)), `-`(`/`(`*`(f, `*`(s)), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734)))))))), {d = 500, f... only because all coefficients were numeric and so Maple could find the zeros of the derivative numerically). 


Can we get around this road block? 


Simplifying the model by linearizing e. 

Recall our formula for e(s).  

e(s) = `+`(`/`(`*`(100), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`^`(.92, `+`(`*`(.1242745473, `*`(s)), `-`(11.00002734))))))) (5.3.1)


Note that the graph of the factor y = `^`(.92000, `+`(`*`(.12427, `*`(s)), `-`(11.00003))) is almost linear over the range of speeds truckers drive!   



Idea:  Replace y with its "closest" linear approximation in the formula for p making it much easier to solve for the optimal value of s algebraically. 


To derive a good linear approximation of y, we will determine the linear function `+`(`*`(a, `*`(s)), b) that has the minimum squared difference with y over an interval of typical speeds, say 80-130 km/h.  To do this, we minimize the following definite integral over all choices of a and b: 


int(`*`(`^`(`+`(`*`(a, `*`(s)), b, `-`(`^`(.92000, `+`(`*`(.12427, `*`(s)), `-`(11.00003))))), 2)), s = 80 .. 130) = `+`(`-`(`*`(8767.591012, `*`(a))), `-`(`*`(85.24565793, `*`(b))), 37.14322842, `*`(50.00000005, `*`(`^`(b, 2))), `*`(561666.6675, `*`(`^`(a, 2))), `*`(10500.00001, `*`(a, `*`(b))))[0.35967440686e-2, [a = -0.879374708828572355e-2, b = 1.77580002267357551]] 


The fitted linear function is y[approx] = `+`(`-`(`*`(0.879e-2, `*`(s))), 1.77580)and is plotted below with the original. 

Plot_2dWith this approximation, p becomes 

p(s) = `+`(`/`(`*`(r, `*`(s)), `*`(d)), `-`(`/`(`*`(f, `*`(s)), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`+`(`-`(`*`(0.879e-2, `*`(s))), 1.77580)))))) (5.3.2)


Differentiating in s, we getdiff(p(s), s) = `+`(`/`(`*`(r), `*`(d)), `-`(`/`(`*`(f), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`+`(`-`(`*`(0.879e-2, `*`(s))), 1.77580))))), `-`(`/`(`*`(0.879e-2, `*`(f, `*`(s))), `*`(`+...
diff(p(s), s) = `+`(`/`(`*`(r), `*`(d)), `-`(`/`(`*`(f), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`+`(`-`(`*`(0.879e-2, `*`(s))), 1.77580))))), `-`(`/`(`*`(0.879e-2, `*`(f, `*`(s))), `*`(`+...

Setting to 0 and solving for s, we get  

0 = `+`(`/`(`*`(r), `*`(d)), `-`(`/`(`*`(f), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`+`(`-`(`*`(0.879e-2, `*`(s))), 1.77580))))), `-`(`/`(`*`(0.879e-2, `*`(f, `*`(s))), `*`(`+`(2.60046234...
0 = `+`(`/`(`*`(r), `*`(d)), `-`(`/`(`*`(f), `*`(`+`(2.600462344, `-`(`*`(0.2e-4, `*`(w)))), `*`(`+`(`-`(`*`(0.879e-2, `*`(s))), 1.77580))))), `-`(`/`(`*`(0.879e-2, `*`(f, `*`(s))), `*`(`+`(2.60046234...


[[s = `+`(`/`(`*`(0.7765572886e-4, `*`(`+`(`*`(6503867500., `*`(r, `*`(w))), `-`(`*`(0.8456531262e15, `*`(r))), `*`(250000., `*`(`^`(`+`(`*`(0.2477763660e19, `*`(r, `*`(d, `*`(f)))), `-`(`*`(0.1905633...
[[s = `+`(`/`(`*`(0.7765572886e-4, `*`(`+`(`*`(6503867500., `*`(r, `*`(w))), `-`(`*`(0.8456531262e15, `*`(r))), `*`(250000., `*`(`^`(`+`(`*`(0.2477763660e19, `*`(r, `*`(d, `*`(f)))), `-`(`*`(0.1905633...
[[s = `+`(`/`(`*`(0.7765572886e-4, `*`(`+`(`*`(6503867500., `*`(r, `*`(w))), `-`(`*`(0.8456531262e15, `*`(r))), `*`(250000., `*`(`^`(`+`(`*`(0.2477763660e19, `*`(r, `*`(d, `*`(f)))), `-`(`*`(0.1905633...
[[s = `+`(`/`(`*`(0.7765572886e-4, `*`(`+`(`*`(6503867500., `*`(r, `*`(w))), `-`(`*`(0.8456531262e15, `*`(r))), `*`(250000., `*`(`^`(`+`(`*`(0.2477763660e19, `*`(r, `*`(d, `*`(f)))), `-`(`*`(0.1905633...
[[s = `+`(`/`(`*`(0.7765572886e-4, `*`(`+`(`*`(6503867500., `*`(r, `*`(w))), `-`(`*`(0.8456531262e15, `*`(r))), `*`(250000., `*`(`^`(`+`(`*`(0.2477763660e19, `*`(r, `*`(d, `*`(f)))), `-`(`*`(0.1905633...


This is called a mess.  Let's demessify it by assigning a numerical value to one of the parameters, say, w = 50000 in the first solution (which is the one that makes physical sense). 


[s = `+`(202.0250284, `-`(`/`(`*`(119.8354802, `*`(`^`(`*`(r, `*`(d, `*`(f))), `/`(1, 2)))), `*`(r))))] (5.3.5)


Maple would have made me much happier if it had printed this as but the punch line is the same and makes perfect intuitive sense:  increasing f or d pulls the optimal speed down, while increasing r pulls it up.   




Control panel 

If you've read this far, you have eaten enough mathematical vegetables to get dessert. 


Using the dials below, set the distance of the delivery route (d), the revenue per delivery (r), the fuel price per litre (f), and the weight of the loaded truck (w).    


The speedometer will then display the optimum speed under those conditions. 


distance per trip (km) 

Embedded component 

Optimal Speed 

revenue per trip ($) 

Embedded component 

Embedded component 

fuel cost  

Embedded component 

weight (tons) 

Embedded component