Skip to content

Commit

Permalink
revamp of code for chapter 3
Browse files Browse the repository at this point in the history
  • Loading branch information
sausheong committed Jul 10, 2012
1 parent 70c1ae4 commit b20dea3
Show file tree
Hide file tree
Showing 13 changed files with 365 additions and 0 deletions.
63 changes: 63 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-10.rb
@@ -0,0 +1,63 @@
require 'csv'
require './restroom'

# Simulation script 3 (and 4)

max_frequency = 5 # how many times a person goes to the restroom with the period
facilities_per_restroom = 3
max_use_duration = 1
population_range = 10..600 # using a population range of 0 to 500 people
max_num_of_restrooms = 1..4

max_num_of_restrooms.each do |num_of_restrooms|
data = {}
population_range.step(10).each do |population_size|
Person.population.clear
population_size.times { Person.population << Person.new(rand(max_frequency)+1, rand(max_use_duration)+1) } # create the population
data[population_size] = [] #initialize the temp data store
restrooms = []
num_of_restrooms.times {restrooms << Restroom.new(facilities_per_restroom)} # create the restroom

# iterate over a period
DURATION.times do |t|
restroom_shortest_queue = restrooms.min {|n,m| n.queue.size <=> m.queue.size }
data[population_size] << restroom_shortest_queue.queue.size # we want the queue size
restrooms.each {|restroom|
queue = restroom.queue.clone # clone the queue so that we don't mess up the live one
restroom.queue.clear # clear the queue

# let everyone from the queue enter the restroom first
until queue.empty?
restroom.enter queue.shift # de-queue the first person in line and move him to the restroom
end
}
# for each person in the population check if he needs to go
Person.population.each do |person|
person.frequency = (t > 270 and t < 390) ? 12 : rand(max_frequency)+1 # peak for lunch time
if person.need_to_go?
restroom = restrooms.min {|a,b| a.queue.size <=> b.queue.size}
restroom.enter person
end
end
restrooms.each {|restroom| restroom.tick }
end

end

# write the temp store into CSV
CSV.open("simulation3-#{num_of_restrooms}.csv", 'w') do |csv|
# setup labels
lbl = []
population_range.step(10).each {|population_size| lbl << population_size }
csv << lbl

# write the data
DURATION.times do |t|
row = []
population_range.step(10).each do |population_size|
row << data[population_size][t]
end
csv << row
end
end
end
56 changes: 56 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-10b.rb
@@ -0,0 +1,56 @@
require 'csv'
require './restroom'

# Simulation script 3 (generating data for final simulation)

max_frequency = 5 # how many times a person goes to the restroom with the period
facilities_per_restroom = 12
max_use_duration = 1
population_range = 10..600 # using a population range of 0 to 500 people

data = {}
population_range.step(10).each do |population_size|
Person.population.clear
population_size.times { Person.population << Person.new(rand(max_frequency)+1, rand(max_use_duration)+1) } # create the population
data[population_size] = [] #initialize the temp data store
restroom = Restroom.new facilities_per_restroom # create the restroom

# iterate over a period
DURATION.times do |t|
data[population_size] << restroom.queue.size # we want the queue size
queue = restroom.queue.clone # clone the queue so that we don't mess up the live one
restroom.queue.clear # clear the queue

# let everyone from the queue enter the restroom first
until queue.empty?
restroom.enter queue.shift # de-queue the first person in line and move him to the restroom
end

# for each person in the population check if he needs to go
Person.population.each do |person|
person.frequency = (t > 270 and t < 390) ? 12 : rand(max_frequency)+1 # peak for lunch time
if person.need_to_go?
restroom.enter person
end
end
restroom.tick
end

end

# write the temp store into CSV
CSV.open('simulation3.csv', 'w') do |csv|
# setup labels
lbl = []
population_range.step(10).each {|population_size| lbl << population_size }
csv << lbl

# write the data
DURATION.times do |t|
row = []
population_range.step(10).each do |population_size|
row << data[population_size][t]
end
csv << row
end
end
21 changes: 21 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-11a.r
@@ -0,0 +1,21 @@
library(ggplot2)

pdf("figure3-7.pdf")

df <- function(sim) {
data <- read.table(paste(sim,".csv",sep=""), header=TRUE, sep=",")
max <- apply(data,2,max)
return(data.frame(population=seq(from=10,to=600,by=10),max=max))
}

ggplot() + scale_shape_manual(name="Type", values=c(2,3,4,22)) +
geom_smooth(data = df("simulation3-1"), aes(x=population,y=max)) +
geom_point(data = df("simulation3-1"), aes(x=population,y=max,shape="max1")) +
geom_smooth(data = df("simulation3-2"), aes(x=population,y=max)) +
geom_point(data = df("simulation3-2"), aes(x=population,y=max,shape="max2")) +
geom_smooth(data = df("simulation3-3"), aes(x=population,y=max)) +
geom_point(data = df("simulation3-3"), aes(x=population,y=max,shape="max3")) +
geom_smooth(data = df("simulation3-4"), aes(x=population,y=max)) +
geom_point(data = df("simulation3-4"), aes(x=population,y=max,shape="max4")) +
scale_y_continuous("queue size") +
scale_x_continuous("population")
15 changes: 15 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-11b.r
@@ -0,0 +1,15 @@
library(ggplot2)

