In [ ]:
using Gadfly

In [ ]:
include("spp.jl")

Verify that the static planning problem produces a reasonable work rate allocation, maximum throughput, expected delays, and expected backlogs


In [ ]:
num_decks = 20
work_rate_budget = 1
difficulty = 0.01;

In [ ]:
opt_arrival_rate, opt_work_rates, equilibrium_flow_rates = allocate_work_rates(num_decks, work_rate_budget, difficulty);

In [ ]:
p1 = plot(x=1:num_decks, y=opt_work_rates, Geom.point, Geom.line, Guide.xlabel("Deck"), Guide.ylabel("Work Rate"), Guide.title("Optimal Work Rate Allocation"))

In [ ]:
draw(PDF("figures/lqn/p1.pdf", 12cm, 8cm), p1)

In [ ]:
expected_delays = 1 ./ (opt_work_rates - equilibrium_flow_rates);

In [ ]:
p2 = plot(x=1:num_decks, y=expected_delays, Geom.point, Geom.line, Guide.xlabel("Deck"), Guide.ylabel("Expected Delay"), Guide.title("Intervals between Reviews"))

In [ ]:
draw(PDF("figures/lqn/p2.pdf", 12cm, 8cm), p2)

In [ ]:
p3 = plot(x=1:num_decks, y=expected_delays.*equilibrium_flow_rates, Geom.point, Geom.line, Guide.xlabel("Deck"), Guide.ylabel("Expected Queue Length"), Guide.title("Queue Backlogs"))

In [ ]:
draw(PDF("figures/lqn/p3.pdf", 12cm, 8cm), p3)

How do the optimal work rate allocation and throughput vary with difficulty $\theta$?


In [ ]:
num_decks = 20
work_rate_budget = 1.
difficulties = [0.001, 0.01, 0.05, 0.1];

In [ ]:
res = [allocate_work_rates(num_decks, work_rate_budget, d) for d=difficulties];

In [ ]:
arrival_rates = [x[1] for x=res]
work_rates = [x[2] for x=res];

In [ ]:
colors = ["red", "pink", "orange", "gray", "blue"];

In [ ]:
p4 = plot(map(d -> layer(x=1:num_decks, y=work_rates[d], Theme(default_color=color(colors[d])), Geom.line)[1], 1:length(difficulties)), Guide.xlabel("Deck"), Guide.ylabel("Work Rate"), Guide.title("Optimal Work Rate Allocation"), Guide.manual_color_key("Difficulty", map(string, difficulties), colors[1:length(difficulties)]))

In [ ]:
draw(PDF("figures/lqn/p4.pdf", 12cm, 8cm), p4)

In [ ]:
difficulties = 0.001:0.005:0.1;

In [ ]:
res = [allocate_work_rates(num_decks, work_rate_budget, d) for d=difficulties];

In [ ]:
p5 = plot(x=difficulties, y=[x[1] for x=res], Geom.point, Geom.line, Guide.xlabel("Difficulty"), Guide.ylabel("Max Arrival Rate"), Guide.title("Throughput vs. Difficulty"))

In [ ]:
draw(PDF("figures/lqn/p5.pdf", 12cm, 8cm), p5)

How does the optimal throughput vary with budget $U$?


In [ ]:
num_decks = 5
difficulty = 0.01
budgets = 0.02:0.05:1

In [ ]:
res = [allocate_work_rates(num_decks, d, difficulty) for d=budgets];

In [ ]:
p6 = plot(x=budgets, y=[x[1] for x=res], Geom.point, Geom.line, Guide.xlabel("Work Rate Budget"), Guide.ylabel("Max Arrival Rate"), Guide.title("Throughput vs. Budget"))

In [ ]:
draw(PDF("figures/lqn/p6.pdf", 12cm, 8cm), p6)

Determine the maximum throughput (i.e., the theoretical phase transition threshold) for simulations and the Mechanical Turk experiments


In [ ]:
num_decks = 5
difficulty = 0.0076899999999998905 # from mturk_experiments.ipynb
work_rate_budget = 0.19020740740740741 # from mturk_experiments.ipynb
allocation_heuristic = x -> 1/sqrt(x)

In [ ]:
eps = 1e-6
function bisect(lext_min, lext_max)
    lext_mid = (lext_min + lext_max) / 2
    work_rates = work_rates_of_heuristic(num_decks, work_rate_budget - lext_mid, allocation_heuristic)
    throughput = throughput_for_work_rates(num_decks, work_rates, difficulty)
    if lext_mid > throughput && lext_mid - throughput < eps
        return lext_mid
    elseif lext_mid < throughput
        return bisect(lext_mid, lext_max)
    else
        return bisect(lext_min, lext_mid)
    end
end

In [ ]:
theoretical_phase_transition_threshold = bisect(0.0001, 0.2)

Compute expected recall likelihoods (under the mean-recall approximation) for simulations


In [ ]:
arrival_rates = 0.001:0.0005:0.01

In [ ]:
for arrival_rate in arrival_rates
    work_rates =  work_rates_of_heuristic(num_decks, work_rate_budget-arrival_rate, allocation_heuristic)
    u = work_rates
    l = eq_flow_rates_for_work_rates_and_arrival_rate(num_decks, work_rates, difficulty, arrival_rate)[2]
    i = 1:length(u)
    println((u .- l)./(u.-l.+difficulty./i))
end

In [ ]: