Skip to content

pabloc11/CS249A-Assign2

Repository files navigation

user: pabloc11
user: nch25

Name: Pablo Ceballos
Name: Nicholas Hippenmeyer

Compiling: Run 'make' in the top level directory.  This will compile all code, including all client simulation code in the 'test' directory.
Running Simulations: Client simulation code is located in the 'test' directory.  As an example, run 'test/activity' to run the activity test file.

*************************** Index ***************************

1. Introduction
2. Client Interface APIs
		2.1 Code Organization
    2.2 Supported Entities
    2.3 Supported Attributes
    2.4 Creating/Querying a Network
3. Exceptions
    3.1 All Supported Exceptions
    3.2 Handling Exceptions in the client code
4. Running Simulations
    4.1 Virtual Time vs Real Time
    4.2 Scheduled Changes to Fleet Attributes
5. Routing Algorithms
    5.1 Depth First Search
    5.2 Uniform Cost Search
6. Simulation Results
    6.1 Sample Simulation 1
    6.2 Sample Simulation 2
7. Architecture and Design
    7.1 Architecture/Design Decisions
    7.2 Typical Simulation Program Flow

*************************** 1. Introduction ***************************

The purpose of this assignment was to design a library and client interface that could be used to simulate the congestion effects of a shipping business.  Shipments are defined by the client which are then shipped through a network consisting of locations and segments.  Constraints such as transportation speed, difficulty, cost and capacity are imposed to model real-world transportation limitations.  Finally, a simulation is run and statistics are output to the client.

*************************** 2. Client API ***************************

*** 2.1 Code Organization ***

The project top-level directory contains all the header files used to interact with the various layers of the application.  Furthermore, the following subdirectories exist as well:

- fwk (Framework source code)
- engine (Engine layer source code)
- instance (Middle layer source code)
- activity (Activity source code)
- test (Simulation code)

*** 2.2 Supported Entities ***

The following entities exist in the engine layer:

- Segment
	- Truck Segment
	- Boat Segment
	- Plane Segment
- Location
	- Customer Location
	- Port Location
	- Terminal Location
		- Truck Terminal
		- Boat Terminal
		- Plane Terminal
		
In addition, the following classes which subclass directly from the NamedInterface class also exist in the engine layer:

- Network
- Stats
- Fleet
- Connectivity
- Shipment

All of the above classes, with the exception of Shipments can be interacted with from the middle (representation) layer.

*** 2.3 Supported Attributes ***

The following attributes exist for each class accessible through the client API:

Segments:
- "source" (the name of a location where the segment begins)
- "length" (a number representing the length in miles of a segment)
- "return segment" (the name of a segment that represents the reverse direction)
- "difficulty" (a number from 1 to 5 representing the difficulty of a segment)
- "expedite support" ('yes' or 'no' indicating whether the segment supports expedited shipping)
- "capacity" (an integer number representing the number of packages a segment can support)
- "shipments received" (read-only: the number of shipments received by a segment)
- "shipments refused" (read-only: the number of shipments refused by a segment)

Locations:
- "segmentX" (read-only: the Xth segment originating from a location)

Customer Locations:
- "transfer rate" (an integer number of shipments per day supported by a location)
- "shipment size" (an integer number of packages per shipment)
- "destination" (the name of a customer location representing the destination of a shipment)
- "shipments received" (the number of shipments received by a location)
- "average latency" (the average time taken for a shipment to arrive at a location)
- "total cost" (the total cost taken for a shipment to arrive at a location)
			
Stats:
- "Customer" (read-only: the number of customer locations in a network)
- "Port" (read-only: the number of port locations in a network)
- "Truck terminal" (read-only: the number of truck terminals in a network)
- "Boat terminal" (read-only: the number of boat terminals in a network)
- "Plane terminal" (read-only: the number of plane terminals in a network)
- "Expedite percentage" (read-only: the percentage of segments in a network that support expedited shipping)

