F
Farrel Lifson
I've just released Precedence 0.8. This is a combined release with 0.7
(last release was 0.6). This is not backward compatiable with 0.6 so
if you're using it you might have to do some refactoring. Here's the
README and CHANGELOG.
---------------------------------------------------------------------------=
----------------------------------------------------
=3D Precedence
Precedence is a library that allows for the creation, manipulation and anal=
ysis
of precedence networks.
=3D=3D Download and Install
Available as a RubyGem from Rubyforge. To install
$ gem install precedence
will fetch the latest gem from Rubyforge and install it.
Source can also be downloaded from http://rubyforge.org/projects/precedenc=
e.
=3D=3D Example Usage
require('precedence')
=20
# Set up network
net =3D Precedence::Network.new
net.new_activity('act-1-1') do |act|
=09act.expected_duration =3D 3
=09act.description =3D 'System specification'
end
net.new_activity('act-1-2' do |act|
=09act.expected_duration =3D 2
=09act.description =3D 'Review'
end
net.new_activity('act-1-3') do |act|
=09act.expected_duration =3D 2
=09act.description =3D 'System re-specification'
end
net.new_activity('act-2-1') do |act|
=09act.expected_duration =3D 3
=09act.description =3D 'Test tool design'
end
net.new_activity('act-2-2') do |act|=20
=09act.expected_duration =3D 5
=09act.description =3D 'Test tool implementation'
end
net.new_activity('act-3-1')
=09act.expected_duration =3D 3
=09act.description =3D 'System design'
end
net.new_activity('act-3-2') do |act|
=09act.expected_duration =3D 12
=09act.description =3D 'System implementation'
end
net.new_activity('act-2-3') do |act|=20
=09act.expected_duration =3D 10
=09act.description =3D 'System testing'
end
net.connect('act-1-1','act-1-2')
net.connect('act-1-2','act-1-3')
net.connect('act-1-3','act-3-1')
net.connect('act-1-2','act-2-1')
net.connect('act-2-1','act-2-2')
net.connect('act-2-2','act-3-2')
net.connect('act-3-1','act-3-2')
net.connect('act-3-2','act-2-3')
net.fix_connections!
=20
# Generate a diagram
File.open('network.dot',File::CREAT|File::TRUNC|File::WRONLY) do |file|
=09file.puts(net.to_dot)
end
system("dot","-Tpng","-onetwork.png","network.dot")
=20
# Perform some analysis of the activities
activity =3D net.activities['act-1-2']
activity.on_critical_path? # =3D> true=20
activity.earliest_start # =3D> 3.0
activity.latest_finish # =3D> 5.0
activity.total_float # =3D> 0 - activities on the critical path have no f=
loat
=20
# Save the network to a YAML file
File.open('network.yaml',File::CREAT|File::TRUNC|File::WRONLY do |file|
=09file.puts(net.to_yaml)
end
=20
# Read the network from a YAML file
newNet =3D Precedence::Network.from_yaml(File.new('network.yaml',File::RDO=
NLY))
=20
=3D=3D Documentation
The Precedence API online documentation is available at=20
http://precedence.rubyforge.org.=20
Refer to the CHANGELOG and TODO files for past changes and upcoming plans.
=3D=3D Credits
Farrel Lifson <[email protected]>
=3D=3D License
This software is made available under the BSD license.
=3D ChangeLog
=3D 0.8
* Added multiple durations. An activity has the following durations associa=
ted
activity =3D Precedence::Activity.new('activity1') do |act|
act.expected_duration =3D 2 # This is what would've been act.duration
act.minimum_duration =3D 1 # The minimum time the activity could need
act.maximum_duration =3D 4 # The maximum time the activity should need
end
From this the following may be determined:
activity.mean_duration
activity.standard_deviation
activity.variance
A Beta distribution is assumed to be used for the probability density fun=
ction
and if certain assumptions are made the following hold
- The mean_duration is calculated as:=20
(4*expected_duration + minimum_duration + maximum_duration)/6
- The standard deviations is:=20
(maximum_duration - minimum_duration)/6
- The variance is the standard deviation squared.
The activity.duration attribute is still present and it is configurable t=
o=20
allow the differing duration types. The duration to be used is set using =
the
Activity.duration_type attribute. For instance assuming we have the follo=
wing=20
two activities set up:
act1 =3D Precedence::Activity.new('a1') do |activity|
activity.expected_duration =3D 2
activity.minimum_duration =3D 1
activity.maximum_duration =3D 3
end
act2 =3D Precedence::Activity.new('a2') do |activity|
activity.expected_duration =3D 3
activity.minimum_duration =3D 1
activity.maximum_duration =3D 5
end
act1.add_post_activities(act2)
# Duration type is initially set to the expected duration
act2.earliest_finish # =3D> 5
# Change duration type to the maximum duration
act2.duration_type =3D Activity::MAXIMUM_DURATION
act2.earliest_finish # =3D> 7
The allowed duration types are : EXPECTED_DURATION, MEAN_DURATION,=20
MINIMUM_DURATION and MAXIMUM_DURATION
* Moved the ActivityHash and ResourceHash into the Precedence::Utilities mo=
dule.
* Added Activity.active_at?(time) which returns true if the activity
is active at
time.
* Added Network.activities_at_time(time) which returns an array of activiti=
es=20
active at that time.
=20
* Added Activity.active_during?(range) which returns true if the
activity is active
during the time range given.
* Added Network.activities_during_time(range) which returns an array
of activities
active during the range given.
* Added Network.each_time_period(tick,&block) which iterates over the durat=
ion
of the project in time steps of the tick parameter, yielding an array of
activities active at each time to the block.
=20
* Removed the StartActivity and FinishActivity of the network from the=20
Network.activities hash. They are still avaialable in the hash if needed
precNetwork.activities['start']
precNetwork.activities['finish']=20
will return the StartActivity/FinishActivity however
precNetwork.activities.each
will not include them. I am still thinking of a way to get rid of
them altogether.
=20
* Added Network.reference_exists? which will return true if the
reference is in the network.
=3D 0.7
* Added ability to load from and save networks to YAML files.
* Split StartFinishActivity into seperate StartActivity and FinishActivity=
=20
classes.
* Added StartActivity::REFERENCE and Network::START as well as=20
FinishActivity::REFERENCE and Network::FINISH as constants to hold the=20
reserved references for the start and finish activities in a network.
* Totally changed the way activities are created in both the Activity and
Network classes. =20
Activity.new(reference,duration,description,post_activities,pre_activiti=
es)
is now
Activity.new(reference) do |activity|
activity.duration =3D duration
activity.description =3D description
activity.add_post_activities(post_activities)
activity.add_pre_activities(pre_activities)
end =20
The same applies to the Network.new_activity method
Network.new_activity(reference,duration,description,post_activities,pre_=
activities)
has become
network.new_activity(reference) do |activity|
activity.duration =3D duration
activity.description =3D description
activity.add_pre_activities(pre_activities)
end
network.connect(reference,post_activities)
pre_activities.each do |pre_act_ref|
network.connect(pre_act_ref,reference)
end
In fact the block from his method is passed directly to the Activity.new=
=20
method. While you could use add_post_activities and add_pre_activities in=
this
block it is better to use Network.connect when dealing with the Network c=
lass.
* Added resources to activities. They can be set via the activity.resources=
hash
(last release was 0.6). This is not backward compatiable with 0.6 so
if you're using it you might have to do some refactoring. Here's the
README and CHANGELOG.
---------------------------------------------------------------------------=
----------------------------------------------------
=3D Precedence
Precedence is a library that allows for the creation, manipulation and anal=
ysis
of precedence networks.
=3D=3D Download and Install
Available as a RubyGem from Rubyforge. To install
$ gem install precedence
will fetch the latest gem from Rubyforge and install it.
Source can also be downloaded from http://rubyforge.org/projects/precedenc=
e.
=3D=3D Example Usage
require('precedence')
=20
# Set up network
net =3D Precedence::Network.new
net.new_activity('act-1-1') do |act|
=09act.expected_duration =3D 3
=09act.description =3D 'System specification'
end
net.new_activity('act-1-2' do |act|
=09act.expected_duration =3D 2
=09act.description =3D 'Review'
end
net.new_activity('act-1-3') do |act|
=09act.expected_duration =3D 2
=09act.description =3D 'System re-specification'
end
net.new_activity('act-2-1') do |act|
=09act.expected_duration =3D 3
=09act.description =3D 'Test tool design'
end
net.new_activity('act-2-2') do |act|=20
=09act.expected_duration =3D 5
=09act.description =3D 'Test tool implementation'
end
net.new_activity('act-3-1')
=09act.expected_duration =3D 3
=09act.description =3D 'System design'
end
net.new_activity('act-3-2') do |act|
=09act.expected_duration =3D 12
=09act.description =3D 'System implementation'
end
net.new_activity('act-2-3') do |act|=20
=09act.expected_duration =3D 10
=09act.description =3D 'System testing'
end
net.connect('act-1-1','act-1-2')
net.connect('act-1-2','act-1-3')
net.connect('act-1-3','act-3-1')
net.connect('act-1-2','act-2-1')
net.connect('act-2-1','act-2-2')
net.connect('act-2-2','act-3-2')
net.connect('act-3-1','act-3-2')
net.connect('act-3-2','act-2-3')
net.fix_connections!
=20
# Generate a diagram
File.open('network.dot',File::CREAT|File::TRUNC|File::WRONLY) do |file|
=09file.puts(net.to_dot)
end
system("dot","-Tpng","-onetwork.png","network.dot")
=20
# Perform some analysis of the activities
activity =3D net.activities['act-1-2']
activity.on_critical_path? # =3D> true=20
activity.earliest_start # =3D> 3.0
activity.latest_finish # =3D> 5.0
activity.total_float # =3D> 0 - activities on the critical path have no f=
loat
=20
# Save the network to a YAML file
File.open('network.yaml',File::CREAT|File::TRUNC|File::WRONLY do |file|
=09file.puts(net.to_yaml)
end
=20
# Read the network from a YAML file
newNet =3D Precedence::Network.from_yaml(File.new('network.yaml',File::RDO=
NLY))
=20
=3D=3D Documentation
The Precedence API online documentation is available at=20
http://precedence.rubyforge.org.=20
Refer to the CHANGELOG and TODO files for past changes and upcoming plans.
=3D=3D Credits
Farrel Lifson <[email protected]>
=3D=3D License
This software is made available under the BSD license.
=3D ChangeLog
=3D 0.8
* Added multiple durations. An activity has the following durations associa=
ted
activity =3D Precedence::Activity.new('activity1') do |act|
act.expected_duration =3D 2 # This is what would've been act.duration
act.minimum_duration =3D 1 # The minimum time the activity could need
act.maximum_duration =3D 4 # The maximum time the activity should need
end
From this the following may be determined:
activity.mean_duration
activity.standard_deviation
activity.variance
A Beta distribution is assumed to be used for the probability density fun=
ction
and if certain assumptions are made the following hold
- The mean_duration is calculated as:=20
(4*expected_duration + minimum_duration + maximum_duration)/6
- The standard deviations is:=20
(maximum_duration - minimum_duration)/6
- The variance is the standard deviation squared.
The activity.duration attribute is still present and it is configurable t=
o=20
allow the differing duration types. The duration to be used is set using =
the
Activity.duration_type attribute. For instance assuming we have the follo=
wing=20
two activities set up:
act1 =3D Precedence::Activity.new('a1') do |activity|
activity.expected_duration =3D 2
activity.minimum_duration =3D 1
activity.maximum_duration =3D 3
end
act2 =3D Precedence::Activity.new('a2') do |activity|
activity.expected_duration =3D 3
activity.minimum_duration =3D 1
activity.maximum_duration =3D 5
end
act1.add_post_activities(act2)
# Duration type is initially set to the expected duration
act2.earliest_finish # =3D> 5
# Change duration type to the maximum duration
act2.duration_type =3D Activity::MAXIMUM_DURATION
act2.earliest_finish # =3D> 7
The allowed duration types are : EXPECTED_DURATION, MEAN_DURATION,=20
MINIMUM_DURATION and MAXIMUM_DURATION
* Moved the ActivityHash and ResourceHash into the Precedence::Utilities mo=
dule.
* Added Activity.active_at?(time) which returns true if the activity
is active at
time.
* Added Network.activities_at_time(time) which returns an array of activiti=
es=20
active at that time.
=20
* Added Activity.active_during?(range) which returns true if the
activity is active
during the time range given.
* Added Network.activities_during_time(range) which returns an array
of activities
active during the range given.
* Added Network.each_time_period(tick,&block) which iterates over the durat=
ion
of the project in time steps of the tick parameter, yielding an array of
activities active at each time to the block.
=20
* Removed the StartActivity and FinishActivity of the network from the=20
Network.activities hash. They are still avaialable in the hash if needed
precNetwork.activities['start']
precNetwork.activities['finish']=20
will return the StartActivity/FinishActivity however
precNetwork.activities.each
will not include them. I am still thinking of a way to get rid of
them altogether.
=20
* Added Network.reference_exists? which will return true if the
reference is in the network.
=3D 0.7
* Added ability to load from and save networks to YAML files.
* Split StartFinishActivity into seperate StartActivity and FinishActivity=
=20
classes.
* Added StartActivity::REFERENCE and Network::START as well as=20
FinishActivity::REFERENCE and Network::FINISH as constants to hold the=20
reserved references for the start and finish activities in a network.
* Totally changed the way activities are created in both the Activity and
Network classes. =20
Activity.new(reference,duration,description,post_activities,pre_activiti=
es)
is now
Activity.new(reference) do |activity|
activity.duration =3D duration
activity.description =3D description
activity.add_post_activities(post_activities)
activity.add_pre_activities(pre_activities)
end =20
The same applies to the Network.new_activity method
Network.new_activity(reference,duration,description,post_activities,pre_=
activities)
has become
network.new_activity(reference) do |activity|
activity.duration =3D duration
activity.description =3D description
activity.add_pre_activities(pre_activities)
end
network.connect(reference,post_activities)
pre_activities.each do |pre_act_ref|
network.connect(pre_act_ref,reference)
end
In fact the block from his method is passed directly to the Activity.new=
=20
method. While you could use add_post_activities and add_pre_activities in=
this
block it is better to use Network.connect when dealing with the Network c=
lass.
* Added resources to activities. They can be set via the activity.resources=
hash