Solved

# Waiting room sim. program help.

Posted on 2005-02-26
Medium Priority
317 Views
I'm trying to write a simulation with some statistical/metric information. The simulation goes as follow. It's a waiting room simulation. There will be one entrace will ppl wait in line to be seated in a room and en exit door when people to go the doctor's room (enter door and exit door will be at opposite end of this system. The waiting room will have about 10 chairs (two rows of five chairs each). When the ppl waiting in line goes into the waiting room, they look for an empty chair to sit randomly. If there are no empty seats, they will continue to wait until there's an empty seat and sit. Once everyone in line (queue) have all been in the waiting room, sat down, and leave. The system of the simulation ends.

Some of my state variables:
# of people waiting to be serve.
# of seats.
-arrival rate of people entering
-Range of how long ppl sit in seconds.
-Rate at which exit door will allow the people to leave (in seconds).

Each user waiting in line (queue) to find a sit will be assigned a random number (the seat). They will have time associated with them to from entering the door to finding a seat, the time they have seat, and the time from getting off the seat to exit.

Some data I want to keep track of:

1) Time each person spent in the system (waiting in line and seated),
2) # of ppl in entrance and exit queue, number of cars "seated"
3) average time in each queue,
4) average time a car is parked, etc.

I know I can write a queue of nodes. The queue will contain number of people waiting in line to be seated, with nodes containing info. about a user time spent waiting in line, time to get to the seat, time seated, time to leave, and the total time in the system.

- How would I write one when all the seats are full and the user has to wait? ex. "if seats are full, then user time increase. when one seat chair becomes empty, user takes a seat and the time gets recorded, etc, etc"?

Can someone help me with the pseudo-code and ideas on this, and especially help me with how to keep track of the data (1-4)?
0
Question by:identityless
• 3

LVL 1

Expert Comment

ID: 13413054
Hi do you need to come up with your program or ur main concern is just the datas and simulation ? If it is the later maybe u can try those simulation softwares that are available online such as Arena ? It will simulate the datas by the distribution models that are tagged to the entities..
0

LVL 7

Expert Comment

ID: 13417133
One approach is using a global 'time':

unsigned long seconds = 0;

Have a "think function" for every 'intelligent' object:

/* NOTE: I'm using the '::' notation somewhat generally, this is pseudo-code */
Chair::think(unsigned long time)
{
if (time >= Chair::GetLastSeatingTime() + Chair::MaximumSeatingTime) {
Person = Chair::GetSittingPerson();
Person::StandUp();
}
}

and call the think() function for every intelligent object every second:

for (int i=0; i<=120; ++i) /* Run the simulation for 2 minutes */
for (each object)
object.think(i);

(Note how >= for comparing time is really unnecessary since every think function will be called every second)

Another example:

Person::think(unsigned long time)
{
if (timeLastSatDown - time == 900) /* When I've sat for 15 minutes... */
Person::GotBored(); /* ...I get bored */
}

Keeping track of data is easy this way, when you process the whole thing one frame at a time.
0

Author Comment

ID: 13422844
How would I find the avg. time each person spend in the queue (line)? I will have a queue for the waiting line and I know that the last person will take a longer time than the eariler people. How would I give a pseduo-code for the 1st person in the queue having a short waiting time and then in the end, the last person has a longer waiting time? For the avg. waiting time, I just add the total number of waiting time for all persons divided by number of people waited in the total system, correct?

- Assuming time when a person enters the waiting room, all the seats are occupied. I suppose a object.UserSeatingTime() increases until a space is available, correct? This is where I'm stuck on the coding part where the seats are full (assuming the people take a long time to seat) and a new user spents time looking for a seat. Can you help me with this part?

- Another problem I have is, only one person is allow to leave at a time (other people may be ahead). How would I prevent collison in timing?

Thanks!
0

LVL 7

Expert Comment

ID: 13433598
>For the avg. waiting time, I just add the total number of waiting time for all persons divided by number of people waited in the total system, correct?

That is the definition of "average" :).

>I suppose a object.UserSeatingTime() increases until a space is available, correct?
UserSeatingTime() would increase for every frame that the user would be sitting:

