Arena Model Instructions - "Dishwasher Manufacturing" (Ready-to-implement)
--------------------------------------------------------------------------
Filename suggestion: Arena_Model_Instructions.txt
Purpose: Step-by-step Arena module-by-module blueprint. Copy each module into
Arena's GUI and set fields exactly as specified.
GENERAL MODEL SETTINGS
----------------------
- Time units: Minutes
- Run Length: 480 (minutes) --> Model > Run Setup: Length of Simulation = 480
- Warm-up: none by default (set if you want steady-state)
- Replications: use Experimenter; default for verification runs = 30 replications
(Experimenter > Replications = 30)
- Entities: We'll use logical entity types via naming (Order, WorkOrder, Part,
Dishwasher)
- Resources: W1_machine, W2_machine, W3_machine, W4_machine, setup_worker, AGV,
assembly_workers
ENTITY TYPES (logical; Arena uses Entity Type field in Create blocks)
- Order
- WorkOrder
- Part
- Dishwasher
RESOURCE DEFINITIONS (Add in Basic Process > Resources)
- Resource: W1_machine, Capacity = 1
- Resource: W2_machine, Capacity = 1
- Resource: W3_machine, Capacity = 1
- Resource: W4_machine, Capacity = 1
- Resource: setup_worker, Capacity = 2
- Resource: AGV, Capacity = 9
- Resource: assembly_workers, Capacity = 3
VARIABLES (Model > Basic Process > Variables)
- production_w1 = 0
- production_w2 = 0
- production_w3 = 0
- production_w4 = 0
- nextOrderID = 0 (use to assign unique IDs if desired)
- monthly_cost = 0 (for scenario cost calculations)
- base_AGV = 9 (reference value)
- base_setup_workers = 2
- base_W1 = 1 ; base_W2 = 1 ; base_W3 = 1 ; base_W4 = 1
ELEMENT-BY-ELEMENT MODULES (build in this order)
------------------------------------------------
1) CREATE - "Order Arrival"
- Module: Create
- Name: Order Arrival
- Entity Type: Order
- Arrival Mode: Random (Exponential)
- Time Between Arrivals: EXPO(60) ; mean interarrival = 60 min (1 hour)
- First Creation: 0.0
- Max Arrivals: leave blank (or set to very large)
2) ASSIGN - "Order Setup"
- Module: Assign (immediately after Order Arrival)
- Name: Order Setup
- Assignments (add lines):
- nextOrderID = nextOrderID + 1 (optional)
- [Link] = nextOrderID (attribute named OrderID)
- [Link] = TNOW
(We will pick OrderType and OrderQty with a Decide block next.)
3) DECIDE - "Order Type Decide"
- Module: Decide (By Chance)
- Name: Order Type Decide
- Type: By Chance (Probabilities)
- Branches:
- 0.70 --> Branch A (OrderType = "A")
- 0.20 --> Branch B (OrderType = "B")
- 0.10 --> Branch C (OrderType = "C")
4a) ASSIGN (Branch A) - "Set A Attributes"
- Module: Assign
- Name: Set A Attributes
- Assign:
- [Link] = "A"
- [Link] = TRUNC(UNIF(25,35)) ; use INT/Trunc to ensure integer if
desired
4b) ASSIGN (Branch B) - "Set B Attributes"
- Module: Assign
- Name: Set B Attributes
- Assign:
- [Link] = "B"
- [Link] = TRUNC(UNIF(17,23))
4c) ASSIGN (Branch C) - "Set C Attributes"
- Module: Assign
- Name: Set C Attributes
- Assign:
- [Link] = "C"
- [Link] = TRUNC(UNIF(18,22))
5) CREATE/CLONE WORKORDERS (For each product type create WorkOrders for required
part types)
- Approach: Use separate flows after the Order Type Decide for clarity.
Branch A (OrderType = "A") - Product A needs Part1, Part2, Part4
---------------------------------------------------------------
5A-1) CREATE - "Create WOs for A - Part1"
- Module: Create
- Name: Create WO_A_P1
- Entity Type: WorkOrder
- Number of Entities: 1
- Actions (immediately after Create use Assign block to set attributes):
- [Link] = [Link]
- [Link] = 1
- [Link] = [Link]
- [Link] = 1 ; optional helper to track routing steps
5A-2) CREATE - "Create WO_A_P2" (similar to above but PartType = 2)
5A-3) CREATE - "Create WO_A_P4" (PartType = 4)
Branch B (OrderType = "B") - Parts: 2,4,5,6
- Create 4 corresponding WorkOrder entities with PartType 2,4,5,6 and
PartsRemaining = OrderQty.
Branch C (OrderType = "C") - Parts: 1,2,3,4,5
- Create 5 WorkOrders for PartType 1,2,3,4,5 with PartsRemaining = OrderQty.
Implementation note:
- Since Arena does not automatically copy attributes from the parent Order to newly
created WorkOrder when using separate Create modules, be sure to pass attributes
via Assign (create an Assign module immediately after each Create to set
ParentOrderID, PartsRemaining, PartType, and OrderQty if needed).
6) ROUTING: WorkOrder → Workstation Sequence
---------------------------------------------
- For each WorkOrder entity, route it through the workstation sequence that
corresponds to its PartType.
- Suggested implementation:
- Place a DECIDE (By Expression) based on [Link] to jump to the
subflow for that part's routing.
- For each workstation in the route, create the following sub-block sequence
(detailed below).
Example: Part1 route = W2 -> W1 -> W3 -> W4 (as given in project data)
(You should confirm the provided routing table — use DECIDE to route each PartType
correctly.)
WORKSTATION PROCESSING SUB-SEQUENCE (for each station in a Part's route):
-----------------------------------------------------------------------
For each visit to a workstation (e.g., W1):
A) PROCESS - "Seize Setup Worker"
- Module: Process
- Name: Setup_Seize_Release (or Setup_W1)
- Action: Seize Delay Release (Seize setup_worker; Delay =
TRUNCNORMAL(0.5,0.1,0.4,0.6); Release setup_worker)
- Resource to seize: setup_worker (capacity 2)
- Delay time expression: TRUNCNORMAL(0.5,0.1,0.4,0.6)
- If your Arena version doesn't support TRUNCNORMAL, use a small VBA-style loop
or use NORM(0.5,0.1) with conditional rejection.
- Note: If you want to count setups, increment a counter variable here, e.g.,
production_setup = production_setup + 1
B) PROCESS - "Machine Process at W#"
- Module: Process
- Name: Process_W1
- Action: Seize Delay Release (Seize W1_machine)
- Resource: W1_machine
- Delay time expression (processing time distribution):
- W1: NORM(0.77,0.11)
- W2: NORM(0.50,0.14)
- W3: NORM(0.55,0.09)
- W4: Use Input Analyzer result. (Either use fitted distribution parameters or
Sample from table of 78 data points; instructions below to use table sampling)
- After the delay, Release W1_machine
C) ASSIGN - "Decrement PartsRemaining or Loop control"
- Module: Assign
- Name: Decrement PartsRemaining
- Assign:
- [Link] = [Link] - 1
- Next - DECIDE:
- If [Link] > 0 then route to the next required workstation in
the routing (or loop back as needed)
- If [Link] = 0 then proceed to "Create Parts" (the middle
area)
Important routing logic:
- The description implies each WorkOrder cycles through its routing sequence for
each individual dishwasher in the order quantity (i.e., number of cycles equals
OrderQty). One correct way to model:
- Keep WorkOrder moving through its routing in sequence once per cycle, and after
finishing all stations in the route, decrement PartsRemaining by 1. If
PartsRemaining still > 0, loop back to the first station in the route. If
PartsRemaining = 0, proceed to create Part entities.
- The alternative interpretation (process each WorkOrder in each station `OrderQty`
times before moving to next station) is incorrect. Implement the cycle-by-cycle
routing as above (complete route sequence = 1 part produced).
7) CREATING PART ENTITIES (after WorkOrder completed all cycles)
----------------------------------------------------------------
- When a WorkOrder reaches the end of its routing and has PartsRemaining = 0,
create `OrderQty` Part entities that represent the physical parts to be transported
to assembly.
- Implementation options:
Option 1 (preferred if Arena supports Create with attribute-based count):
- Use a Create module that creates `[Link]` copies where
ProducedQty was set to the original OrderQty.
Option 2 (general):
- Use a small loop: use a Process block with Delay = 0 and in it create one
Part entity and decrement a temporary counter until desired number created.
Option 3 (Split + Create):
- Use Arena's "Separate" + "Create" repeated - but the simplest is to have
WorkOrder carry attribute PartsProducedTarget (set to OrderQty) and run a loop that
creates that many Part entities.
- When creating each Part entity set attributes:
- [Link] = [Link]
- [Link] = [Link]
- [Link] = [Link]
- [Link] = TNOW
- After creation, send Parts to the Middle Area queue (name the queue:
MiddleArea_Q). Make sure that all parts queue here and wait for AGV pickup.
8) MIDDLE AREA QUEUE (storage for parts waiting for transport)
- Name the queue: MiddleArea_Q
- Set a Data Collection Tally / Statistic to measure time-average number in queue
(use the default queue statistic in Arena).
- Ensure this queue is the one you'll monitor for area requirement validation
(e.g., average # of parts in queue * area per part = required area).
9) AGV TRANSPORT (Transport from Middle Area to Assembly)
- Model AGV as a Resource with capacity = 9.
- For each Part to be transported create a Process block:
- Process Name: AGV_Transport
- Action: Seize Delay Release
- Resource to seize: AGV
- Delay: UNIF(3.3,7.3) ; this models loading+transport+unload round-trip
time
- Release AGV
- After AGV transport finishes, route Part to assembly arrival queues (one queue
per assembly match block if you want).
Notes on capacity = 1 per tour:
- The problem states "AGVs with capacity of 1 parts each in every tour." Since we
model AGV as a resource, ensure each Part seizes one AGV unit and the AGV capacity
equals number of physical AGVs (9). This models one AGV per trip for one part.
- If you later increase AGV capacity (scenario), modify resource capacity
accordingly.
10) MATCH / ASSEMBLY PREPARATION
- Create MATCH module(s) to collect the required parts for each order into a single
Dishwasher entity for assembly.
- Approach:
- Use separate Match blocks by OrderType or a single Match block with conditional
number to match.
- For each OrderType define "Number to Match" = number of different parts that go
into that dishwasher type.
- Product A: match 3 parts (parts 1,2,4) per unit produced (BUT careful: each
physical dishwasher needs 1 copy of each required part — you must match 1-of-each
part keyed by ParentOrderID and by part type)
- Product B: match 4 parts (2,4,5,6)
- Product C: match 5 parts (1,2,3,4,5)
- Recommended implementation in Arena:
- Use separate Match blocks for A, B, C keyed by AssemblyMatchKey = ParentOrderID
and configure each match block to wait for the correct part types count. If Arena's
Match cannot match by part-type conditionally, you may need a more manual approach:
- Route Parts by PartType into separate holding queues for each part-type and
then use a combination of Match blocks or Create/Batch logic to assemble exactly
one of each required part per dishwasher.
Simpler practical approach (common class approach):
- For each ParentOrderID and per desired dishwasher count, wait until there exist
available copies of all required part types in corresponding queues, then remove
one copy from each queue and create a Dishwasher entity. Implement by:
- After AGV arrival, route part to a queue named by (ParentOrderID, PartType) or
use a global pool per order and use a VBA/Logic check to create Dishwasher when all
counts for required parts >= 1.
11) ASSEMBLY PROCESS
- Once a Dishwasher entity is created via the Match logic, route it to Assembly
Process block:
- Process Name: Assembly_Process
- Action: Seize Delay Release
- Resource: assembly_workers (capacity = 3)
- Delay time expression depends on dishwasher type (A/B/C). Use a Decide or
attribute check to set appropriate delay:
- A: NORM(4.91,1.01)
- B: NORM(5.33,0.95)
- C: NORM(5.71,1.25)
- After delay, Release assembly_workers
- Dispose the Dishwasher (use Dispose module) and record time-in-system stat:
- Use Assign before Dispose to set OrderTimeInSystem = TNOW - [order arrival
time] (note: dishwasher must carry attribute linking to original OrderArrTime or
ParentOrderID to trace back)
- Use Tally or Record to store that value: TALLY("OrderTimeInSystem",
OrderTimeInSystem)
12) RECORDING / OUTPUTS (Tally / Statistics / Writes)
- Key statistics to collect:
- Tally("OrderTimeInSystem") ; collect mean, stdev, CI
- Queue statistic for MiddleArea_Q (average number in queue over time)
- Resource utilization for W1..W4, setup_worker, AGV, assembly_workers (Arena's
Resource reports)
- Number of parts created (counter)
- If you want per-entity output table:
- Use a Write block to write records for each completed dishwasher: (OrderID,
OrderType, OrderQty, CompletionTime, TimeInSystem) -> CSV file.
- Use Arena's Reports at the end of runs and export to Excel for plotting
(verification & validation graphs).
13) INPUT SAMPLING FOR W4 (using the provided 78 data points)
----------------------------------------------------------------
If you prefer to sample directly from the empirical W4 data (recommended until you
confirm a distribution), do the following:
A) Import W4 data into a Table in Arena (Data module):
- Create a RandomTable (or Data module Table) named W4_Table and paste all 78
numeric values in order.
- When modeling W4 processing times, use expression: TABLELOOKUP("W4_Table",
UNIFORM(1,78) rounded to int)
- In Arena use: SAMPLE("W4_Table") or TABLE("W4_Table", UNIFORM(1,78)) depending
on Arena version.
- Alternatively: Use Input Analyzer in Arena to fit a distribution (e.g., Normal,
Lognormal). If fitted distribution is acceptable, use that (e.g., NORM(mean,std)).
B) If you fitted NORM(mean,std) from analysis earlier:
- Use Process delay expression for W4: NORM([Link], [Link]) (replace with mean and
std from your Input Analyzer fit)
14) SCENARIOS (Alternative Designs)
-----------------------------------
Use Experimenter to define scenarios or create model copies. At minimum create two
alternatives plus baseline.
Baseline: resources as defined above
Scenario 1 - Add one W2 machine:
- Change resource W2_machine capacity to 2 (instead of 1)
- Keep other resources constant
Scenario 2 - Add one AGV:
- Change resource AGV capacity to 10 (instead of 9)
Scenario 3 (optional) - Add one setup worker:
- Change setup_worker capacity to 3 (instead of 2)
Cost calculations (monthly) - implement as expressions or Assigns after scenario
runs:
- monthly_cost = (W1_extra*30000) + (W2_extra*34000) + (W3_extra*25000) +
(W4_extra*38000) + (AGV_extra*1600) + (assembly_extra*9000) + (setup_extra*10000)
- Example: if W2 capacity = 2 in scenario then W2_extra = (2 - base_W2) = 1
15) VERIFICATION & VALIDATION (graphs and instructions)
--------------------------------------------------------
Verification Graphs (what to produce and how):
- Time-series plot of MiddleArea_Q queue length for a single replication (use
Arena's built-in Time Plot or export queue count per time unit to Excel)
- Resource utilization over time for AGV and W4_machine to check bottleneck
behavior (use Arena Time Plot or export)
- Animation trace: sample entity trace to visually inspect routing
Validation Graphs:
- Q-Q plot and histogram of W4 process times (already created using Input Analyzer
or external Python/Excel). Insert Q-Q and histogram images into report to justify
W4 distribution selection.
- Histogram of Order Time-in-System from simulation and compare to historical or
expected values (if available). Use Excel for overlay comparison.
- Scatter plot: Time-in-System vs OrderQty to check correlation between order size
and system time.
- Use Arena output exported to CSV and create plots in Excel or Python. For each
important statement claim in your report, include a supporting figure and short
interpretation.
16) EXPORTING DATA TO EXCEL / CSV (Write block)
- Use Write module to write per-completion records:
- File name: Output_OrderRecords.csv
- Columns: OrderID, ParentOrderID, OrderType, OrderQty, CompletionTime,
TimeInSystem
- After simulation runs finish, open CSV in Excel for plotting histograms,
scatterplots, Q-Q plots, etc.
17) SUGGESTED EXPERIMENTER SETTINGS
- Replications: 30 (or more for CI narrowness)
- Random Seed: Use default or set replicable seeds
- Use scenarios to run baseline and alternatives automatically and compare output
statistics (Tally mean for "OrderTimeInSystem", MiddleArea_Q average, AGV
utilization)
18) SUGGESTED CHECK LIST FOR BUILD & TEST
- [ ] Confirm routing table for all PartTypes (PartType -> sequence of W#)
- [ ] Verify WorkOrder cycles logic (complete route sequence per cycle)
- [ ] Verify Part creation count equals OrderQty
- [ ] Match logic: ensure matching is keyed by ParentOrderID and that parts types
are correctly matched
- [ ] Validate W4 distribution via Input Analyzer (fit and choose a distribution)
- [ ] Run single replication in trace mode to validate entity flow and debug
- [ ] Run multiple replications and collect statistics
APPENDIX - Exact Expressions & Arena-friendly code snippets
-----------------------------------------------------------
- Interarrival: EXPO(60)
- OrderQty (A): TRUNC(UNIF(25,35))
- OrderQty (B): TRUNC(UNIF(17,23))
- OrderQty (C): TRUNC(UNIF(18,22))
- Setup time: TRUNCNORMAL(0.5,0.1,0.4,0.6) (if available)
- W1 process: NORM(0.77,0.11)
- W2 process: NORM(0.50,0.14)
- W3 process: NORM(0.55,0.09)
- W4 process: SAMPLE from table "W4_Table" or NORM(mean,std) if fitted
- AGV trip time: UNIF(3.3,7.3)
- Assembly times:
- A: NORM(4.91,1.01)
- B: NORM(5.33,0.95)
- C: NORM(5.71,1.25)
COMMON ARENA IMPLEMENTATION TIPS
--------------------------------
- Use ATTRIBUTES: In Create module set Attributes if Arena version supports
attribute assignment on creation. Otherwise use Assign blocks right after Create.
- Use MATCH: Keyed by ParentOrderID for assembly matching; if matching by type is
complex, consider explicit queues and a small logic submodel to create dishwashers.
- Debugging: Run a short replication (length=60 with small arrival rate) and use
animation trace to confirm the flow.
- Export: Use Write blocks for detailed per-entity exports for Excel analysis.
-----------------------------------------------
End of Arena Model Instructions - copy this file into a plain text file
-----------------------------------------------