This assignment is a continuation of the last one; you will be extending your last assignment to a more useful and more interesting simulation.
The assignment has a number of parts. The order of the parts below is reasonable but not necessarily the order in which you should do the implementation — you may defer working on a part that appears earlier in the list to work on one that appears later in the list.
In Assignment 2, you had the option of handling errors by printing messages at the point of detection. Make the implementation use exceptions as covered in class, using the standard error (stderr or cerr) as your logging mechanism.
The Activity Manager allows creation and deletion of activity objects. When running, it chooses the appropriate next activity and executes it.
Virtual time should be stepped through using hours as the time unit.
Use the double-precision floating-point type for the representation of
hours. Just be sure to understand the idiosyncrasies of floating-point
numbers, and avoid mistakes such as testing for equality or inequality
(==, !=) between the numbers.
When a shipment arrives on a segment, an attribute-based notification causes an activity to be enqueued. The activity delays for the proper amount of time and then uses a timeout notifiee to indicate that the shipment has been delivered and the segment carrier is free to transport again.
A shipment has the following characteristics:
A location that receives a shipment acts according to the location type:
How does a location decide where next to send a shipment? You may use any scheme you like. One straightforward approach that we suggest is a route table that uses a spanning tree of every location to determine a route for any shipment. Mention your scheme in your README file.
Every segment has an outgoing capacity, which is a fixed size. If the segment is at its full capacity and a new shipment arrives, the location will refuse delivery.
For this assignment, we will only account for virtual time associated with carrying a shipment along a segment, and we assume that transfer at a segment and determination of a route takes no virtual time.
As an example of calculating the virtual time for carrying a shipment: if a shipment consisting of 200 packages is to be sent over a 400-mile segment using trucks capable of 50 packages and operating at 80 mph, it takes (400 miles)/(80 mph)=5 hours to send 50 packages, so you can assume that it takes (5 hours)×(200/50)=20 hours to send 200 packages.
Finally, you must somehow inject shipments into the simulation and collect statistics for them. To this end, you must extend the attributes supported by instances of type Customer and any segment type.
The real-time activity manager shall be used to advance the virtual time; that is, the advancement of the clock for your virtual-time Activity Manager is an activity from the point of view of your real-time Activity Manager.
The real-time activity manager should advance the virtual time with a scaling factor; for example, one second of the real time (wallclock time) per hour of the virtual time.
Like the virtual activity manager, this Activity Manager also allows creation and deletion of activity objects. When running, it chooses the appropriate Activity object at the appropriate time and executes it.
Construct a shipping network with at least four locations, and confirm that shipments move between them as expected. Add a diagram of this network to your README file, and discuss the tests performed. The code for this client should be named verification.cpp.
In addition, set up a shipping network with 100 sources and 1 destination. The destination should be connected to a terminal, which is in turn connected to 10 terminals, each of which is connected to 10 sources. All connections are via truck segments. Have each source send shipments holding 100 packages to the destination at the normal truck speed. Run the simulation for a while.
Now, reset the simulation and do the same thing, but vary the shipment sizes (use a randomly chosen shipment size for each source) from 1 package to 1,000 packages. Record the results for this case.
Discuss in your README file the level of shipment delivery refusal observed in each case. The client implementing this test should be submitted as experiment.cpp.
(optional; for extra credit) Give ideas (in your README) for experiments that you think would be interesting, and implement them. Some extension topics include: sophisticated routing schemes that take into account segment speeds and shipping traffic, receipt acknowledgment, and redelivery requests, methods to handle burstiness of the traffic, terminal latency modeling, experimenting with different network topologies, maintaining a trace route in the shipment structure to be used with probe shipments to determine least congested routes, and random variations in segment performance. You are not limited to this list.
The string values from Assignment 2 continue to be a contract between the rep layer and the client. However, we must add some new strings to provide the extra functionality for this assignment.
How you implement your simulation is completely up to you, however, here are some guidelines which may be helpful to get you started.
A customer location should only begin sending shipments once all 3 of the source attributes have been set. A reactor (CustomerReactor) for customer locations that receives notification on "Transfer rate" "Shipment size" and "Destination" would be ideal here. Once all 3 attributes have been set, the customer location should create a new Activity (InjectActivityReactor) that injects shipments into customer location.
Each location could also have a reactor (LocationReactor) that receives notification on when a shipment arrives, either by the inject activity or from a forward activity. This reactor should find the best segment to enqueue the shipment onto. A segment could also have another reactor (SegmentReactor) that creates and schedules a forwarding activity if necessary.
A forwarding activity (ForwardActivityReactor) should try to forward a shipment to the next location. If there are any additional Shipments left on the queue, the ForwardActivityReactor should automatically reschedule itself for the next execution.
Also, you can find source code examples of how to use the Notifiee and Activity interface here. You may use as much or as little code from these examples in your assignment as you wish.
Start from the code you developed for Assignment 2, and known issues with that code before going forward. You are encouraged to use the following files located in the assignment source directory for Parts 2 and 4:
Submit the assignment using the /usr/class/cs249a/bin/submit program. Your submission must include the following:
You many re-submit as many times as you like. If you re-submit a file, the new version will overwrite the old one.