Warehouse Simulation with SimPy: From Receiving to Shipping

<p>Warehouses are logistics engines. Goods flow in, get stored, get picked, and flow out. Simulation reveals the bottlenecks between receive and ship.</p> <h2 id="the-warehouse-model">The Warehouse Model</h2> <p>Key processes: - <strong>Receiving</strong> - Goods arrive - <strong>Putaway</strong> - Storage in locations - <strong>Storage</strong> - Inventory holding - <strong>Picking</strong> - Order fulfillment - <strong>Packing</strong> - Preparation for shipping - <strong>Shipping</strong> - Goods leave</p> <h2 id="basic-warehouse">Basic Warehouse</h2> <div class="code-block"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">simpy</span> <span class="kn">import</span><span class="w"> </span><span class="nn">random</span> <span class="k">class</span><span class="w"> </span><span class="nc">Warehouse</span><span class="p">:</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">env</span><span class="p">,</span> <span class="n">config</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span> <span class="o">=</span> <span class="n">env</span> <span class="bp">self</span><span class="o">.</span><span class="n">receiving_docks</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;receiving_docks&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">forklifts</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;forklifts&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">pickers</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;pickers&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">packing_stations</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;packing_stations&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">shipping_docks</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;shipping_docks&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Container</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;storage_capacity&#39;</span><span class="p">],</span> <span class="n">init</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;initial_inventory&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">stats</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;received&#39;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">&#39;shipped&#39;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">&#39;orders&#39;</span><span class="p">:</span> <span class="p">[]}</span> <span class="k">def</span><span class="w"> </span><span class="nf">receive_shipment</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">shipment_id</span><span class="p">,</span> <span class="n">quantity</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Process incoming shipment.&quot;&quot;&quot;</span> <span class="n">arrival</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="c1"># Dock</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">receiving_docks</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">dock</span><span class="p">:</span> <span class="k">yield</span> <span class="n">dock</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="mi">30</span><span class="p">))</span> <span class="c1"># Unload</span> <span class="c1"># Putaway with forklift</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">forklifts</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">forklift</span><span class="p">:</span> <span class="k">yield</span> <span class="n">forklift</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">quantity</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">)</span> <span class="c1"># Time per pallet</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">quantity</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">stats</span><span class="p">[</span><span class="s1">&#39;received&#39;</span><span class="p">]</span> <span class="o">+=</span> <span class="n">quantity</span> <span class="k">def</span><span class="w"> </span><span class="nf">process_order</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">order_id</span><span class="p">,</span> <span class="n">items</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Pick, pack, and ship an order.&quot;&quot;&quot;</span> <span class="n">order_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="n">record</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="n">order_id</span><span class="p">,</span> <span class="s1">&#39;items&#39;</span><span class="p">:</span> <span class="n">items</span><span class="p">,</span> <span class="s1">&#39;start&#39;</span><span class="p">:</span> <span class="n">order_start</span><span class="p">}</span> <span class="c1"># Pick items</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">pickers</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">picker</span><span class="p">:</span> <span class="k">yield</span> <span class="n">picker</span> <span class="c1"># Travel and pick time</span> <span class="n">pick_time</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">items</span><span class="p">))</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">pick_time</span><span class="p">)</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">items</span><span class="p">)</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;picked&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="c1"># Pack</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">packing_stations</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">station</span><span class="p">:</span> <span class="k">yield</span> <span class="n">station</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;packed&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="c1"># Ship</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">shipping_docks</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">dock</span><span class="p">:</span> <span class="k">yield</span> <span class="n">dock</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;shipped&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;total_time&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="o">-</span> <span class="n">order_start</span> <span class="bp">self</span><span class="o">.</span><span class="n">stats</span><span class="p">[</span><span class="s1">&#39;orders&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">record</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">stats</span><span class="p">[</span><span class="s1">&#39;shipped&#39;</span><span class="p">]</span> <span class="o">+=</span> <span class="n">items</span> <span class="c1"># Run simulation</span> <span class="n">env</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Environment</span><span class="p">()</span> <span class="n">warehouse</span> <span class="o">=</span> <span class="n">Warehouse</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="p">{</span> <span class="s1">&#39;receiving_docks&#39;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">&#39;forklifts&#39;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">&#39;pickers&#39;</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="s1">&#39;packing_stations&#39;</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> <span class="s1">&#39;shipping_docks&#39;</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">&#39;storage_capacity&#39;</span><span class="p">:</span> <span class="mi">10000</span><span class="p">,</span> <span class="s1">&#39;initial_inventory&#39;</span><span class="p">:</span> <span class="mi">5000</span> <span class="p">})</span> </code></pre></div> <h2 id="zone-based-picking">Zone-Based Picking</h2> <div class="code-block"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">ZonedWarehouse</span><span class="p">:</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">env</span><span class="p">,</span> <span class="n">zone_config</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span> <span class="o">=</span> <span class="n">env</span> <span class="bp">self</span><span class="o">.</span><span class="n">zones</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="n">zone_name</span><span class="p">,</span> <span class="n">config</span> <span class="ow">in</span> <span class="n">zone_config</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> <span class="bp">self</span><span class="o">.</span><span class="n">zones</span><span class="p">[</span><span class="n">zone_name</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">&#39;inventory&#39;</span><span class="p">:</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Container</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;capacity&#39;</span><span class="p">],</span> <span class="n">init</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;initial&#39;</span><span class="p">]),</span> <span class="s1">&#39;pickers&#39;</span><span class="p">:</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;pickers&#39;</span><span class="p">])</span> <span class="p">}</span> <span class="k">def</span><span class="w"> </span><span class="nf">pick_order</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">order_id</span><span class="p">,</span> <span class="n">items_by_zone</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Pick items from multiple zones.&quot;&quot;&quot;</span> <span class="n">picked_items</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">zone_name</span><span class="p">,</span> <span class="n">items</span> <span class="ow">in</span> <span class="n">items_by_zone</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> <span class="n">zone</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">zones</span><span class="p">[</span><span class="n">zone_name</span><span class="p">]</span> <span class="k">with</span> <span class="n">zone</span><span class="p">[</span><span class="s1">&#39;pickers&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">picker</span><span class="p">:</span> <span class="k">yield</span> <span class="n">picker</span> <span class="k">yield</span> <span class="n">zone</span><span class="p">[</span><span class="s1">&#39;inventory&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">items</span><span class="p">)</span> <span class="n">pick_time</span> <span class="o">=</span> <span class="n">items</span> <span class="o">*</span> <span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="mf">0.8</span><span class="p">)</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">pick_time</span><span class="p">)</span> <span class="n">picked_items</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="n">zone_name</span><span class="p">]</span> <span class="o">*</span> <span class="n">items</span><span class="p">)</span> <span class="k">return</span> <span class="n">picked_items</span> <span class="c1"># Zone configuration</span> <span class="n">zone_config</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">&#39;A&#39;</span><span class="p">:</span> <span class="p">{</span><span class="s1">&#39;capacity&#39;</span><span class="p">:</span> <span class="mi">3000</span><span class="p">,</span> <span class="s1">&#39;initial&#39;</span><span class="p">:</span> <span class="mi">2000</span><span class="p">,</span> <span class="s1">&#39;pickers&#39;</span><span class="p">:</span> <span class="mi">4</span><span class="p">},</span> <span class="c1"># Fast movers</span> <span class="s1">&#39;B&#39;</span><span class="p">:</span> <span class="p">{</span><span class="s1">&#39;capacity&#39;</span><span class="p">:</span> <span class="mi">5000</span><span class="p">,</span> <span class="s1">&#39;initial&#39;</span><span class="p">:</span> <span class="mi">3000</span><span class="p">,</span> <span class="s1">&#39;pickers&#39;</span><span class="p">:</span> <span class="mi">3</span><span class="p">},</span> <span class="c1"># Medium</span> <span class="s1">&#39;C&#39;</span><span class="p">:</span> <span class="p">{</span><span class="s1">&#39;capacity&#39;</span><span class="p">:</span> <span class="mi">8000</span><span class="p">,</span> <span class="s1">&#39;initial&#39;</span><span class="p">:</span> <span class="mi">5000</span><span class="p">,</span> <span class="s1">&#39;pickers&#39;</span><span class="p">:</span> <span class="mi">2</span><span class="p">},</span> <span class="c1"># Slow movers</span> <span class="p">}</span> </code></pre></div> <h2 id="wave-planning">Wave Planning</h2> <div class="code-block"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">WaveBasedWarehouse</span><span class="p">:</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">env</span><span class="p">,</span> <span class="n">config</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span> <span class="o">=</span> <span class="n">env</span> <span class="bp">self</span><span class="o">.</span><span class="n">config</span> <span class="o">=</span> <span class="n">config</span> <span class="bp">self</span><span class="o">.</span><span class="n">order_queue</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Store</span><span class="p">(</span><span class="n">env</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">pickers</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;pickers&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">waves_completed</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">def</span><span class="w"> </span><span class="nf">receive_order</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">order</span><span class="p">):</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">order_queue</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">order</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">run_waves</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">wave_interval</span><span class="p">,</span> <span class="n">orders_per_wave</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Release orders in waves.&quot;&quot;&quot;</span> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">wave_interval</span><span class="p">)</span> <span class="c1"># Collect orders for this wave</span> <span class="n">wave_orders</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">wave_orders</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">orders_per_wave</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">order</span> <span class="o">=</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">order_queue</span><span class="o">.</span><span class="n">get</span><span class="p">()</span> <span class="n">wave_orders</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">order</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="k">break</span> <span class="k">if</span> <span class="n">wave_orders</span><span class="p">:</span> <span class="c1"># Process wave</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">process</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">process_wave</span><span class="p">(</span><span class="n">wave_orders</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">waves_completed</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">def</span><span class="w"> </span><span class="nf">process_wave</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">orders</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Process all orders in a wave.&quot;&quot;&quot;</span> <span class="c1"># Sort by zone to minimize travel</span> <span class="n">orders</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">o</span><span class="p">:</span> <span class="n">o</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;zone&#39;</span><span class="p">,</span> <span class="s1">&#39;A&#39;</span><span class="p">))</span> <span class="k">for</span> <span class="n">order</span> <span class="ow">in</span> <span class="n">orders</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">process</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">pick_order</span><span class="p">(</span><span class="n">order</span><span class="p">))</span> <span class="c1"># Wait for all picks to complete</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> </code></pre></div> <h2 id="conveyor-system">Conveyor System</h2> <div class="code-block"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">ConveyorSystem</span><span class="p">:</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">env</span><span class="p">,</span> <span class="n">speed</span><span class="p">,</span> <span class="n">length</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span> <span class="o">=</span> <span class="n">env</span> <span class="bp">self</span><span class="o">.</span><span class="n">speed</span> <span class="o">=</span> <span class="n">speed</span> <span class="c1"># Items per minute</span> <span class="bp">self</span><span class="o">.</span><span class="n">length</span> <span class="o">=</span> <span class="n">length</span> <span class="c1"># Sections</span> <span class="bp">self</span><span class="o">.</span><span class="n">sections</span> <span class="o">=</span> <span class="p">[</span><span class="n">simpy</span><span class="o">.</span><span class="n">Store</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">length</span><span class="p">)]</span> <span class="k">def</span><span class="w"> </span><span class="nf">put_item</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Put item on conveyor at start.&quot;&quot;&quot;</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">sections</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Move items along conveyor.&quot;&quot;&quot;</span> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="mi">1</span> <span class="o">/</span> <span class="bp">self</span><span class="o">.</span><span class="n">speed</span><span class="p">)</span> <span class="c1"># Move items from end to start</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">):</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">sections</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">items</span><span class="p">:</span> <span class="n">item</span> <span class="o">=</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">sections</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">()</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">sections</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_item</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Get item from end of conveyor.&quot;&quot;&quot;</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">sections</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">()</span> </code></pre></div> <h2 id="complete-warehouse-simulation">Complete Warehouse Simulation</h2> <div class="code-block"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">simpy</span> <span class="kn">import</span><span class="w"> </span><span class="nn">random</span> <span class="kn">import</span><span class="w"> </span><span class="nn">numpy</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">np</span> <span class="k">class</span><span class="w"> </span><span class="nc">FullWarehouseSimulation</span><span class="p">:</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">env</span><span class="p">,</span> <span class="n">config</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span> <span class="o">=</span> <span class="n">env</span> <span class="bp">self</span><span class="o">.</span><span class="n">config</span> <span class="o">=</span> <span class="n">config</span> <span class="c1"># Resources</span> <span class="bp">self</span><span class="o">.</span><span class="n">receiving</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;receiving_docks&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">putaway_crew</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;putaway_workers&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Container</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;storage&#39;</span><span class="p">],</span> <span class="n">init</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;initial_stock&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">pickers</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;pickers&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">packers</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;packers&#39;</span><span class="p">])</span> <span class="bp">self</span><span class="o">.</span><span class="n">shipping</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Resource</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">capacity</span><span class="o">=</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;shipping_docks&#39;</span><span class="p">])</span> <span class="c1"># Stats</span> <span class="bp">self</span><span class="o">.</span><span class="n">order_stats</span> <span class="o">=</span> <span class="p">[]</span> <span class="bp">self</span><span class="o">.</span><span class="n">inbound_stats</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">def</span><span class="w"> </span><span class="nf">inbound_shipment</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">shipment_id</span><span class="p">,</span> <span class="n">pallets</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Process inbound delivery.&quot;&quot;&quot;</span> <span class="n">arrival</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="n">record</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="n">shipment_id</span><span class="p">,</span> <span class="s1">&#39;pallets&#39;</span><span class="p">:</span> <span class="n">pallets</span><span class="p">,</span> <span class="s1">&#39;arrival&#39;</span><span class="p">:</span> <span class="n">arrival</span><span class="p">}</span> <span class="c1"># Receive</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">receiving</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">dock</span><span class="p">:</span> <span class="k">yield</span> <span class="n">dock</span> <span class="n">unload_time</span> <span class="o">=</span> <span class="n">pallets</span> <span class="o">*</span> <span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">unload_time</span><span class="p">)</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;unloaded&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="c1"># Putaway</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">putaway_crew</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">worker</span><span class="p">:</span> <span class="k">yield</span> <span class="n">worker</span> <span class="n">putaway_time</span> <span class="o">=</span> <span class="n">pallets</span> <span class="o">*</span> <span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">putaway_time</span><span class="p">)</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">pallets</span> <span class="o">*</span> <span class="mi">50</span><span class="p">)</span> <span class="c1"># 50 units per pallet</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;stored&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;total_time&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="o">-</span> <span class="n">arrival</span> <span class="bp">self</span><span class="o">.</span><span class="n">inbound_stats</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">record</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">outbound_order</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">order_id</span><span class="p">,</span> <span class="n">units</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Process customer order.&quot;&quot;&quot;</span> <span class="n">arrival</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="n">record</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="n">order_id</span><span class="p">,</span> <span class="s1">&#39;units&#39;</span><span class="p">:</span> <span class="n">units</span><span class="p">,</span> <span class="s1">&#39;arrival&#39;</span><span class="p">:</span> <span class="n">arrival</span><span class="p">}</span> <span class="c1"># Wait for inventory if needed</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">units</span><span class="p">)</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;allocated&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="c1"># Pick</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">pickers</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">picker</span><span class="p">:</span> <span class="k">yield</span> <span class="n">picker</span> <span class="n">lines</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">units</span> <span class="o">//</span> <span class="mi">5</span><span class="p">)</span> <span class="n">pick_time</span> <span class="o">=</span> <span class="n">lines</span> <span class="o">*</span> <span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">pick_time</span><span class="p">)</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;picked&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="c1"># Pack</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">packers</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">packer</span><span class="p">:</span> <span class="k">yield</span> <span class="n">packer</span> <span class="n">pack_time</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">pack_time</span><span class="p">)</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;packed&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="c1"># Ship</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">shipping</span><span class="o">.</span><span class="n">request</span><span class="p">()</span> <span class="k">as</span> <span class="n">dock</span><span class="p">:</span> <span class="k">yield</span> <span class="n">dock</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;shipped&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="n">record</span><span class="p">[</span><span class="s1">&#39;total_time&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="o">-</span> <span class="n">arrival</span> <span class="bp">self</span><span class="o">.</span><span class="n">order_stats</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">record</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">inbound_arrivals</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Generate inbound deliveries.&quot;&quot;&quot;</span> <span class="n">shipment_id</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">expovariate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;inbound_rate&#39;</span><span class="p">]))</span> <span class="n">pallets</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">process</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inbound_shipment</span><span class="p">(</span><span class="n">shipment_id</span><span class="p">,</span> <span class="n">pallets</span><span class="p">))</span> <span class="n">shipment_id</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">def</span><span class="w"> </span><span class="nf">order_arrivals</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Generate customer orders.&quot;&quot;&quot;</span> <span class="n">order_id</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span> <span class="c1"># Time-varying order rate</span> <span class="n">hour</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span> <span class="o">/</span> <span class="mi">60</span><span class="p">)</span> <span class="o">%</span> <span class="mi">24</span> <span class="k">if</span> <span class="mi">9</span> <span class="o">&lt;=</span> <span class="n">hour</span> <span class="o">&lt;=</span> <span class="mi">17</span><span class="p">:</span> <span class="n">rate</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;peak_order_rate&#39;</span><span class="p">]</span> <span class="k">else</span><span class="p">:</span> <span class="n">rate</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s1">&#39;off_peak_order_rate&#39;</span><span class="p">]</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">expovariate</span><span class="p">(</span><span class="n">rate</span><span class="p">))</span> <span class="n">units</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">process</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">outbound_order</span><span class="p">(</span><span class="n">order_id</span><span class="p">,</span> <span class="n">units</span><span class="p">))</span> <span class="n">order_id</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">def</span><span class="w"> </span><span class="nf">inventory_monitor</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">interval</span><span class="o">=</span><span class="mi">60</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Track inventory levels.&quot;&quot;&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory_log</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory_log</span><span class="o">.</span><span class="n">append</span><span class="p">({</span> <span class="s1">&#39;time&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span><span class="p">,</span> <span class="s1">&#39;level&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory</span><span class="o">.</span><span class="n">level</span> <span class="p">})</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">timeout</span><span class="p">(</span><span class="n">interval</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">duration</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">process</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inbound_arrivals</span><span class="p">())</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">process</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">order_arrivals</span><span class="p">())</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">process</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inventory_monitor</span><span class="p">())</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">until</span><span class="o">=</span><span class="n">duration</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">report</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">=== Warehouse Simulation Report ===&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Duration: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">now</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">60</span><span class="si">:</span><span class="s2">.1f</span><span class="si">}</span><span class="s2"> hours&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Inbound:&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; Shipments: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inbound_stats</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">inbound_stats</span><span class="p">:</span> <span class="n">times</span> <span class="o">=</span> <span class="p">[</span><span class="n">s</span><span class="p">[</span><span class="s1">&#39;total_time&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">inbound_stats</span><span class="p">]</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; Avg dock-to-stock: </span><span class="si">{</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">times</span><span class="p">)</span><span class="si">:</span><span class="s2">.1f</span><span class="si">}</span><span class="s2"> min&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Outbound:&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; Orders: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">order_stats</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">order_stats</span><span class="p">:</span> <span class="n">times</span> <span class="o">=</span> <span class="p">[</span><span class="n">s</span><span class="p">[</span><span class="s1">&#39;total_time&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">order_stats</span><span class="p">]</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; Avg order cycle time: </span><span class="si">{</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">times</span><span class="p">)</span><span class="si">:</span><span class="s2">.1f</span><span class="si">}</span><span class="s2"> min&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; 90th percentile: </span><span class="si">{</span><span class="n">np</span><span class="o">.</span><span class="n">percentile</span><span class="p">(</span><span class="n">times</span><span class="p">,</span><span class="w"> </span><span class="mi">90</span><span class="p">)</span><span class="si">:</span><span class="s2">.1f</span><span class="si">}</span><span class="s2"> min&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Inventory:&quot;</span><span class="p">)</span> <span class="n">levels</span> <span class="o">=</span> <span class="p">[</span><span class="n">l</span><span class="p">[</span><span class="s1">&#39;level&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">inventory_log</span><span class="p">]</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; Avg level: </span><span class="si">{</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">levels</span><span class="p">)</span><span class="si">:</span><span class="s2">.0f</span><span class="si">}</span><span class="s2"> units&quot;</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot; Min level: </span><span class="si">{</span><span class="nb">min</span><span class="p">(</span><span class="n">levels</span><span class="p">)</span><span class="si">:</span><span class="s2">.0f</span><span class="si">}</span><span class="s2"> units&quot;</span><span class="p">)</span> <span class="c1"># Config</span> <span class="n">config</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">&#39;receiving_docks&#39;</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">&#39;putaway_workers&#39;</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">&#39;storage&#39;</span><span class="p">:</span> <span class="mi">50000</span><span class="p">,</span> <span class="s1">&#39;initial_stock&#39;</span><span class="p">:</span> <span class="mi">25000</span><span class="p">,</span> <span class="s1">&#39;pickers&#39;</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="s1">&#39;packers&#39;</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> <span class="s1">&#39;shipping_docks&#39;</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">&#39;inbound_rate&#39;</span><span class="p">:</span> <span class="mf">0.02</span><span class="p">,</span> <span class="s1">&#39;peak_order_rate&#39;</span><span class="p">:</span> <span class="mf">0.5</span><span class="p">,</span> <span class="s1">&#39;off_peak_order_rate&#39;</span><span class="p">:</span> <span class="mf">0.1</span> <span class="p">}</span> <span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span> <span class="n">env</span> <span class="o">=</span> <span class="n">simpy</span><span class="o">.</span><span class="n">Environment</span><span class="p">()</span> <span class="n">sim</span> <span class="o">=</span> <span class="n">FullWarehouseSimulation</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">config</span><span class="p">)</span> <span class="n">sim</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">duration</span><span class="o">=</span><span class="mi">480</span><span class="p">)</span> <span class="c1"># 8 hours</span> <span class="n">sim</span><span class="o">.</span><span class="n">report</span><span class="p">()</span> </code></pre></div> <h2 id="summary">Summary</h2> <p>Warehouse simulation captures: - Inbound and outbound flows - Resource constraints (docks, workers, equipment) - Inventory dynamics - Order cycle times - Zone-based operations</p> <p>Simulate before you build. Optimise before you fail.</p> <h2 id="next-steps">Next Steps</h2> <ul> <li><a href="/blog_posts/simpy-supply-chain-simulation.html">Supply Chain Simulation</a></li> <li><a href="/blog_posts/simpy-manufacturing-simulation.html">Manufacturing Simulation</a></li> <li><a href="/blog_posts/simpy-container-explained.html">Container Explained</a></li> </ul>

Build Professional Simulations

Break free from commercial software and learn how to build powerful, industry-standard simulations in Python. The Complete Simulation in Python with SimPy Bootcamp gives you everything you need.

Explore the Bootcamp