Problem 3 of Monte Carlo solutions to Fifty Challenging Problems...

(This is another part of the Fifty Problems series, a set of example applications of Monte Carlo methods. In each post, I present source code which answers a probabilistic question using simulated models of the underlying system.)

In a jury, each individual member has probability p of making the right decision. Which is more likely to find the correct decision: a 3-person jury in which the third member decides by flipping a coin (50/50), or a 1-person jury? (NB: these juries are majority rule, not unanimous)
#!/usr/bin/env ruby

# First off, we need to model the juries:
#  1.  One-man jury: just p every time
#  2.  Three-man jury: p,p,0.5 (majority rules)
#
# The goal is: which jury is more likely to be correct?

# Apparent sexism note: if "woman" was shorter than "man", 
# these would all be n_woman_judgement.  I'm lazy.

def one_man_judgement(p)
	sample = rand()
	if (sample < p)
		return true
	else
		return false
	end
end

def three_man_judgement(p)
	j1 = one_man_judgement(p)
	j2 = one_man_judgement(p)
	j3 = one_man_judgement(0.5)

	if (j1 && j2 || j1 && j3 || j2 && j3)
		return true
	else
		return false
	end	
end

# So, now we can get the judgement of a jury by calling one of the above.
# if it's true, they got the correct judgement; if false, they got it wrong.

# Since we're leaving p unspecified, we should sample it at multiple
# values.  I usually go for 20 right up front, since it's often over
# the precision needs of a problem.  If you see anything fishy (esp
# non-monotonic behavior), you probably want to run again with tighter
# buckets, to get a better idea of the shape of the curve.

SAMPLE_WIDTH=0.05
TRIALS=10000

one_man_wins = 0
three_man_wins = 0

p = 0.0
while (p <= 1.0)
	# now, we create the confusion matrix:

	one_man_outcomes = { :correct => 0, :incorrect => 0 }
	three_man_outcomes = { :correct => 0, :incorrect => 0 }

	TRIALS.times do
		o = one_man_judgement(p)
		t = three_man_judgement(p)

		one_man_outcomes[ o ? :correct : :incorrect ] += 1
		three_man_outcomes[ t ? :correct : :incorrect ] += 1
	end

	p_one = one_man_outcomes[:correct] / TRIALS.to_f
	p_three = three_man_outcomes[:correct] / TRIALS.to_f
	puts "==== #{p} // #{TRIALS} ===="
	puts "sample\ttrue\tfalse\tP"
	puts "one\t#{one_man_outcomes[:correct]}\t#{one_man_outcomes[:incorrect]}\t#{p_one}"
	puts "three\t#{three_man_outcomes[:correct]}\t#{three_man_outcomes[:incorrect]}\t#{p_three}"


	one_man_wins += one_man_outcomes[:correct]
	three_man_wins += three_man_outcomes[:correct]

	p += SAMPLE_WIDTH
end


puts
puts "FINAL: At #{one_man_wins} samples one-man is better; at #{three_man_wins} three-man is better"


I've been coding my way through Fifty Challenging Problems in Statistics with Solutions. This post is a part of the Fifty Challenging Problems series.

This was brought to you by Josh Myer. He has other fun things at his homepage.