Version: 4.1.3
13 Simulation Control (Advanced)
13.1 Example – Harbor Model
| #lang scheme |
| ; Harbor Model |
| (require (planet williams/simulation/simulation-with-graphics)) |
| (require (planet williams/science/random-distributions)) |
| ; Data collection variables |
| (define cycle-time #f) |
| ; Model definition |
| (define random-sources (make-random-source-vector 2)) |
| (define dock #f) |
| (define queue #f) |
| (define (scheduler) |
| (let loop () |
| (make-object ship%) |
| (wait (random-exponential (vector-ref random-sources 0) (/ 4.0 3.0))) |
| (loop))) |
| (define-process-class ship% |
| (field (unloading-time (random-flat (vector-ref random-sources 1) 1.0 2.5))) |
| (let ((arrival-time (current-simulation-time))) |
| (when (not (harbor-master this 'arriving)) |
| (set-insert! queue this) |
| (suspend-process)) |
| (work unloading-time) |
| (set-remove! dock this) |
| (set-variable-value! |
| cycle-time (- (current-simulation-time) arrival-time)) |
| (harbor-master this 'leaving))) |
| (define ship-unloading-time |
| (class-field-accessor ship% unloading-time)) |
| (define set-ship-unloading-time! |
| (class-field-mutator ship% unloading-time)) |
| (define (harbor-master ship action) |
| (case action |
| ((arriving) |
| (if (< (set-n dock) 2) |
| ; Dock is not full |
| (begin |
| (if (set-empty? dock) |
| (set-ship-unloading-time! |
| ship (/ (ship-unloading-time ship) 2.0)) |
| (let ((other-ship (set-first dock))) |
| (send other-ship interrupt) |
| (send other-ship set-time (* (send other-ship get-time) 2.0)) |
| (send other-ship resume))) |
| (set-insert! dock ship) |
| #t) |
| ; Dock is full |
| #f)) |
| ((leaving) |
| (if (set-empty? queue) |
| (when (not (set-empty? dock)) |
| (let ((other-ship (set-first dock))) |
| (send other-ship interrupt) |
| (send other-ship set-time (/ (send other-ship get-time) 2.0)) |
| (send other-ship resume) |
| #t)) |
| (let ((next-ship (set-remove-first! queue))) |
| (set-insert! dock next-ship) |
| (send next-ship resume) |
| #t))) |
| (else |
| (error 'harbor-master "illegal action value ~a" action)))) |
| (define (stop-sim) |
| (printf "Harbor Model - report after ~a simulated days - ~a ships processed~n" |
| (current-simulation-time) (variable-n cycle-time)) |
| (printf "Minimum unload time was ~a~n" |
| (variable-minimum cycle-time)) |
| (printf "Maximum unload time was ~a~n" |
| (variable-maximum cycle-time)) |
| (printf "Average queue of ships waiting to be unloaded was ~a~n" |
| (variable-mean (set-variable-n queue))) |
| (printf "Maximum queue was ~a~n" |
| (variable-maximum (set-variable-n queue))) |
| (write-special (history-plot (variable-history (set-variable-n queue)) |
| "History of Waiting Queue")) |
| (newline) |
| (stop-simulation)) |
| (define (run-simulation) |
| (with-new-simulation-environment |
| (set! cycle-time (make-variable)) |
| (tally (variable-statistics cycle-time)) |
| (set! dock (make-set)) |
| (set! queue (make-set)) |
| (accumulate (variable-history (set-variable-n queue))) |
| (schedule now (scheduler)) |
| (schedule (at 80.0) (stop-sim)) |
| (start-simulation))) |
| (run-simulation) |
The following is the output from the model.
| Harbor Model - report after 80.0 simulated days - 65 ships processed |
| Minimum unload time was 0.5656279138989291 |
| Maximum unload time was 3.893379568241123 |
| Average queue of ships waiting to be unloaded was 0.24532233055969996 |
| Maximum queue was 3 |
