Skip to content

Commit

Permalink
Add examples
Browse files Browse the repository at this point in the history
  • Loading branch information
jouzz committed Apr 18, 2024
1 parent 53202d3 commit 20e586e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 4 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# sim
Discrete event simulation library, inspired by GPSS, to be used in Deno projects.
Discrete event simulation library, inspired by GPSS and SimPy.

## Usage
Deno import
```js
import { Process, Sim, uniformInt } from "https://deno.land/x/[email protected]/mod.ts";

Expand All @@ -20,6 +19,8 @@ sim.generatePoisson(agent, 1 / 5); // generate one agent every 5 units of time
sim.run(30); // start the simulation, and run it for 30 units of time
```

Check the examples folder for other models.

## Current capabilities
- Scheduling of events with simulated time
- Resources, with impatience
Expand All @@ -28,6 +29,6 @@ sim.run(30); // start the simulation, and run it for 30 units of time
- Basic analysis (multiple runs, ANOVA, etc.)
- Basic charts (using Vega-Lite)

## Intended
- Better docs (for now, see tests)
## TO-DO
- More examples
- Ability for processes to get more information about the simulated environment (resource stats, etc.)
3 changes: 3 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Examples

The SimPy folder contains simulation models that try to reproduce some of the [SimPy example models](https://simpy.readthedocs.io/en/latest/examples/index.html).
59 changes: 59 additions & 0 deletions examples/SimPy/bank_renege.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Covers: Resources, Condition events
A counter with a random service time and customers who renege.
Based on https://simpy.readthedocs.io/en/latest/examples/bank_renege.html
This example models a bank counter and customers arriving at random times.
Each customer has a certain patience. She waits to get to the counter until she’s at the end of her tether.
If she gets to the counter, she uses it for a while before releasing it.
New customers are created by the source process every few time steps.
*/

import { PREEMPT, Process, Result, Sim, expovariate, uniform } from "../../mod.ts";

const NEW_CUSTOMERS = 5 // Total number of customers
const INTERVAL_CUSTOMERS = 10.0 // Generate new customers roughly every x seconds
const MIN_PATIENCE = 1 // Min. customer patience
const MAX_PATIENCE = 3 // Max. customer patience

const sim = new Sim();

const counter = sim.resource("Counter");

function* source(_: number): Process {
for(let i=0; i<NEW_CUSTOMERS; ++i){
sim.spawn(customer);
yield expovariate(1 / INTERVAL_CUSTOMERS);
}
}

let customerId = 0;

function* customer(_: number): Process {
const arrive = sim.time;
const name = `Customer 0${++customerId}`;
console.log(`${arrive.toFixed(4)} ${name}: Here I am`);
const req = yield counter.requestImpatient(impatience);
const wait = sim.time - arrive;
if(req == Result.OK){
console.log(`${sim.time.toFixed(4)} ${name}: Waited ${wait}`);
yield expovariate(1 / 12);
yield counter.release();
console.log(`${sim.time.toFixed(4)} ${name}: Finished`);
}
else{
console.log(`${sim.time.toFixed(4)} ${name}: RENEGED after ${wait}`);
}
}

function* impatience(_:number): Process {
const patience = uniform(MIN_PATIENCE, MAX_PATIENCE);
yield patience;
yield PREEMPT;
}

sim.spawn(source);
console.log("Bank Renege");
sim.run();
45 changes: 45 additions & 0 deletions examples/SimPy/carwash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Carwash example.
Based on https://simpy.readthedocs.io/en/latest/examples/carwash.html
Covers: Waiting for other processes, Resources
Scenario:
A carwash has a limited number of washing machines and defines
a washing processes that takes some (random) time.
Car processes arrive at the carwash at a random time. If one washing
machine is available, they start the washing process and wait for it
to finish. If not, they wait until they can use one.
*/

import { Sim, Process, uniformInt } from "../../mod.ts";

const NUM_MACHINES = 2 // Number of machines in the carwash
const WASHTIME = 5 // Minutes it takes to clean a car
const T_INTER = 7 // Create a car every ~7 minutes
const SIM_TIME = 20 // Simulation time in minutes

const sim = new Sim();

const machine = sim.resource("Machine", NUM_MACHINES);

let carCount = 0;

function* car(_: number): Process {
const name = `Car ${carCount++}`;
console.log(`${name} arrives at the carwash at ${sim.time.toFixed(2)}`);
yield machine.request();
console.log(`${name} enters the carwash at ${sim.time.toFixed(2)}`);
yield WASHTIME;
const pctDirt = uniformInt(50, 99);
console.log(`Carwash removed ${pctDirt}% of ${name}'s dirt`);
console.log(`${name} leaves the carwash at ${sim.time.toFixed(2)}`);
yield machine.release();
}

for(let i=0; i<4; ++i) sim.spawn(car);
sim.generate(car, T_INTER, 2);

console.log("Carwash");
sim.run(SIM_TIME);

0 comments on commit 20e586e

Please sign in to comment.