Skip to content

Instantly share code, notes, and snippets.

@davidrichards
Created November 27, 2011 12:01
Show Gist options
  • Save davidrichards/1397470 to your computer and use it in GitHub Desktop.
Save davidrichards/1397470 to your computer and use it in GitHub Desktop.
The Learning Curve
=begin
One of my favorite equations from business school: the learning curve.
Human experience has shown that every time our experience with a single
task doubles, our efficiency increases by 20%. Our learning curve is
actually around 20%, with a 95% confidence rate around 10% and 30%.
This was the equation that founded BCG as they measured everything
related to the then-new aviation industry. It's been used to measure
all sorts of human tasks and has proven pretty resilient for people of
all kinds of backgrounds and aptitudes.
One interesting extension to this little class would be to calculate
the actual learning curve, given two measurements, but I did this little
exercise to deal with insomnia, and I'm finally feeling sleepy again.
=end
class LearningCurve
RATE = 0.2
attr_accessor :initial_cost
def initialize(initial_cost=1)
@initial_cost = initial_cost
end
attr_writer :n
def n
@n ||= 1
end
def times_doubled
Math.log2(n)
end
def unit_cost
((1 - RATE) ** times_doubled) * initial_cost
end
def assert_initial_cost_assuming_unit_cost_of(unit_cost)
@initial_cost = unit_cost / ((1 - RATE) ** times_doubled)
end
# Had to break out the algebra for this one.
# unit_cost = ((1 -rate)^log base 2(n)) * initial_cost
# unit_cost / initial_cost = (1-rate)^log base 2(n)
# log base(1-rate)(unit_cost / initial_cost) = log base 2(n)
# 2^(log base(1-rate)(unit_cost / initial_cost)) = n
# since log base(1-rate)(unit_cost / initial_cost) = log(unit_cost / initial_cost) / log(1-rate)
# I get this final form, rounded up (since the experience must be finished)
def experience_needed_for_unit_cost_under(unit_cost)
(2**(Math.log(unit_cost.to_f / initial_cost) / Math.log(1 - RATE))).ceil
end
end
require File.expand_path('../spec_helper', __FILE__)
describe LearningCurve do
before do
@curve = LearningCurve.new
end
it "should return 1.0 unit_cost and 0.0 times_doubled at n == 1" do
@curve.n = 1
@curve.unit_cost.should be_within(1.0e-05).of(1.0)
@curve.times_doubled.should eql(0.0)
end
it "should return 0.8 unit_cost and 1.0 times_doubled at n == 2" do
@curve.n = 2
@curve.unit_cost.should be_within(1.0e-05).of(0.8)
@curve.times_doubled.should eql(1.0)
end
it "should return 0.64 unit_cost and 2.0 times_doubled at n == 4" do
@curve.n = 4
@curve.unit_cost.should be_within(1.0e-05).of(0.64)
@curve.times_doubled.should eql(2.0)
end
it "should return 0.512 unit_cost and 3.0 times_doubled at n == 8" do
@curve.n = 8
@curve.unit_cost.should be_within(1.0e-05).of(0.512)
@curve.times_doubled.should eql(3.0)
end
it "should take into account the initial cost" do
initial_cost = 15
unit_rate = 0.64
@curve = LearningCurve.new(initial_cost)
@curve.n = 4
@curve.unit_cost.should be_within(1.0e-05).of(initial_cost * unit_rate)
@curve.times_doubled.should eql(2.0)
end
it "should be able to recompute the initial_cost" do
@curve.n = 10
@curve.assert_initial_cost_assuming_unit_cost_of(2)
# A little algebra to solve for the initial cost
expected = 2 / ((1 - LearningCurve::RATE) ** Math.log2(10))
@curve.initial_cost.should be_within(1.0e-05).of(expected)
end
it "should be able to calculate the number of experiences needed to have a specific unit cost" do
@curve.n = 10
initial_cost = 2 / ((1 - LearningCurve::RATE) ** Math.log2(10))
@curve.initial_cost = initial_cost
# Had to break out the algebra for this one.
expected = (2**(Math.log(1.0 / initial_cost) / Math.log(1 - LearningCurve::RATE))).ceil
@curve.experience_needed_for_unit_cost_under(1).should be_within(1.0e-05).of(expected)
end
end
@curve = LearningCurve.new
@curve.n = 10 # Assuming 10 bowties have been made
@curve.assert_initial_cost_assuming_unit_cost_of(2) # Gives us 4.197184791733325
@curve.experience_needed_for_unit_cost_under(1) # Gives us 87, or 77 more bowties
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment