
In het 2e jaar van Bedrijfskunde moest er bij het vak “Kwantitatieve Besluitvormingstechnieken” een programmeer opdracht gedaan worden. Het ging daarbij een wachtrij probleem waarvoor een optimale oplossing gevonden moest worden mbv een computer programma: “zoek gegeven een bepaalde aankomst verdeling van oost/west-bootjes en noord/zuid-autootjes naar de beste brugopening regel voor een brugwachter”, “hoeveel meter extra kade moet er komen bij een bepaalde toename van vrachtboten”, etc.
Het is 1984 en dat programma schrijf ik in de object oriented (!) taal “Simula” op de Vax computer van de RUG! Hoe cool is dat? In dat jaar waren er overigens maar 4 mede studenten die zo’n programma konden schrijven en uiteindelijk hebben wij dus alle opdrachten gemaakt. Niet verder vertellen! We hadden overigens geen onderlinge afspraken gemaakt, dus het zal niet heel moeilijk geweest zijn te herkennen welke programmeur welke programma geschreven had.
2024: … en toen kwam..

Je voert in: “schrijf een simula programma waarmee ik openingstijden voor een brug kan simuleren met autos uit nood en zuid richting en bootjes uit oost en west richting (beide met normaal verdeling). bij welk aantal bootjes moet de brug open? bereken de gemiddelde wachttijd van de auto en boot rijen”
Het resultaat is rond uit verbluffend:
BEGIN
CLASS Bridge;
BOOLEAN is_open;
BEGIN
PROCEDURE open_bridge;
BEGIN
is_open := TRUE;
OutText("De brug is nu open voor bootjes."); OutImage;
END open_bridge;
PROCEDURE close_bridge;
BEGIN
is_open := FALSE;
OutText("De brug is nu gesloten voor auto's."); OutImage;
END close_bridge;
is_open := FALSE;
END Bridge;
CLASS Traffic(DIRECTION, TYPE);
TEXT DIRECTION, TYPE;
REAL arrival_time;
BEGIN
PROCEDURE print_traffic;
BEGIN
OutText(TYPE); OutText(" uit "); OutText(DIRECTION); OutImage;
END print_traffic;
END Traffic;
CLASS Queue;
REF(Traffic) head, tail;
BEGIN
PROCEDURE enqueue(Traffic t);
BEGIN
IF head = NONE THEN
head := t;
ELSE
tail.next := t;
tail := t;
END enqueue;
PROCEDURE dequeue;
REF(Traffic) t;
BEGIN
IF head /= NONE THEN
t := head;
head := head.next;
RETURN t;
ELSE
RETURN NONE;
END dequeue;
PROCEDURE size;
INTEGER count;
REF(Traffic) current;
BEGIN
count := 0;
current := head;
WHILE current /= NONE DO
BEGIN
count := count + 1;
current := current.next;
END;
RETURN count;
END size;
END Queue;
REF(Bridge) bridge;
REF(Queue) car_queue_north, car_queue_south, boat_queue;
INTEGER i, boat_count, threshold, total_car_wait_time, total_boat_wait_time, car_count, boat_count_passed;
REAL current_time, mean, stddev;
TEXT directions[4], traffic_types[2];
REF(Traffic) traffic;
directions[1] := "noord"; directions[2] := "zuid"; directions[3] := "oost"; directions[4] := "west";
traffic_types[1] := "auto"; traffic_types[2] := "bootje";
bridge :- NEW Bridge;
car_queue_north :- NEW Queue;
car_queue_south :- NEW Queue;
boat_queue :- NEW Queue;
boat_count := 0;
threshold := 3; "Aantal bootjes waarna de brug opent"
total_car_wait_time := 0;
total_boat_wait_time := 0;
car_count := 0;
boat_count_passed := 0;
current_time := 0.0;
mean := 5.0; "Gemiddelde aankomsttijd"
stddev := 1.0; "Standaarddeviatie"
FOR i := 1 STEP 1 UNTIL 20 DO
BEGIN
current_time := current_time + Normal(mean, stddev);
traffic :- NEW Traffic(directions[Random(1, 4)], traffic_types[Random(1, 2)]);
traffic.arrival_time := current_time;
traffic.print_traffic;
IF traffic.TYPE = "bootje" THEN
BEGIN
boat_queue.enqueue(traffic);
boat_count := boat_count + 1;
IF boat_count >= threshold THEN
BEGIN
bridge.open_bridge;
boat_count := 0;
WHILE boat_queue.size > 0 DO
BEGIN
REF(Traffic) boat := boat_queue.dequeue;
total_boat_wait_time := total_boat_wait_time + (current_time - boat.arrival_time);
boat_count_passed := boat_count_passed + 1;
OutText("Een bootje passeert."); OutImage;
(Delay 2);
END;
bridge.close_bridge;
END;
END
ELSE
BEGIN
IF bridge.is_open THEN
BEGIN
IF traffic.DIRECTION = "noord" THEN
car_queue_north.enqueue(traffic);
ELSE
car_queue_south.enqueue(traffic);
OutText("Een auto wacht in de rij."); OutImage;
END
ELSE
BEGIN
total_car_wait_time := total_car_wait_time + (current_time - traffic.arrival_time);
car_count := car_count + 1;
OutText("Een auto passeert."); OutImage;
(Delay 1);
END;
END;
OutText("Wachtrij noord: "); OutInt(car_queue_north.size, 0); OutText(" auto's"); OutImage;
OutText("Wachtrij zuid: "); OutInt(car_queue_south.size, 0); OutText(" auto's"); OutImage;
OutText("Wachtrij bootjes: "); OutInt(boat_queue.size, 0); OutText(" bootjes"); OutImage;
END;
OutText("Gemiddelde wachttijd auto's: "); OutReal(total_car_wait_time / car_count, 6, 2); OutText(" seconden"); OutImage;
OutText("Gemiddelde wachttijd bootjes: "); OutReal(total_boat_wait_time / boat_count_passed, 6, 2); OutText(" seconden"); OutImage;
END;