Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 1 of 1

Thread: Single-thread Pizza Parlor Simulation

  1. #1
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    7,104
    My Mood
    Mellow
    Thanks
    277
    Thanked 859 Times in 842 Posts

    Default Single-thread Pizza Parlor Simulation

    While this project uses mostly basic Java concepts and tools, the tools are used in an advanced way that raises the level to slightly above basic, perhaps to the intermediate level. The project uses a single-thread to simulate the operation of a pizza parlor. The simulation was inspired by this thread.

    The code below is heavily commented so that further explanation should be unnecessary, but to prevent you reading the code to determine what it is or does, here's a summary copied from the existing comments:

    demonstrates the use of a queue to accomplish events in simulation time
    rather than real or scaled time. multi-threading is not used, because this
    simulation is intended to be a precursor to a multi-threaded program, and
    more than a single thread is not needed

    concept: events are added to a queue ordered by their start times,
    priorities, and event numbers. the simulation time begins at zero and
    advances to each event's start time as the event is removed from the queue
    and processed. as each event is processed, its start time and priority are
    modified to reflect the next action and then returned to the queue if the
    event is still in play or removed if it is not

    Also noted in the comments is that the posted code will not run without the missing Event and OrderedEventQueue classes. The Event class implements Comparable to define the ordering of Event objects and is otherwise unremarkable. Even simpler is the OrderedEventQueue class that extends an ArrayList so that 3 simple methods could be added to both control and inspect the objects in the queue.

    Questions/comments welcome.
    import java.util.ArrayList;
    import java.util.Random;
     
    /**
     * File: PizzaParlorSimulation.java
     * Author: GregBrannon, April 2014
     *
     * inspired by this thread:
     * 
     * [url]http://www.javaprogrammingforums.com/whats-wrong-my-code/36975-elevator-simulation-event-time-not-clock.html#post144786[/url]
     *
     * demonstrates the use of a queue to accomplish events in simulation time
     * rather than real or scaled time. multi-threading is not used, because this
     * simulation is intended to be a precursor to a multi-threaded program, and
     * more than a single thread is not needed
     *
     * simulation rules, assumptions, etc.
     * - the simulation has 4 events: order, prepare, cook, and remove.
     * - each pizza order is an Event (my custom Event class) that is modified to
     *   be each of the other events as the simulation proceeds 
     * - the first pizza is ordered at time zero
     * - each subsequent pizza order arrives at intervals of 2 to 5 (inclusive)
     *       time units
     * - a pizza order event is assigned a random queue time of at least
     *       5 time units to a maximum of 8 time units 
     * - pizza preparation time is a random number of time units between 8 and 15
     * - the simulation will run for the number MAX_PIZZAS
     * - the time to bake a pizza is randomly chosen between 20 and 30 (inclusive)
     *       time units
     * - 4 pizzas can be cooking at once (set by the variable ovenSpace)
     * 
     * to avoid providing a total solution, the posted simulation code omits my
     * custom Event and OrderedEventQueue classes. ask for help if needed to
     * construct your own versions of these classes. the requirements
     * for both classes should be derivable from the posted code, except for the
     * queue's insertInOrder() method and the Event's compareTo() method that
     * it depends on. if there's any secret sauce, it's in those two methods
     * 
     * concept: events are added to a queue ordered by their start times,
     * priorities, and event numbers. the simulation time begins at zero and
     * advances to each event's start time as the event is removed from the queue
     * and processed. as each event is processed, its start time and priority are
     * modified to reflect the next action, and then returned to the queue or
     * removed, if the event has completed the final action
     * 
     * TODO add the option to specify the number of pizzas that can be in the
     * oven at a time by varying the variable ovenSpace
     */
    public class PizzaParlorSimulation
    {
        // instance variables
        private final boolean TEST;
        private int currentSimTime;
        private int orderNumber;
        private int pizzasInOven;
        private int ovenSpace;
        private int pizzasDelivered;
        private final int MAX_PIZZAS;
        private boolean acceptingOrders;
        private OrderedEventQueue<Event> orderedEventQueue;
        private Random random;
        private Event newEvent;
     
        // default constructor - used to initialize instance variables and then
        // start the simulation
        public PizzaParlorSimulation()
        {
            // a flag to indicate whether the simulation should run in the test
            // or production modes
            TEST = false;
     
            // initialize instance variables
            currentSimTime = 0;
            orderNumber = 0;
            pizzasInOven = 0;
            ovenSpace = 4;
            pizzasDelivered = 0;
            orderedEventQueue = new OrderedEventQueue<Event>();
            random = new Random( System.currentTimeMillis() );
            MAX_PIZZAS = 40;
            acceptingOrders = true;
     
            // start the simulation of ordering and baking pizzas
            makePizzaPies();
     
        } // end default constructor
     
        // a controller for the pizza demo
        private void makePizzaPies()
        {
            // continue the simulation until event queue is empty
            do
            {
                // add another pizza order to the queue if the simulation is still
                // accepting orders
                if ( acceptingOrders )
                {
                    orderPizza();
                }
     
                // retrieve the next event from the event queue and process it,
                // updating the current simulation time with the event's start time
                processNextEvent();
     
                reportStatus();
            }
            while ( !orderedEventQueue.isEmpty() );
     
        } // end method makePizzaPies()
     
        // creates a pizza order event and adds it to the queue. prints a message
        // if the maximum number of orders have been accepted
        public void orderPizza()
        {
            // the first the pizza order arrives in the queue at time zero
            int eventStartTime = 0;
     
            // only allow number of pizza orders defined by MAX_PIZZAS
            if ( orderNumber < MAX_PIZZAS )
            {
                // in test mode, report the status of the simulation
                if ( TEST )
                {
                    System.out.println( "Pizza order #" + orderNumber +
                            " is being accepted" );
                }
     
                // determine the pizza order's details
                // the start time for all pizzas after the first is the current
                // event time plus a random number between 2 and 5, inclusive
                if ( orderNumber > 0 )
                {
                    eventStartTime = currentSimTime + random.nextInt( 4 ) + 2;
                }
     
                // the rest of the order's attributes . . .
                String eventName = "OrderPizza" + orderNumber;
                int eventNumber = orderNumber++;
     
                // set the time to process the order (minimum queue time)
                // a random number between 5 and 8
                int eventDuration = random.nextInt( 4 ) + 5;
     
                // the queue time for events is orderWaitTime + ovenWaitTime and
                // then increases each time the event must wait for a spot in the
                // oven
                int eventQueueTime = eventDuration;
     
     
                // the following is not used at the order stage
                // TODO (or at all yet)
                int eventEndTime = 0;
     
                // create the order and add it to the queue in order
                newEvent = new Event( eventName, eventNumber, eventStartTime,
                        eventDuration, eventQueueTime, eventEndTime );
     
                // set the new event's priority to 3 (the highest)
                newEvent.setEventPriority( 3 );
     
                orderedEventQueue.insertInOrder( newEvent );
            }
            else
            {
                System.out.
                println( "The pizza parlor is not accepting more orders." );
                acceptingOrders = false;
            }
     
        } // end method orderPizza()
     
        // retrieves the next event from the queue and processes it
        private void processNextEvent()
        {
            Event nextEvent = null;
     
            // take the first event from the queue
            if ( !orderedEventQueue.isEmpty() )
            {
                nextEvent = orderedEventQueue.remove( 0 );
            }
            else
            {
                System.out.println( "Simulation complete!" );
                return;
            }
     
            // advance the current time to the event's start time
            // (this will be zero for the first event but will advance after that)
            currentSimTime = nextEvent.getEventStartTime();
     
            // a message to monitor progress 
            System.out.println( "The name of the event being processed is: " +
                    nextEvent.getEventName() );
     
            // if the event is an order . . .
            if ( nextEvent.getEventName().startsWith( "Order" ) )
            {
                // a message to monitor progress in TEST mode
                if ( TEST )
                {
                    System.out.println( "Assembling pizza # " +
                            nextEvent.getEventNumber() + " before cooking at time " +
                            currentSimTime );
                }
     
                // set the time to prepare the pizza for the oven (build the pizza)
                // a random number between 8 and 15
                nextEvent.setEventDuration( random.nextInt( 7 ) + 8 );
     
                // add the next queue time to the total event queue time
                nextEvent.setEventQueueTime( nextEvent.getEventQueueTime() +
                        nextEvent.getEventDuration() );
     
                // set up the event to for its next step
                nextEvent.setEventName( "CookPizza" + nextEvent.getEventNumber() );
     
                // set the new event's priority to 2 (the middle)
                newEvent.setEventPriority( 2 );
     
                // set this event's next start time as the current time plus the
                // event's duration.  setting the event start time is the key to
                // simulating correctly
                nextEvent.setEventStartTime( currentSimTime + 
                        nextEvent.getEventDuration() );
     
                // return the event to the queue
                orderedEventQueue.insertInOrder( nextEvent );
            }
            // . . . or if it is to cook the pizza . . .
            else if ( nextEvent.getEventName().startsWith( "Cook" ) )
            {
                // this step is limited by the amount of oven space. to make the
                // simulation interesting, the user could be asked how many pizzas
                // can be cooked at a time before the simulation begins. the default
                // value is four, but that can be increased to see the effect of
                // cooking space to complete the desired number of pizzas
                if ( pizzasInOven < ovenSpace )
                {
                    // a message to monitor progress in TEST mode
                    if ( TEST )
                    {
                        System.out.println( "Moving pizza # " +
                                nextEvent.getEventNumber() +
                                " into the oven at time " + currentSimTime );
                    }
     
                    // set the time to cook the pizza, a random number between
                    // 20 and 30
                    nextEvent.setEventDuration( random.nextInt( 11 ) + 20 );
     
                    // add the next queue time to the total event queue time
                    nextEvent.setEventQueueTime( nextEvent.getEventQueueTime() +
                            nextEvent.getEventDuration() );
     
                    // set up the event to for its next step
                    nextEvent.setEventName( "RemovePizza" + 
                            nextEvent.getEventNumber() );
     
                    // set the new event's priority to 1 (the lowest)
                    nextEvent.setEventPriority( 1 );
     
                    // set this event's next start time as the current time plus the
                    // event's duration.  setting the event start time is the key to
                    // simulating correctly
                    nextEvent.setEventStartTime( currentSimTime + 
                            nextEvent.getEventDuration() );
     
                    // return the event to the queue
                    orderedEventQueue.insertInOrder( nextEvent );
     
                    // increment the number of pizzas in the oven
                    pizzasInOven++;
                }
                else
                {
                    // a message to monitor progress in TEST mode
                    if ( TEST )
                    {
                        System.out.
                            println( "The oven is full, must wait for room." );
                    }
     
                    // increment the event's start time and return it to the queue
                    nextEvent.setEventStartTime( currentSimTime + 1 );
     
                    // increment the event's total queue time
                    nextEvent.
                        setEventQueueTime( nextEvent.getEventQueueTime() + 1 );
     
                    orderedEventQueue.insertInOrder( nextEvent );
                }
            }
            // . . . or, finally, to remove the pizza from the oven . . .
            else if ( nextEvent.getEventName().startsWith( "Remove" ) )
            {
                // a message to monitor progress 
                System.out.println( "Removing pizza # " +
                        nextEvent.getEventNumber() + " from the oven at time " +
                        currentSimTime );
     
                // set the event's end time
                nextEvent.setEventEndTime( currentSimTime );
     
                // decrement the number of pizzas in the oven
                pizzasInOven--;
     
                // increment the number of pizzas delivered
                pizzasDelivered++;
            }
     
        } // end method processNextEvent()
     
        // report current simulation time, total pizzas ordered, total pizzas
        // delivered, pizza orders in queue, waiting for oven, in oven, total
        // queue time
        private void reportStatus()
        {
            /* this is a more compact message used to monitor the sim's progress
             * while debugging */
            if ( TEST )
            {
                System.out.println( "The current eventNumber:startTime:priority"
                        + ":duration of the events in the queue is: " );
                for ( int i = 0 ; i < orderedEventQueue.size() ; i++ )
                {
                    System.out.print( orderedEventQueue.get( i ).
                            getEventNumber() + ":" );
                    System.out.print( orderedEventQueue.get( i ).
                            getEventStartTime() + ":" );
                    System.out.print( orderedEventQueue.get( i ).
                            getEventPriority() + ":" );
                    System.out.print( orderedEventQueue.get( i ).
                            getEventDuration() + ", " );
                }
     
                System.out.println();
            }
     
            // TODO total queue time is a snapshot of the queue time for all events
            // currently in queue. further coding will be required to accumulate
            // all queue time that occurred during the entire simulation. care will
            //be required to ensure that queue time is not double counted
     
            else
            {
                // report the simulation's current results
                System.out.println( "\nAt simulation time: " + currentSimTime + 
                        ", the status is:" );
                System.out.println( "Total pizzas ordered: " + orderNumber );
                System.out.println( "Total items in the queue: " +
                        orderedEventQueue.size() );
                System.out.println( "Total pizzas waiting for the oven: " +
                        orderedEventQueue.getNumberOfEventsWithPriority( 2 ) );
                System.out.println( "Total pizzas in oven: " + pizzasInOven );
                System.out.println( "Total pizzas delivered: " + pizzasDelivered );
                System.out.
                    println( "Total queue time of events currently in queue: " + 
                        orderedEventQueue.getTotalQueueTime() );
            }
     
    } // end method reportStatus()
     
        // a main method to simply start the application
        public static void main( String[] args )
        {
            new PizzaParlorSimulation();
     
        } // end main() method
     
    } // end class PizzaParlorSimulation

  2. The Following User Says Thank You to GregBrannon For This Useful Post:

    tofu (January 15th, 2015)


Similar Threads

  1. How to categorise a daemon thread to specific thread in java?
    By rajasekhar_b in forum What's Wrong With My Code?
    Replies: 0
    Last Post: January 10th, 2014, 06:55 AM
  2. pizza parlor orde
    By Mark Paynaganan in forum What's Wrong With My Code?
    Replies: 1
    Last Post: October 20th, 2013, 04:44 AM
  3. Replies: 1
    Last Post: September 24th, 2013, 04:18 PM
  4. java pizza program beginerr
    By nikki101 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: June 17th, 2013, 03:22 AM
  5. Replies: 3
    Last Post: April 11th, 2011, 09:51 PM