{-# LANGUAGE RecursiveDo #-} -- Example: Analysis of a PERT-type Network -- -- It is described in different sources [1, 2]. So, this is chapter 14 of [2] and section 7.11 of [1]. -- -- PERT is a technique for evaluating and reviewing a project consisting of -- interdependent activities. A number of books have been written that describe -- PERT modeling and analysis procedures. A PERT network activity descriptions -- are given in a table stated below. All activity times will be assumed to be -- triangularly distributed. For ease of description, activities have been -- aggregated. The activities relate to power units, instrumentation, and -- a new assembly and involve standard types of operations. -- -- In the following description of the project, activity numbers are given -- in parentheses. At the beginning of the project, three parallel activities -- can be performed that involve: the disassembly of power units and -- instrumentation (1); the installation of a new assembly (2); and -- the preparation for a retrofit check (3). Cleaning, inspecting, and -- repairing the power units (4) and calibrating the instrumentation (5) -- can be done only after the power units and instrumentation have been -- disassembled. Thus, activities 4 and 5 must follow activity 1 in the network. -- Following the installation of the new assembly (2) and after the instrumentation -- have been calibrated (5), a check of interfaces (6) and a check of -- the new assembly (7) can be made. The retrofit check (9) can be made -- after the assembly is checked (7) and the preparation for the retrofit -- check (3) has been completed. The assembly and test of power units (8) -- can be performed following the cleaning and maintenance of power units (4). -- The project is considered completed when all nine activities are completed. -- Since activities 6, 8, and 9 require the other activities to precede them, -- their completion signifies the end of the project. This is indicated on -- the network by having activities 6, 8, and 9 incident to node 6, the sink -- node for the project. The objective of this example is to illustrate -- the procedures for using Aivika to model and simulate project planning network. -- -- Activity Description Mode Minimum Maximum Average -- -- 1 Disassemble power units and instrumentation 3 1 5 3 -- 2 Install new assembly 6 3 9 6 -- 3 Prepare for retrofit check 13 10 19 14 -- 4 Clean, inspect, and repair power units 9 3 12 8 -- 5 Calibrate instrumentation 3 1 8 4 -- 6 Check interfaces 9 8 16 11 -- 7 Check assembly 7 4 13 8 -- 8 Assemble and test power units 6 3 9 6 -- 9 Retrofit check 3 1 8 4 -- -- Node Depends of Activities -- -- 1 - -- 2 1 -- 3 2, 5 -- 4 3, 7 -- 5 4 -- 6 6, 8, 9 -- -- Activity Depends on Node -- -- 1 1 -- 2 1 -- 3 1 -- 4 2 -- 5 2 -- 6 3 -- 7 3 -- 8 5 -- 9 4 -- -- [1] A. Alan B. Pritsker, Simulation with Visual SLAM and AweSim, 2nd ed. -- [2] Труб И.И., Объектно-ориентированное моделирование на C++: Учебный курс. - СПб.: Питер, 2006 import Control.Monad import Control.Monad.Trans import Control.Arrow import Data.Array import Data.Maybe import Data.Monoid import Simulation.Aivika.Trans import Simulation.Aivika.IO type DES = IO -- | The simulation specs. specs = Specs { spcStartTime = 0.0, spcStopTime = 1000.0, spcDT = 0.1, spcMethod = RungeKutta4, spcGeneratorType = SimpleGenerator } model :: Simulation DES (Results DES) model = mdo timers' <- forM [2..5] $ \i -> newArrivalTimer projCompletionTimer <- newArrivalTimer let timers = array (2, 5) $ zip [2..] timers' p1 = randomTriangularProcessor 1 3 5 p2 = randomTriangularProcessor 3 6 9 p3 = randomTriangularProcessor 10 13 19 p4 = randomTriangularProcessor 3 9 12 p5 = randomTriangularProcessor 1 3 8 p6 = randomTriangularProcessor 8 9 16 p7 = randomTriangularProcessor 4 7 13 p8 = randomTriangularProcessor 3 6 9 p9 = randomTriangularProcessor 1 3 8 let c2 = arrivalTimerProcessor (timers ! 2) c3 = arrivalTimerProcessor (timers ! 3) c4 = arrivalTimerProcessor (timers ! 4) c5 = arrivalTimerProcessor (timers ! 5) c6 = arrivalTimerProcessor projCompletionTimer [i1, i2, i3] <- cloneStream 3 n1 [i4, i5] <- cloneStream 2 n2 [i6, i7] <- cloneStream 2 n3 let i9 = n4 i8 = n5 let s1 = runProcessor p1 i1 s2 = runProcessor p2 i2 s3 = runProcessor p3 i3 s4 = runProcessor p4 i4 s5 = runProcessor p5 i5 s6 = runProcessor p6 i6 s7 = runProcessor p7 i7 s8 = runProcessor p8 i8 s9 = runProcessor p9 i9 let n1 = takeStream 1 $ randomStream $ return (0, 0) n2 = runProcessor c2 s1 n3 = runProcessor c3 $ firstArrivalStream 2 (s2 <> s5) n4 = runProcessor c4 $ firstArrivalStream 2 (s3 <> s7) n5 = runProcessor c5 s4 n6 = runProcessor c6 $ firstArrivalStream 3 (s6 <> s8 <> s9) runProcessInStartTime $ sinkStream n6 return $ results [resultSource "timers" "Timers" timers, -- resultSource "projCompletion" "Project Completion Timer" projCompletionTimer] modelSummary :: Simulation DES (Results DES) modelSummary = fmap resultSummary model main = printSimulationResultsInStopTime printResultSourceInEnglish -- model specs modelSummary specs