home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 May / PCFMay2001.iso / Xenon / C++ / FreeCommandLineTools.exe / Examples / StdLib / icecream.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-31  |  6.7 KB  |  257 lines

  1. #include "stlexam.h"
  2. #pragma hdrstop
  3. /**************************************************************************
  4.  *
  5.  * icecream.cpp - priority queue example program. Section 11.3.1
  6.  *
  7.  ***************************************************************************
  8.  *
  9.  * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
  10.  * ALL RIGHTS RESERVED
  11.  *
  12.  * The software and information contained herein are proprietary to, and
  13.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  14.  * intends to preserve as trade secrets such software and information.
  15.  * This software is furnished pursuant to a written license agreement and
  16.  * may be used, copied, transmitted, and stored only in accordance with
  17.  * the terms of such license and with the inclusion of the above copyright
  18.  * notice.  This software and information or any other copies thereof may
  19.  * not be provided or otherwise made available to any other person.
  20.  *
  21.  * Notwithstanding any other lease or license that may pertain to, or
  22.  * accompany the delivery of, this computer software and information, the
  23.  * rights of the Government regarding its use, reproduction and disclosure
  24.  * are as set forth in Section 52.227-19 of the FARS Computer
  25.  * Software-Restricted Rights clause.
  26.  * 
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  29.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  30.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  31.  * P.O. Box 2328, Corvallis, Oregon 97339.
  32.  *
  33.  * This computer software and information is distributed with "restricted
  34.  * rights."  Use, duplication or disclosure is subject to restrictions as
  35.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  36.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  37.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  38.  * then the "Alternate III" clause applies.
  39.  *
  40.  **************************************************************************/
  41.  
  42. #include <vector>
  43. #include <queue>
  44.  
  45. #ifdef _RW_STD_IOSTREAM
  46. #include <iostream>
  47. #else
  48. #include <iostream.h>
  49. #endif
  50.     
  51. #ifndef _RWSTD_NO_NAMESPACE
  52. using namespace std;
  53. #endif
  54.  
  55. //
  56. // Execution event in a descrete event driven simulation.
  57. //
  58.  
  59. class event
  60. {
  61.   public:
  62.     //
  63.     // Construct sets time of event.
  64.     //
  65.     event (unsigned int t) : time(t) { };
  66.     //
  67.     // Time is a public data field.
  68.     //
  69.     const unsigned int time;
  70.     //
  71.     // Execute event my invoking this method.
  72.     //
  73.     virtual void processEvent() = 0;
  74. };
  75.  
  76. //
  77. // Needed by some compilers.
  78. //
  79. inline void __destroy (event **) {}
  80.  
  81. struct eventComparison
  82. {
  83.     bool operator () (const event * left, const event * right)
  84.         { return left->time > right->time; }
  85. };
  86.  
  87. //
  88. // Framework for discrete event-driven simulations.
  89. //
  90.  
  91. class simulation
  92. {
  93.   public:
  94.     simulation () : eventQueue(), time(0) {}
  95.     void run ();
  96.     unsigned int time;
  97.     void  scheduleEvent (event * newEvent) { eventQueue.push(newEvent); }
  98.   protected:
  99.     priority_queue<event*, vector<event *,allocator<event*> >, eventComparison > eventQueue;
  100. };
  101.  
  102. void simulation::run ()
  103. {
  104.     while (! eventQueue.empty())
  105.     {
  106.         event * nextEvent = eventQueue.top();
  107.         eventQueue.pop();
  108.         time = nextEvent->time;
  109.         nextEvent->processEvent();
  110.         delete nextEvent;
  111.     }
  112. }
  113.  
  114. //
  115. //  Ice cream store simulation.
  116. //
  117.  
  118. class storeSimulation : public simulation
  119. {
  120.   public:
  121.     storeSimulation() : freeChairs(35), profit(0.0), simulation() { }
  122.         
  123.     bool canSeat (unsigned int numberOfPeople);
  124.     void order   (unsigned int numberOfScoops);
  125.     void leave   (unsigned int numberOfPeople);
  126.     //
  127.     // Data fields.
  128.     //
  129.     unsigned int freeChairs;
  130.     double       profit;  
  131. } theSimulation;
  132.  
  133. class arriveEvent : public event
  134. {
  135.   public:
  136.     arriveEvent (unsigned int time, unsigned int groupSize)
  137.         : event(time), size(groupSize) { }
  138.     virtual void processEvent();
  139.   private:
  140.     unsigned int size;
  141. };
  142.  
  143. class orderEvent : public event
  144. {
  145.   public:
  146.     orderEvent (unsigned int time, unsigned int groupSize)
  147.         : event(time), size(groupSize) { }
  148.     virtual void processEvent();
  149.   private:
  150.     unsigned int size;
  151. };
  152.  
  153. class leaveEvent : public event
  154. {
  155. public:
  156.     leaveEvent (unsigned int time, unsigned int groupSize)
  157.         : event(time), size(groupSize) { }
  158.     virtual void processEvent();
  159. private:
  160.     unsigned int size;
  161. };
  162.  
  163. //
  164. // Return random integer between 0 and n.
  165. //
  166.  
  167. int irand (int n) { return (rand()/10) % n; }
  168.  
  169. void arriveEvent::processEvent ()
  170. {
  171.     if (theSimulation.canSeat(size))
  172.         theSimulation.scheduleEvent(new orderEvent(time + 1 + irand(4), size));
  173. }
  174.  
  175. void orderEvent::processEvent ()
  176. {
  177.     //
  178.     // Each person orders some number of scoops.
  179.     //
  180.     for (int i = 0; i < size; i++)
  181.         theSimulation.order(1 + irand(4));
  182.     //
  183.     // Then we schedule the leave event.
  184.     //
  185.     theSimulation.scheduleEvent(new leaveEvent(time + 1 + irand(10), size));
  186. }
  187.  
  188. void leaveEvent::processEvent () { theSimulation.leave(size); }
  189.  
  190. //
  191. // If sufficient room then seat customers.
  192. //
  193.  
  194. bool storeSimulation::canSeat (unsigned int numberOfPeople)
  195. {
  196.     cout << "Time: " << time;
  197.     cout << " group of " << numberOfPeople << " customers arrives";
  198.     if (numberOfPeople < freeChairs)
  199.     {
  200.         cout << " is seated" << endl;
  201.         freeChairs -= numberOfPeople;
  202.         return true;
  203.     }
  204.     else
  205.     {
  206.         cout << " no room, they leave" << endl;
  207.         return false;
  208.     }
  209. }
  210.  
  211. //
  212. // Service icecream, compute profits.
  213. //
  214.  
  215. void storeSimulation::order (unsigned int numberOfScoops)
  216. {
  217.     cout << "Time: " << time;
  218.     cout << " serviced order for " << numberOfScoops << endl;
  219.     profit += 0.35 * numberOfScoops;
  220. }
  221.  
  222. //
  223. // People leave, free up chairs.
  224. //
  225.  
  226. void storeSimulation::leave (unsigned int numberOfPeople)
  227. {
  228.     cout << "Time: " << time;
  229.     cout << " group of size " << numberOfPeople << " leaves" << endl;
  230.     freeChairs += numberOfPeople;
  231. }
  232.  
  233. int main ()
  234. {
  235.     cout << "Ice Cream Store simulation from Chapter 9"  << endl;
  236.     //
  237.     // Load queue with some number of initial events.
  238.     //
  239.     unsigned int t = 0;
  240.     while (t < 20)
  241.     {
  242.         t += irand(6);
  243.         cout << "pumping queue with event " << t << endl;
  244.         theSimulation.scheduleEvent(new arriveEvent(t, 1 + irand(4)));
  245.     }
  246.     //
  247.     // Run the simulation.
  248.     //
  249.     theSimulation.run();
  250.     cout << "Total profits " << theSimulation.profit << endl;
  251.     
  252.     cout << "End of ice cream store simulation" << endl;
  253.  
  254.     return 0;
  255. }
  256.     
  257.