Skip to content
Snippets Groups Projects
Commit 086ec747 authored by pjs's avatar pjs
Browse files

Array-based priority queue

parent 16779950
No related branches found
No related tags found
No related merge requests found
# dis is a PriorityQueue
class PriorityQueue
def initialize
clear
end
def <<(element)
@elements << element
# bubble up the element that we just added
bubble_up(@elements.size - 1)
end
alias push <<
def peek
# the first element will always be the min, because of the heap constraint
@elements[1]
end
def pop
# remove the last element of the list
min = @elements[1]
# and make sure the tree is ordered again
bubble_down(1)
min
end
def clear
@elements = [nil]
end
def empty?
@elements.length < 2
end
private
def bubble_up(index)
target = @elements[index]
loop do
parent_index = (index / 2)
# return if we reach the root or the parent is less than the child
if parent_index < 1 || @elements[parent_index] <= target
@elements[index] = target
return
end
# otherwise we exchange the child with the parent
@elements[index] = @elements[parent_index]
# and keep bubbling up
index = parent_index
end
end
def bubble_down(index)
target = @elements.pop
loop do
child_index = (index * 2)
# stop if we reach the bottom of the tree
if child_index > @elements.size - 1
@elements[index] = target
return
end
# make sure we get the smallest child
not_the_last_element = child_index < @elements.size - 1
left_element = @elements[child_index]
right_element = @elements[child_index + 1]
child_index += 1 if not_the_last_element && right_element < left_element
# there is no need to continue if the parent element is already smaller
# then its children
if target <= @elements[child_index]
@elements[index] = target
return
end
@elements[index] = @elements[child_index]
# repeat the process until we reach a point where the parent
# is larger than its children
index = child_index
end
end
end
require 'rubygems' if RUBY_VERSION =~ /^1\.8/ require_relative 'priority_queue'
require 'skewheap'
# The +SimpleKit+ module provides basic event scheduling capabilities. # The +SimpleKit+ module provides basic event scheduling capabilities.
# #
...@@ -10,7 +9,7 @@ require 'skewheap' ...@@ -10,7 +9,7 @@ require 'skewheap'
module SimpleKit module SimpleKit
# The set of module methods to be passed to the EventScheduler # The set of module methods to be passed to the EventScheduler
# if not found in the model class. # if not found in the model class.
DELEGATED_METHODS = [:model_time, :schedule, :halt] DELEGATED_METHODS = [:model_time, :schedule, :halt].freeze
# Run your model by creating a new +EventScheduler+ and invoking its # Run your model by creating a new +EventScheduler+ and invoking its
# +run+ method. # +run+ method.
...@@ -29,8 +28,8 @@ module SimpleKit ...@@ -29,8 +28,8 @@ module SimpleKit
end end
end end
# Class +EventScheduler+ provides the computation engine for a discrete # Class +EventScheduler+ provides the computation engine for a
# event simulation model. It uses the +SkewHeap+ RubyGem as a priority # discrete event simulation model. It uses an array-based priority
# queue implementation for the pending events list. # queue implementation for the pending events list.
# #
# Users must create a model class which: # Users must create a model class which:
...@@ -43,7 +42,7 @@ module SimpleKit ...@@ -43,7 +42,7 @@ module SimpleKit
# and setting up an empty event list. # and setting up an empty event list.
def initialize(the_model) def initialize(the_model)
@user_model = the_model @user_model = the_model
@event_list = SkewHeap.new @event_list = PriorityQueue.new
end end
# Add an event to the pending events list. # Add an event to the pending events list.
...@@ -80,8 +79,6 @@ module SimpleKit ...@@ -80,8 +79,6 @@ module SimpleKit
end end
end end
private
# This is a private helper Struct for the EventScheduler class. # This is a private helper Struct for the EventScheduler class.
# Users should never try to access this directly. # Users should never try to access this directly.
EventNotice = Struct.new(:event, :time, *:args) do EventNotice = Struct.new(:event, :time, *:args) do
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment