Java Reference
In-Depth Information
Another way of working it out is to simulate rolling two dice using random numbers between
1 and 6, adding up the number of times that each result was picked, and dividing by the num-
ber of rolls. This is actually a really simple Monte Carlo simulation. The more times we sim-
ulate rolling the dice, the more closely we approximate the actual result—so we really want
to do it a lot.
Example 6-3 shows how we can implement the Monte Carlo approach using the streams lib-
rary. N represents the number of simulations we'll be running, and at we use the
IntStream range function to create a stream of size N . At we call the parallel method in
order to use the parallel version of the streams framework. The twoDiceThrows function
simulates throwing two dice and returns the sum of their results. We use the mapToObj meth-
od in in order to use this function on our data stream.
Example 6-3. Parallel Monte Carlo simulation of dice rolling
public
public Map < Integer , Double > parallelDiceRolls () {
double
double fraction = 1.0 / N ;
return
return IntStream . range ( 0 , N )
. parallel ()
. mapToObj ( twoDiceThrows ())
. collect ( groupingBy ( side -> side ,
summingDouble ( n -> fraction )));
}
At we have a Stream of all the simulation results we need to combine. We use the group-
ingBy collector, introduced in the previous chapter, in order to aggregate all results that are
equal. I said we were going to count the number of times each number occured and divide by
N . In the streams framework, it's actually easier to map numbers to 1/N and add them, which
is exactly the same. This is accomplished in through the summingDouble function. The
Map<Integer, Double> that gets returned at the end maps each sum of sides thrown to its
probability.
I'll admit it's not totally trivial code, but implementing a parallel Monte Carlo simulation in
five lines of code is pretty neat. Importantly, because the more simulations we run, the more
closey we approximate the real answer, we've got a real incentive to run a lot of simulations.
This is also a good use for parallelism as it's an implementation that gets good parallel spee-
dup.
I won't go through the implementation details, but for comparison Example 6-4 lists the
same parallel Monte Carlo simulation implemented by hand. The majority of the code imple-
mentation deals with spawning, scheduling, and awaiting the completion of jobs within a
 
 
 
Search WWH ::




Custom Search