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">'receiving_docks'</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">'forklifts'</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">'pickers'</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">'packing_stations'</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">'shipping_docks'</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">'storage_capacity'</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">'initial_inventory'</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">'received'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">'shipped'</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="s1">'orders'</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">"""Process incoming shipment."""</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">'received'</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">"""Pick, pack, and ship an order."""</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">'id'</span><span class="p">:</span> <span class="n">order_id</span><span class="p">,</span> <span class="s1">'items'</span><span class="p">:</span> <span class="n">items</span><span class="p">,</span> <span class="s1">'start'</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">'picked'</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">'packed'</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">'shipped'</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">'total_time'</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">'orders'</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">'shipped'</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">'receiving_docks'</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">'forklifts'</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'pickers'</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="s1">'packing_stations'</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> <span class="s1">'shipping_docks'</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">'storage_capacity'</span><span class="p">:</span> <span class="mi">10000</span><span class="p">,</span> <span class="s1">'initial_inventory'</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">'inventory'</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">'capacity'</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">'initial'</span><span class="p">]),</span> <span class="s1">'pickers'</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">'pickers'</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">"""Pick items from multiple zones."""</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">'pickers'</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">'inventory'</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">'A'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'capacity'</span><span class="p">:</span> <span class="mi">3000</span><span class="p">,</span> <span class="s1">'initial'</span><span class="p">:</span> <span class="mi">2000</span><span class="p">,</span> <span class="s1">'pickers'</span><span class="p">:</span> <span class="mi">4</span><span class="p">},</span> <span class="c1"># Fast movers</span> <span class="s1">'B'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'capacity'</span><span class="p">:</span> <span class="mi">5000</span><span class="p">,</span> <span class="s1">'initial'</span><span class="p">:</span> <span class="mi">3000</span><span class="p">,</span> <span class="s1">'pickers'</span><span class="p">:</span> <span class="mi">3</span><span class="p">},</span> <span class="c1"># Medium</span> <span class="s1">'C'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'capacity'</span><span class="p">:</span> <span class="mi">8000</span><span class="p">,</span> <span class="s1">'initial'</span><span class="p">:</span> <span class="mi">5000</span><span class="p">,</span> <span class="s1">'pickers'</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">'pickers'</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">"""Release orders in waves."""</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"><</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">"""Process all orders in a wave."""</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">'zone'</span><span class="p">,</span> <span class="s1">'A'</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">"""Put item on conveyor at start."""</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">"""Move items along conveyor."""</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">"""Get item from end of conveyor."""</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">'receiving_docks'</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">'putaway_workers'</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">'storage'</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">'initial_stock'</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">'pickers'</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">'packers'</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">'shipping_docks'</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">"""Process inbound delivery."""</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">'id'</span><span class="p">:</span> <span class="n">shipment_id</span><span class="p">,</span> <span class="s1">'pallets'</span><span class="p">:</span> <span class="n">pallets</span><span class="p">,</span> <span class="s1">'arrival'</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">'unloaded'</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">'stored'</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">'total_time'</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">"""Process customer order."""</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">'id'</span><span class="p">:</span> <span class="n">order_id</span><span class="p">,</span> <span class="s1">'units'</span><span class="p">:</span> <span class="n">units</span><span class="p">,</span> <span class="s1">'arrival'</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">'allocated'</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">'picked'</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">'packed'</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">'shipped'</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">'total_time'</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">"""Generate inbound deliveries."""</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">'inbound_rate'</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">"""Generate customer orders."""</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"><=</span> <span class="n">hour</span> <span class="o"><=</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">'peak_order_rate'</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">'off_peak_order_rate'</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">"""Track inventory levels."""</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">'time'</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">'level'</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">"</span><span class="se">\n</span><span class="s2">=== Warehouse Simulation Report ==="</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"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"</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Inbound:"</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">" 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">"</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">'total_time'</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">" 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"</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Outbound:"</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">" 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">"</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">'total_time'</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">" 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"</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">" 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"</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Inventory:"</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">'level'</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">" 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"</span><span class="p">)</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">" 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"</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">'receiving_docks'</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">'putaway_workers'</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">'storage'</span><span class="p">:</span> <span class="mi">50000</span><span class="p">,</span> <span class="s1">'initial_stock'</span><span class="p">:</span> <span class="mi">25000</span><span class="p">,</span> <span class="s1">'pickers'</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="s1">'packers'</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span> <span class="s1">'shipping_docks'</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">'inbound_rate'</span><span class="p">:</span> <span class="mf">0.02</span><span class="p">,</span> <span class="s1">'peak_order_rate'</span><span class="p">:</span> <span class="mf">0.5</span><span class="p">,</span> <span class="s1">'off_peak_order_rate'</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