object.Think() /* called every frame */
{
seatingTime++;
}

Or, you could just record the frame # they sat down on and the one they stood up on, the difference would give the number of frames they've been sitting.

>- Another problem I have is, only one person is allow to leave at a time (other people may be ahead). How would I prevent collison in timing?

Very simple when you work with single frames and think functions:
person.Think()
{
if (I have to leave)
IWantToLeave = true;

if (IWantToLeave == true)
if (exitQueueFull == false))
leave...
else
can't leave...
}

The good thing about running a simulation frame by frame is that you don't run into synchronization problems. Here is an example:

One person has sat down on frame #4 and will want to leave after sitting for 6 frames.
Another person has sat down on frame #5 and will want to leave after 5 frames.
Only one person can be leaving at any given time, a person takes 3 frames to leave.
It is frame #10, both persons want to leave at this time. Both their think functions are called, in a certain order:

Person1.think() {
if (sitStart + sitMax == frame) /* 4+6=10 so this will eval to true */
Person1.wantToLeave = true;
}

Person2.think() {
if (sitStart + sitMax == frame) /* 5+5=10 so this will eval to true */
Person2.wantToLeave = true;
}

/* At this point, both people want to leave */

Person2.thinkLeave() { /* second think function, you can have as many as you want */
if (Person2.wantToLeave) { /* evals to true, was set in the previous think function */
if (exitQueue.Full()) { /* false, noone leaving yet */
/* do nothing */
} else {
exitQueue.Add(Person2); /* Ahh, we can leave now */
}
}
}

Person1.thinkLeave() {
if (Person2.wantToLeave) { /* true, was set in the previous think function */
if (exitQueue.Full()) { /* sadly, false, because Person2 was added to the queue in Person2.thinkLeave() */
/* do nothing */
} else {
}
}
}

Can you see how there would never be a collision unless Person1.thinkLeave() and Person2.thinkLeave() were called at the exact same time? For there to be a collision, you would have to use multithreading, but our current implementation waits for one person to finish thinking before calling another one:

for(i=0; i<MAX_PERSONS; i++) {
Person[i].think();
Person[i].thinkLeave();
}

or

/* Stage 1 */
for(i=0; i<MAX_PERSONS; i++)
Person[i].think();

/* Stage 2 */
for(i=0; i<MAX_PERSONS; i++)
Person[i].thinkLeave();

(Actually, using two think functions is redundant, you could merge the functions and still not get any collisions.)
0

LVL 7

Accepted Solution

aib_42 earned 1000 total points
ID: 13433738
How about a more general approach?

Person.Think()
{
if (Person.state == WAITING_TO_SEAT) {

if (seats are available)
Person.sit();
else
Person.waitingToSitTime++;

} else if (Person.state == SITTING) {

Person.sittingTime++;

if (Person.sittingTime == MAX_SITTING_TIME)
Person.state = WAITING_TO_LEAVE;

} else if (Person.state == WAITING_TO_LEAVE) {

if (exit available)
Person.leave();
else
Person.waitingToLeaveTime++

} else if (Person.state == LEAVING) {

Person.leavingTime++;

}
}

Of course, you should take some things into consideration: If a person, on frame #0, is waiting to sit, and a seat is available, and he sits down; then on the beginning of frame #1, before the think function is called, do you want his sitting time to be 0 or 1? What about his 'waiting to sit' time? These are important things to consider, but the solutions are trivial: just move some ifs/elses around. The good thing is, you don't have to worry about synchronization.

It may be easier to have one intelligent object for the beginning. Things might get complicated if you call the think functions of the queues first, which may update a person's states or times, and then call the think functions of the persons, not knowing if the states or times were already altered by the queues' think functions, etc, etc...
It's easier for the person to add himself to a queue or seat himself on a seat in his own think function rather than having queues and seats that can think and would do these things for the persons themselves.

I hope I am not complicating things, this is really a very easy approach once you get used to it. (And it can be used to simulate any real situation.)
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
###### Suggested Courses
Course of the Month8 days, 10 hours left to enroll