pdf("figure3-8.pdf")
data <- read.table("simulation3-1.csv", header=TRUE, sep=",")
df <- data.frame(table(data$X70))
colnames(df) <- c("queue_size", "frequency")
percent_labels <- paste(df$frequency, '(', round(df$frequency*100/540, 2), '%)')

ggplot(data=df) + opts(legend.position = "none") + scale_fill_grey(start = 0.5, end = 0.8) +
geom_bar(aes(x = queue_size, y = frequency, fill = factor(queue_size))) +
geom_text(aes(x = queue_size, y = frequency, label = percent_labels, size=1)) +
scale_y_continuous("frequency") +
scale_x_discrete("queue size")

print(df)
17 changes: 17 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-12.r
@@ -0,0 +1,17 @@
library(ggplot2)

pdf("figure3-9.pdf")

df <- function(sim) {
data <- read.table(paste(sim,".csv",sep=""), header=TRUE, sep=",")
max <- apply(data,2,max)
return(data.frame(population=seq(from=10,to=600,by=10),max=max))
}

ggplot() + scale_shape_manual(name="Type", values=c(2,3,4,22)) +
geom_smooth(data = df("simulation3"), aes(x=population,y=max)) +
geom_point(data = df("simulation3"), aes(x=population,y=max,shape="max-1x12")) +
geom_smooth(data = df("simulation3-4"), aes(x=population,y=max)) +
geom_point(data = df("simulation3-4"), aes(x=population,y=max,shape="max-4x3")) +
scale_y_continuous("queue size") +
scale_x_continuous("population")
16 changes: 16 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-13.r
@@ -0,0 +1,16 @@
library(ggplot2)

pdf("figure3-10.pdf")

data <- read.table("simulation3-4.csv", header=TRUE, sep=",")
df <- data.frame(table(data$X400))
colnames(df) <- c("queue_size", "frequency")
percent_labels <- paste(df$frequency, '(', round(df$frequency*100/540, 2), '%)')

ggplot(data=df) + opts(legend.position = "none") +
geom_bar(aes(x = queue_size, y = frequency, fill = factor(queue_size))) +
geom_text(aes(x = queue_size, y = frequency, label = percent_labels, size=1)) +
scale_y_continuous("frequency") +
scale_x_discrete("queue size")

print(df)
55 changes: 55 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-4.rb
@@ -0,0 +1,55 @@
require 'csv'
require './restroom'

# Simulation script 1

frequency = 3 # how many times a person goes to the restroom with the period
facilities_per_restroom = 3
use_duration = 1
population_range = 10..600 # using a population range of 0 to 500 people

data = {}
population_range.step(10).each do |population_size|
Person.population.clear
population_size.times { Person.population << Person.new(frequency, use_duration) } # create the population
data[population_size] = [] #initialize the temp data store
restroom = Restroom.new facilities_per_restroom # create the restroom

# iterate over a period
DURATION.times do |t|
data[population_size] << restroom.queue.size # we want the queue size
queue = restroom.queue.clone # clone the queue so that we don't mess up the live one
restroom.queue.clear # clear the queue

# let everyone from the queue enter the restroom first
until queue.empty?
restroom.enter queue.shift # de-queue the first person in line and move him to the restroom
end


# for each person in the population check if he needs to go
Person.population.each do |person|
if person.need_to_go?
restroom.enter person
end
end
restroom.tick
end
end

# write the temp store into CSV
CSV.open('simulation1.csv', 'w') do |csv|
# setup labels
lbl = []
population_range.step(10).each {|population_size| lbl << population_size }
csv << lbl

# write the data
DURATION.times do |t|
row = []
population_range.step(10).each do |population_size|
row << data[population_size][t]
end
csv << row
end
end
19 changes: 19 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-5.r
@@ -0,0 +1,19 @@
library(ggplot2)

pdf("figure3-2.pdf")
data <- read.table("simulation1.csv", header=TRUE, sep=",")
mean <- mean(data)
median <- apply(data,2,median)
max <- apply(data,2,max)
df <- data.frame(population=seq(from=10,to=600,by=10),mean=mean, median=median,max=max)

ggplot(data = df) + scale_shape_manual(name="Type", values=c(2,3,4)) +
geom_smooth(aes(x = population, y = mean)) +
geom_point(aes(x = population, y = mean, shape = "mean")) +
geom_smooth(aes(x = population, y = median)) +
geom_point(aes(x = population, y = median, shape = "median")) +
geom_smooth(aes(x = population, y = max)) +
geom_point(aes(x = population, y = max, shape = "max")) +
scale_y_continuous("queue size") +
scale_x_continuous("population")