Fleet:
- "Truck/Boat/Plane, speed" (a number representing the speed of a given mode of transportation)
- "Truck/Boat/Plane, cost" (a number representing the cost of a given mode of transportation)
- "Truck/Boat/Plane, capacity" (an integer number representing the number of packages transportable by a given mode of transportation)
- "Truck/Boat/Plane, speed, scheduled" (the scheduled speed during a further specified time window)
- "Truck/Boat/Plane, cost, scheduled" (the scheduled cost during a further specified time window)
- "Truck/Boat/Plane, capacity, scheduled" (the scheduled capacity during a further specified time window)
- "Start time, scheduled" (the scheduled start time for a fleet's change in attributes: given as a number between 0 and 24)
- "End time, scheduled" (the scheduled end time for a fleet's change in attributes: given as a number between 0 and 24)

Connectivity:
- "routing algorithm" ('dfs' or 'ucs' indicating the algorithm used for routing shipments in a network)
- "explore loc0 : att0 v0 att1 v1 ..." (read_only: as outlined in assignment 2 description)
- "connect loc0 : loc1" (read_only: as outlined in assignment 2 description)

Furthermore, the following class exists only in the middle layer and is used for setting up and running simulations.

Clock:
- "type" ('real' or 'virtual' indicating the type of activity manager used to run a simulation)
- "now" (a number indicating the current time of a simulation)

*** 2.4 Creating/Querying a Network ***

A network is created by running the command:
Ptr<Instance::Manager> manager = shippingInstanceManager();

This creates a manager in the middle layer for creating network entities and running a simulation.  The command "instanceNew(name, entity)" is then called on the manager for creating instance objects in the middle layer and corresponding entities in the engine layer.  These instances can then be referenced by their given name.  The method attributeIs(attr, value) can be called on any instance object as outlined above to set its respective attribute value.

Once a network has been created, any attribute can be queried by calling the attribute(attr) method on an entity.

*************************** 3. Exceptions ***************************

*** 3.1 All Supported Exceptions ***

All errors are handled by printing a detailed error message to stderr and throwing an exception which must be caught at the client layer.  The following exceptions can be throw:

- Fwk::UnknownArgException (thrown when an invalid type-attribute pair is given to an instance object)
- Fwk::EntityNotFoundException (thrown when a entity can't be found by its instance name)
- Fwk::IllegalNameException (thrown when an invalid name is given for an instance object)
- Fwk::NameInUseException (thrown when an instance object is named something that's already in use)
- Fwk::UnknownTypeException (thrown when the type of an instance object is incompatible with an operation)
- Fwk::RangeException (thrown when a value is out of bounds for a given operation)
- Fwk::InternalException (thrown when an internal error has occured)

*** 3.2 Handling Exceptions in the client code ***

The client should handle exceptions by enclosing all code that could generate an exception within a try, catch block.  An example is illustrated below:

try{
  // Any calls to middle layer
}
catch (Fwk::UnknownArgException) {
	// handle unknown argument exception
}
catch (Fwk::EntityNotFoundException) {
	// handle entity not found exception
}
catch (Fwk::IllegalNameException) {
	// handle illegal name exception
}
catch (Fwk::NameInUseException) {
	// handle name in use exception
}
catch (Fwk::UnknownTypeException) {
	// handle unknown type exception
}
catch (Fwk::RangeException) {
	// handle out of range exception
}
catch (Fwk::InternalException) {
	// handle internal exception
}

*************************** 4. Running Simulations ***************************

*** 4.1 Virtual Time vs Real Time ***

Running simulations in virtual time can be accomplished by creating a clock instance (the activity manager type defaults to virtual).  A virtual time activity manager will automatically be created in the middle layer when the a call to instanceNew is made for the first time on the instance manager.  Finally, the simulation can be started by setting the current time on the clock.  To run the simulation for 24 hours, a value of 24 would be used:

Ptr<Instance> clock = manager->instanceNew("clock", "Clock");
clock->attributeIs("now", "24");

To run a simulation in real time, the type 'real' type must be specified on the clock instance:

clock->attributeIs("type", "real");

The scaling factor used is 1s real time : 1hr virtual time.

*** 4.2 Scheduled Changes to Fleet Attributes ***

To specify a time period during which scheduled changes to the fleet's attributes occur, an example of the commands that must be made is shown below:

fleet->attributeIs("Truck, speed", "1");
fleet->attributeIs("Truck, capacity", "1");
fleet->attributeIs("Truck, speed, scheduled", "2");
fleet->attributeIs("Truck, capacity, scheduled", "2");
// any other desired fleet changes
fleet->attributeIs("Start time, scheduled", "10");
fleet->attributeIs("End time, scheduled", "20");

The start and end time represent the beginning and end times in a 24 hour day, respectively.  For the example above, the start time would be 10am and the end time would be 8pm.  After these two times are specified, the activity manager will create an activity to cycle between the normal fleet attributes and the scheduled changes at the given times.

*************************** 5. Routing Algorithms ***************************

The routes between any two customer locations in a network are computed when the 'now' attribute is set on a clock instance.  A routing table is stored for every location in the network as a hash map.  Destination locations are used as the keys with the next segment in the route used as the value.  Whenever a forwarding activity occurs, the outgoing segment from a given location is found by searching for the value (next segment) associated with a given destination.

*** 5.1 Depth First Search ***

The first routing algorithm implemented is depth first search which ignores all paths from a source to a destination that go through a customer location.  This addresses the issue of shipments arriving at customer locations they are not destined for.  

*** 5.2 Uniform Cost Search ***

The second routing algorithm implemented is uniform cost search.  Instead of recursively computing paths between customer locations, it maintains a priority queue of partial paths from a source to a given location in the network sorted by path length.  This guarantees that the shortest path between any two customer locations will be found.  Like the depth first search, we disregard any paths that travel through intermediate customer locations.

*************************** 6. Simulation Results ***************************

*** 6.1 Sample Simulation 1 ***

           Customer 1
         /            \
Truck terminal 1  Truck terminal 2
         \            /
           Customer 2

The following statistics result from running test/verification using segment capacities of 2:

Shipments Received at Customer 2: 2
Average Latency at Customer 2: 6.00
Total Cost at Customer 2: 20.00
Shipments Received at Customer 1: 4
Average Latency at Customer 1: 10.00
Total Cost at Customer 1: 80.00

The following statistics result from running test/verification using segment capacities of 1:

Shipments Received at Customer 2: 2
Average Latency at Customer 2: 10.00
Total Cost at Customer 2: 20.00
Shipments Received at Customer 1: 1
Average Latency at Customer 1: 20.00
Total Cost at Customer 1: 20.00

As seen from the above results, reducing the segment capacities increases the average latency experienced by the shipments since the segments can't be shared between multiple shipments.  Similarly, for the shipments traveling between Customer 2 and Customer 1, the total number of shipments that arrive at the destination go down.  As expected, the total cost per shipment remains the same in both cases.  When we set the routing algorithm to 'dfs', the results differ yet again with segment capacities of 1 due to the varying segment lengths, as shown below:

Shipments Received at Customer 2: 1
Average Latency at Customer 2: 20.00
Total Cost at Customer 2: 20.00
Shipments Received at Customer 1: 0
Average Latency at Customer 1: nan
Total Cost at Customer 1: 0.00

Here, no shipments arrive at customer 1 due to the increased path length from Customer 2 to Customer 1

*** 6.2 Sample Simulation 2 ***

The following statistics result from running test/experiment using a shipment size of 100:

Shipments Received at Destination: 598
Average Latency of Received Shipments at Destination: 17.08
Total Cost of Received Shipments at Destination: 1794.00
Average number of received shipments for all segments: 40.491
Average number of refused shipments for all segments: 35.8514

The following statistics result from running test/experiment using randomly generated shipment sizes (between 1 and 1000) for each source location:

Shipments Received at Destination: 94
Average Latency of Received Shipments at Destination: 35.36
Total Cost of Received Shipments at Destination: 1896.00
Average number of received shipments for all segments: 23.8468
Average number of refused shipments for all segments: 23.2658

As seen above, far fewer shipments arrive at their destinations in the latter case.  This is due to the fact that the average shipment size is significantly higher in the randomly generated case.  Furthermore, we note that nearly all shipments are refused due to the heavy congestion experienced by the network.  Latency also increases significantly due to the higher congestion.

*************************** 7. Architecture and Design ***************************

*** 7.1 Architecture/Design Decisions ***

This application is divided into 3 distinct layers:
- Client layer
- Middle layer
- Engine layer

The client layer interacts with the middle layer only which allows the engine layer implementation to be changed without affecting the client code.  Furthermore the middle layer interface is designed using a strict attribute-only approach.  This greatly simplifies the client-facing API.

The notifier/notifee approach is used by the activity manager to handle shipment injection and forwarding as well as for updating the statistics in the engine layer.  The activity handling is all performed within the middle layer, alleviating the need for the client to create and manage an activity manager.

*** 7.2 Typical Simulation Program Flow ***

- A Shipment arrives at a Location either by an InjectActivityReactor an a ForwardingActivityReactor, shipmentIs() is called.
- The LocationReactor is notified through onShipmentIs(). If the shipment is destined for this destination then statistics are updated and no further action is taken. Otherwise the next segment is looked up in the route table and the shipment is queued on that segment using queuedShipmentIs().
- If the segment has available capacity (or if capacity becomes available at a later point in the simulation) the shipment is transfered from the segment queue to the map of active segments using activeShipmentIs(). In either case statistics are updated on the segment.
- The SegmentReactor is notified through onActiveShipmentNew(). It calculates how long this shipment will take to traverse the segment, creates an Activity and a ForwardingActivityReactor to do the forwarding. Then registers the activity with the activity manager to be executed when the appropriate amount of time has elapsed.
- At some point later in the simulation, the ForwardingActivityReactor is notified that the appropriate amount of time has passed through onStatus(). It updates the statistics in the shipment, removes it from the segment and places it in the next Location using shipmentIs().
- This process repeats from the top.


About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published