![]() | ||||||
#include <Allocatn.h>
Inheritance diagram for Allocation:


The abstract allocation class. Provides a standard interface for the concrete allocation algorithms that can be run from this library. This abstract class also handles the calculations common to all allocations (Coverage, POD, POS, New POC, etc.) so that individual algorithms do not have to reimplement them.
Crucially, it also provides the iterators which are common for all allocations, so that users have a common interface even if all algorithms have different internal data structures. To make this possible, each specific allocation algorithm must implement the six simple virtual accessor functions defined here. Not a bad tradeoff. (In addition, algorithm writers please kindly implement calcAllocation() and call it from your constructor. The code doesn't care, but it will help other readers figure out what's going on.)
The public interface is designed with a few things in mind:
Note on protected versus private: Prevailing wisdom says that member variables are always private. But we have made some protected instead, because child classes are themselves allocations, and need to refer to variables like myEffectiveness quite often. Forcing them to use the indirection of a get function, which is just an alias for returning the variable makes their code uglier. Such variables are already const, so only deliberate misuse presents a problem. Yes an end-user could inherit from the class just to get at the variables directly. But you know what? This is open source. A user that wants to modify the variables that badly can probably manage anyway. Call it low-clutter programming. Eschew superfluous indirection.
Some members remain private: the calculated variables are not always calculated in advance, so access must go through the get functions. This is not a concern with variables passed in as const. Those are always defined and don't change, so if you're an allocation object yourself, why not just use them?
Note on functions not provided: We do not provide getNumAreas() and getNumResources(). As pure allocation objects, all we care about are the resources and areas we get passed, and to us they are just sequential numbers from 0. We don't care if the user only sent us a subset of resources (or areas), or if the user later gets more resources or splits areas. So the user had darn well better keep around an index to take him from our sequential numbers back to actual areas in effect at the time the allocation was made. And if they have to ask us how many areas and resources we had, they've already messed up. (Besides, if they really need this, they can use the iterators and count.)
We do not provide a getPOC() function. If the user doesn't know what our original POC map looked like (oops?), they can get it in at least two ways:
We do not provide an assignment operator. That would be nuts.
Note on valarray: We make extensive use of valarray. Why? We had at one stage replaced our "double *" with vectors, to gain all the notation, encapsulation, and memory cleanup advantages of classes. In our first code review Michael noted that vectors have a lot of overhead and that we never need dynamic resizing. David pointed out that valarrays provided all the advantages of vectors without the overhead: they don't resize (easily), and they're designed from the ground up for speed. Thanks Bjarne!
Code Author : Michael Eldridge Polemics : Charles Twardy Sponsored by: The letter É. (Is your editor unicode?)
Public Member Functions | |
| Allocation (const int p_no_resources, const int p_no_areas, const Array2D &p_effectiveness, const valarray< double > p_endurance, const valarray< double > p_POC) | |
| Base constructor for the allocation class. | |
| Allocation (const Allocation &p_allocation) | |
| The default copy constructor for the base case. | |
| virtual | ~Allocation () |
| double | getEndurance (int resourceNum) |
| Returns the original amount (endurance) for this resource and area. | |
| double | getEffectiveness (int areaNum, int resourceNum) |
| Return the effectiveness of a resource in an area. | |
| virtual void | calcAllocation ()=0 |
| double | getCoverage (int areaNum) |
| Returns the coverage for a specified area. | |
| double | getPOD (int areaNum) |
| Returns the POD for a specified area. | |
| double | getPOS (int areaNum) |
| Returns the POS for a specified area. | |
| double | getNewPOC (int areaNum) |
| Returns the new POC for a specified area, calculating it only if needed. | |
| double | getTotalPOS (void) |
| Returns the totalPOS over all areas, calculating it if needed. | |
Protected Attributes | |
| const int | myNumAreas |
| The total number of areas. | |
| const int | myNumResources |
| The total number of resource groups. | |
| valarray< double > | myPOC |
| The original probability of containment (ie probability of area, POA). | |
| const Array2D & | myEffectiveness |
| The effectiveness of each resource in each area. (W*v/A). | |
| const valarray< double > | myEndurance |
| The amount of time originally made available for each resource. | |
| bool | forceRecalc |
| A flag to force recalculation. For UserDef. | |
Friends | |
| class | AreaIterator |
| So that the AreaIterator can access the first & next functions. | |
| class | ResourceIterator |
| So that the ResourceIterator can access the first & next functions. | |
| class | ActiveAreasIterator |
| So that the ActiveAreasIterator can access the first & next functions. | |
|
||||||||||||||||||||||||
|
Base constructor for the allocation class. Base constructor for the allocation class. Creates all the memory objects for storing all of the search information that is not dependant on the search algorithm. The Assignments parameters are NOT stored in allocation as they are specific to the algorithm. For example, Washburn uses a tree structure while Charnes Cooper uses an Array2D. The most efficient storage type should be used for allocations as the potential number of allocations is areas * resources, which can be larger. |
|
|
Reclaims all the memory used by the base allocation object.
|
|
|
Implemented in CharnesCooper, Washburn, and UserDef. |
|
|
Returns the coverage for a specified area.
|
|
||||||||||||
|
Return the effectiveness of a resource in an area.
|
|
|
Returns the new POC for a specified area, calculating it only if needed. Returns the newPOC for the specified area. If the newPOC has not been calculated, it calculates and stores it. This is similar to the approach detailed in getCoverage, but with a twist. The proper way to initialize myNewPOC is with the previous POC values. So to check whether it has been calculated already, we compare it with the original POC values. We now have the desired behavior. See getCoverage for a full discussion. |
|
|
Returns the POD for a specified area. Returns the POD for the specified area. If the POD for this area has not been calculated, it calculates and stores it. For a full discussion of the reasons for this approach, see getCoverage. |
|
|
Returns the POS for a specified area. Returns the POS for the specified area. If the POS for this area has not been calculated, it calculates and stores it. For a full discussion of the reasons for this approach, see getCoverage. |
|
|
Returns the totalPOS over all areas, calculating it if needed. Returns the totalPOS over all areas. If the totalPOS has not been calculated, it calculates and stores it. This is so that when each request is made to get a totalPOS value, it is not calculated multiple times. The savings can be substantial. To speed up calculation, we only consider active areas. If forceRecalc is true, we also recalculate newPOC in the active areas, and then reset forceRecalc. (New 27mar03, crt) |
|
|
A flag to force recalculation. For UserDef. The only non-const protected data member. Normally, an allocation is set in stone as soon as the object exists, so we can calculate coverage, POD, newPOC, and POS once and store them. But UserDef could change again at any time, and defeat our cleverness. Either we need to make the get functions virtual (just for UserDef), or make them always calculate on the fly (expensive for repeated getTotalPOS operations), or provide a flag to force recalculation. Here's the flag. Since we have protected data members, we put it here because quite obviously it exists precisely so that the kids can set it. (Well, one of them anyway.) If you remove it, please change the logic in the appropriate get functions. And beware: since we provide it, some non-UserDef algorithm may just use it. Though I can't just now see why. Author: crt |
|
|
The amount of time originally made available for each resource. myEndurance is used to store the number of hours originally passed in. This means it will not change. UserDef and other functions will need their own storage for unassigned hours (suggest myAvailable or myUnassignedResources). This move is to clean up semantics. |
| (SARBayes) | Main | Related Pages | Class List | Hierarchy | Methods | Files |
|---|