13 changes: 13 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-6.r
@@ -0,0 +1,13 @@
library(ggplot2)

pdf("figure3-4.pdf")
data <- read.table("simulation1.csv", header=TRUE, sep=",")
df <- data.frame(table(data$X70))
colnames(df) <- c("queue_size", "frequency")
percent_labels <- paste(df$frequency, '(', round(df$frequency*100/540, 2), '%)')

ggplot(data=df) + opts(legend.position = "none") + scale_fill_grey(start = 0.6, end = 0.8) +
geom_bar(aes(x = queue_size, y = frequency, fill = factor(queue_size))) +
geom_text(aes(x = queue_size, y = frequency, label = percent_labels, size=1)) +
scale_y_continuous("frequency") +
scale_x_discrete("queue size")
53 changes: 53 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-7.rb
@@ -0,0 +1,53 @@
require 'csv'
require './restroom'

# Simulation script 2

frequency = 3 # how many times a person goes to the restroom with the period
use_duration = 1
population_size = 1000 # using a population range of 1000 people
facilities_per_restroom_range = 1..30
data = {}
facilities_per_restroom_range.each do |facilities_per_restroom|
Person.population.clear
population_size.times { Person.population << Person.new(frequency, use_duration) } # create the population
data[facilities_per_restroom] = [] #initialize the temp data store
restroom = Restroom.new facilities_per_restroom # create the restroom

# iterate over a period
DURATION.times do |t|
queue = restroom.queue.clone # clone the queue so that we don't mess up the live one
restroom.queue.clear # clear the queue
data[facilities_per_restroom] << queue.size # we want the queue size

# let everyone from the queue enter the restroom first
until queue.empty?
restroom.enter queue.shift # de-queue the first person in line and move him to the restroom
end

# for each person in the population check if he needs to go
Person.population.each do |person|
if person.need_to_go?
restroom.enter person
end
end
restroom.tick
end
end

# write the temp store into CSV
CSV.open('simulation2.csv', 'w') do |csv|
# setup labels
lbl = []
facilities_per_restroom_range.each {|facilities_per_restroom| lbl << facilities_per_restroom }
csv << lbl

# write the data
DURATION.times do |t|
row = []
facilities_per_restroom_range.each do |facilities_per_restroom|
row << data[facilities_per_restroom][t]
end
csv << row
end
end
20 changes: 20 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-8.r
@@ -0,0 +1,20 @@
library(ggplot2)

pdf("figure3-5.pdf")
data <- read.table("simulation2.csv", header = TRUE, sep = ",")
mean <- mean(data)
median <- apply(data, 2, median)
max <- apply(data, 2, max)
df <- data.frame(population = seq(from = 1, to = 30), mean = mean, median = median, max = max)

ggplot(data = df) + scale_shape_manual(name = "Type", values=c(2,3,4)) +
geom_smooth(aes(x = population, y = mean)) +
geom_point(aes(x = population, y = mean, shape = "mean")) +
geom_smooth(aes(x = population, y = median)) +
geom_point(aes(x = population, y = median, shape = "median")) +
geom_smooth(aes(x = population, y = max)) +
geom_point(aes(x = population, y = max, shape = "max")) +
scale_y_continuous("queue size") +
scale_x_continuous("number of facilities in a restroom")

print(df)
16 changes: 16 additions & 0 deletions Chapter 3 - Offices and Restrooms/example3-9.r
@@ -0,0 +1,16 @@
library(ggplot2)

pdf("figure3-6.pdf")

data <- read.table("simulation2.csv", header=TRUE, sep=",")
df <- data.frame(table(data$X19))
colnames(df) <- c("queue_size", "frequency")
percent_labels <- paste(df$frequency, '(', round(df$frequency*100/540, 2), '%)')

ggplot(data=df) + opts(legend.position = "none") + scale_fill_grey(start = 0.6, end = 0.8) +
geom_bar(aes(x = queue_size, y = frequency, fill = factor(queue_size))) +
geom_text(aes(x = queue_size, y = frequency, label = percent_labels, size=1)) +
scale_y_continuous("frequency") +
scale_x_discrete("queue size")

print(df)
1 change: 1 addition & 0 deletions Chapter 3 - Offices and Restrooms/restroom.rb
Expand Up @@ -18,6 +18,7 @@ def enter(person)
unoccupied_facility.occupy person
else
@queue << person
Person.population.delete person

This comment has been minimized.

Copy link
@TanMiningWithPyR

TanMiningWithPyR Jul 14, 2016

If person is pushed in list of queue, we need delete it in list of Person.population, That is right.
But next one minute, when we call the function restroom.enter for the person in the list of queue , we can't delete it from the list of Person.population again.

Here is the code of Facility.occupy:

def occupy(person) unless occupied? # if this facility is occupied return false @occupier = person # this facility is occupied! @duration = 1 # this facility has been occupied for 1 tick Person.population.delete person # remove the person from the population since he's in the queue now true else false end end

end
end

Expand Down

0 comments on commit b20dea3

Please sign in to comment.