Class: Precedence::Network
- Inherits:
-
Object
- Object
- Precedence::Network
- Defined in:
- lib/precedence/network.rb
Overview
Represents an entire precedence network. It wraps around an underlying directed graph of Activity objects and adds a number of utility methods and extra functionality that would not be available if one just used Activity objects.
Constant Summary collapse
- START =
The reference for the StartActivity in the network.
Precedence::StartActivity::REFERENCE
- FINISH =
The reference for the FinishActivity in the network.
Precedence::FinishActivity::REFERENCE
Instance Attribute Summary collapse
-
#activities ⇒ Object
readonly
A hashed collection of all the activities in the network.
Class Method Summary collapse
-
.from_yaml(yaml) ⇒ Object
Returns a Precedence::Network object that is represented by the YAML document.
-
.get_rdot_template ⇒ Object
Returns the rdot (Ruby embedded in a dot file) template that is used by default when generating the precedence network diagrams.
Instance Method Summary collapse
-
#activities_at_time(time) ⇒ Object
Returns an array of activities with each activity being active at the time of the parameter.
-
#activities_during_time(range) ⇒ Object
Returns an array of activities with each acitivity being active deuring the time range of the parameter.
-
#add_activity(activity) ⇒ Object
Adds a Precedence::Activity object to the network.
-
#connect(pre_ref, *post_refs) ⇒ Object
Connects two or more activities together.
-
#disconnect(pre_ref, *post_refs) ⇒ Object
Disconnects an activity from one or more post activities.
-
#each_time_period(tick = 1) ⇒ Object
Iterates over the networks duration yielding an array of activities that are active at that time to a block.
-
#each_time_period_with_index(tick = 1) ⇒ Object
The same functionality as each_time_period except that the time is yielded along with the array of active activities.
-
#finish ⇒ Object
The time it will take to finish all activities in the network.
-
#fix_connections! ⇒ Object
Ensures that the network is properly connected by connecting any activity without pre-activities to the start node and to the finish node if it has no post-activities.
-
#initialize ⇒ Network
constructor
Initialises the precedence network.
-
#new_activity(reference, &block) ⇒ Object
Creates a new activity and adds it to the precedence network.
-
#reference_exists?(reference) ⇒ Boolean
Returns true if the reference is currently in the network.
-
#to_dot(template = nil) ⇒ Object
Returns a dot file capable of being rendered by the Dot graph renderer available from GraphViz (www.graphviz.org).
-
#to_yaml ⇒ Object
Returns a YAML representation of the network.For more information on YAML go to yaml.org.
Constructor Details
#initialize ⇒ Network
Initialises the precedence network. The descriptions for the start and finish activities can be set in the parameters. The start and finish activities of the network have as references ‘start’ and ‘finish’ (held in constants Network::START and Network::FINISH) respectively (and as such these references are reserved) and a duration of 0.
Example usage:
precNetwork = Precedence::Network.new('Begin','End')
will create a new precedence network with the start and finish activities having descriptions of ‘Begin’ and ‘End’ respectively.
34 35 36 37 38 39 40 |
# File 'lib/precedence/network.rb', line 34 def initialize() @start = Precedence::StartActivity.new @finish = Precedence::FinishActivity.new @activities = Precedence::Utilities::ActivityHash.new(@start,@finish) #@activities[START] = @start #@activities[FINISH] = @finish end |
Instance Attribute Details
#activities ⇒ Object (readonly)
A hashed collection of all the activities in the network. The index is the reference of the activity.
15 16 17 |
# File 'lib/precedence/network.rb', line 15 def activities @activities end |
Class Method Details
.from_yaml(yaml) ⇒ Object
Returns a Precedence::Network object that is represented by the YAML document.
Example usage:
precNetwork = nil
File.open('precnetwork.yaml',File::RDONLY) do |f|
precNetwork = Precedence::Network.from_yaml(f)
end
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/precedence/network.rb', line 204 def self.from_yaml(yaml) activities = {} connections = {} YAML::load_documents(yaml) do |doc| activity = Precedence::Activity.from_yaml_object(doc) activities[activity.reference] = activity connections[activity.reference] = doc[activity.reference]['post activities'] end network = Precedence::Network.new() activities.values.each do |activity| unless ((activity.reference == START) or (activity.reference == FINISH)) network.add_activity(activity) end end connections.each do |ref,connections| connections.to_a.each do |post_ref| network.connect(ref,post_ref) end end return network end |
.get_rdot_template ⇒ Object
Returns the rdot (Ruby embedded in a dot file) template that is used by default when generating the precedence network diagrams.
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/precedence/network.rb', line 293 def self.get_rdot_template #:nodoc: return <<END_OF_STRING /* Generated by Precedence on <%= Time.now.to_s %> */ digraph network { rankdir=LR; node [shape=record]; /* Activities */ <% @activities.each do |ref,activity| %> <% case ref when START%> "<%= ref %>" [label="<%= activity.description %>"]; <% when FINISH %> "<%= ref %>" [label="{<%= activity.description%>|<%= activity.earliest_finish %>}"]; <% else %> "<%= ref %>" [label="<%=ref%>|{{<%=activity.earliest_start%>|<%=activity.latest_start%>}|{<%=activity.description%>|{<%=activity.total_float%>|<%=activity.early_float%>}}|{<%=activity.earliest_finish%>|<%=activity.latest_finish%>}}|<%=activity.duration%>"]; <% end %> <% end %> /* Dependencies */ <% @activities.each do |ref,activity|%> <% activity.post_activities.each do |post_activity| %> "<%= activity.reference %>" -> "<%= post_activity.reference %>" <% if (activity.on_critical_path? and post_activity.on_critical_path?)%>[style=bold]<% end %>; <% end %> <% end %> } END_OF_STRING end |
Instance Method Details
#activities_at_time(time) ⇒ Object
Returns an array of activities with each activity being active at the time of the parameter.
276 277 278 279 280 |
# File 'lib/precedence/network.rb', line 276 def activities_at_time(time) return (@activities.values.find_all do |activity| activity.active_on?(time) end) end |
#activities_during_time(range) ⇒ Object
Returns an array of activities with each acitivity being active deuring the time range of the parameter
284 285 286 287 288 |
# File 'lib/precedence/network.rb', line 284 def activities_during_time(range) return (@activities.values.find_all do |activity| activity.active_during?(range) end) end |
#add_activity(activity) ⇒ Object
Adds a Precedence::Activity object to the network. This should be a single activity (no pre- or post-activities should be referenced from it) and it’s reference should not exist in the network.
Example usage:
activity = Precedence::Activity.new('a1',1,'Activity 1')
precNetwork.add_activity(activity)
will add the existing activity ‘a1’ to the network.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/precedence/network.rb', line 68 def add_activity(activity) if (reference_exists?(activity.reference)) raise "Activity #{activity.reference} already exists in the "+ "network." end unless (activity.post_activities == []) raise "Can not add an activity with post activities." end unless (activity.pre_activities == []) raise "Can not add an activity with pre activities." end @activities[activity.reference] = activity end |
#connect(pre_ref, *post_refs) ⇒ Object
Connects two or more activities together. The pre_ref activity will become a pre-activity to all the activities referenced in the post_refs parameter.
Example uysage:
precNetwork.connect(:h1,:h2,:h3)
will add activity ‘h1’ as a pre-activity to activities ‘h2’ and ‘h3’.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/precedence/network.rb', line 92 def connect(pre_ref,*post_refs) unless reference_exists?(pre_ref) raise "Pre-activity with reference #{pre_ref} "+ "was not found." end post_refs.each do |post_ref| unless reference_exists?(post_ref) raise "Post-activity with reference #{post_ref} "+ "was not found." end end post_refs.each do |post_ref| activities[pre_ref].add_post_activities(activities[post_ref]) end end |
#disconnect(pre_ref, *post_refs) ⇒ Object
Disconnects an activity from one or more post activities.
Example usage:
precNetwork.disconnect(:h1,:h2,:h3)
will remove activity ‘h1’ as a pre-activity to activities ‘h2’ and ‘h3’.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/precedence/network.rb', line 116 def disconnect(pre_ref,*post_refs) unless reference_exists?(pre_ref) raise "Pre-activity with reference #{pre_ref} "+ "was not found." end post_refs.each do |post_ref| unless reference_exists?(post_ref) raise "Post-activity with reference #{post_ref} "+ "was not found." end end post_refs.each do |post_ref| activities[pre_ref].remove_post_activities(activities[post_ref]) end end |
#each_time_period(tick = 1) ⇒ Object
Iterates over the networks duration yielding an array of activities that are active at that time to a block. The size of the time jumps can be set using the tick parameter. The duration starts at time 0 and ends at time network.finish - tick.
Example usage:
precNetwork.each_time_period do |activities|
coffeeUsed == 0
activities.each do |activity|
coffeeUsed += activity.resources['coffee']
end
puts "Used #{coffeeUsed} units of coffee in #{activities.size} activities."
end
255 256 257 258 259 |
# File 'lib/precedence/network.rb', line 255 def each_time_period(tick=1) 0.step(finish-tick,tick) do |current_time| yield(activities_at_time(current_time)) end end |
#each_time_period_with_index(tick = 1) ⇒ Object
The same functionality as each_time_period except that the time is yielded along with the array of active activities.
Example usage:
precNetwork.each_time_period_with_index do |activities,time|
puts "At time #{time}, #{activities.size} activities were active."
end
268 269 270 271 272 |
# File 'lib/precedence/network.rb', line 268 def each_time_period_with_index(tick=1) 0.step(finish-tick,tick) do |current_time| yield(activities_at_time(current_time),current_time) end end |
#finish ⇒ Object
The time it will take to finish all activities in the network. (Shortcut to precNetwork.activities.finish)
Example usage:
precNetwork.finish
238 239 240 |
# File 'lib/precedence/network.rb', line 238 def finish return @finish.finish end |
#fix_connections! ⇒ Object
Ensures that the network is properly connected by connecting any activity without pre-activities to the start node and to the finish node if it has no post-activities. Must be called before any analysis on the network is done.
Example usage:
precNetwork.connect('h1','h2')
precNetwork.connect('h2','h3','h4)
precNetwork.fix_connections!
precNetwork.finish
precNetwork.activities['h2'].earliest_finish
156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/precedence/network.rb', line 156 def fix_connections! activities.each do |ref,activity| if activity.pre_activities.size == 0 connect(START,ref) end if activity.post_activities.size == 0 connect(ref,FINISH) end end end |
#new_activity(reference, &block) ⇒ Object
Creates a new activity and adds it to the precedence network. The reference is the only mandatory parameter. This method will take the block given and pass it to the Activity.new method.
Exapmple usage:
precNetwork.new_activity('a2') do |activity|
activity.duration = 3
activity.description = 'Activity2'
end
precNetwork.connect('a2','a1')
will create a new activity in the network with referecne ‘a2’ and with activity ‘a1’ as a post-activity.
55 56 57 58 |
# File 'lib/precedence/network.rb', line 55 def new_activity(reference,&block) activity = Precedence::Activity.new(reference,&block) activities[reference]=activity end |
#reference_exists?(reference) ⇒ Boolean
Returns true if the reference is currently in the network. This includes START and FINISH.
136 137 138 139 140 141 142 143 |
# File 'lib/precedence/network.rb', line 136 def reference_exists?(reference) if ((!activities[reference].nil?) || (reference == START) || (reference == FINISH)) return true end return false end |
#to_dot(template = nil) ⇒ Object
Returns a dot file capable of being rendered by the Dot graph renderer available from GraphViz (www.graphviz.org).
Example usage:
File.open('test_to_dot.dot',File::CREAT|File::TRUNC|File::WRONLY) do|f|
f.puts(net.to_dot)
end
175 176 177 178 179 180 |
# File 'lib/precedence/network.rb', line 175 def to_dot(template=nil) unless template template = Precedence::Network.get_rdot_template end return ERB.new(template).result(binding) end |
#to_yaml ⇒ Object
Returns a YAML representation of the network.For more information on YAML go to yaml.org
Example usage:
File.open('test_to_yaml.yaml',File::CREAT|File::TRUNC|File::WRONLY) do|f|
f.puts(net.to_yaml)
end
189 190 191 192 193 |
# File 'lib/precedence/network.rb', line 189 def to_yaml (activities.values.collect do |activity| activity.to_yaml end).join("\n") end |