Dispatch(demand, capacity, resources, active, minimum, increment, method)
Allocates «capacity» of a list of «resources» to meet the total «demand». For example, given the generating capacity in MW of a set of power plants «resources», it dispatches them so that the sum of the amount capacity dispatched for all plants matches the «demand» in MW. It works along the list of plants («resources») allocating its generation up to its maximum capacity, until it reaches the demand. If the plants have been ordered by marginal cost ($/MWh), this method meets the demand at minimum generation cost. It returns an array of allocated capacity, each with a value between 0 and «capacity», indexed by «resources». Usually, the first n-1 elements of «resources» are allocated at full «capacity»; the nth «resources» may be allocated partially; and the remaining «resources» are allocated at zero. If the «demand» is greater than sum of «capacity» over «resources», all elements will be equal to their full «capacity», but the result will not meet the demand.
The optional «active» flag, also indexed by «resource», is
True (1) or
False (0) to indicate whether each «Resource» can be used to fill the demand. This is useful if some elements are unavailable, or if you want to dispatch over a number of regions, in which resources in each region may only supply the demand in that region. (See the Electric power example below.)
The optional parameter «minimum» specifies that the resource, if dispatched at all must be at least «minimum» capacity. The optional parameter «increment» specifies that the resource must be dispatched with an integral number of increments of capacity. Parameters «minimum» and «increment» may be indexed by «resources» to specify different values for each resource. If «minimum» (or «increment») has the same value as «capacity», it means that that resource must be allocated fully or not at all. A Null or zero values for «increment» (or «minimum») for a resource specifies that there is no minimum increment (or the minimum is zero). Even if «minimum» is not a multiple of «increment», the result will always be a multiple of «increment».
(new to Analytica 4.6) If you specify a «minimum» or an «increment», then it is possible that the allocation will not match the «demand» exactly. The «method» parameter specifies how this should be handled, where «method» can have the following values:
0= never exceed «demand» (default)
1= meet or exceed demand, if possible.
2= meet of exceed demand, if possible, and strictly maximize allocation of earlier resources.
If you are using this to allocate resources within a budget, you'll want to use
method: 0. If you are allocating generation capacity to meet demand, you'll want to use
method: 1, or possibly
method: 2 if your generators have a strict priority ordering.
Method 2 ensures that the first resource always provides as much as possible, up to a maximum point of just meeting demand. Then resource 2 allocates as much as possible up to the point of just meeting demand. And so on. This method gives each resource a strict precedence over all preceding resources, but may over-allocate. It also results in the first n-1 resources allocated at full capacity, followed by the nth resource at partial capacity up to the point where «demand» is met. In contrast, Method 2 still gives priority to earlier resources, but may elect to operate earlier resources at less that full capacity when the later resources are required no matter what. The Method differences example below illustrates the difference.
The «method» parameter is new to Analytica 4.6. Earlier releases use method 1. The «method» parameter is irrelevant if all resources can be allocated continuously (meaning that no resource has an «increment» or «minimum»).
Electrical power dispatch
An island has a set of electrical power plants (the Resources), each with a maximum power capacity in Megawatts (MW), to meet the demand in MW. Each plant has a marginal cost of generation in $/KWh as Marginal_cost. We dispatch the plants stored in order of increasing marginal cost to minimize the total generation cost:
Index Plants_ordered := SortIndex(Marginal_cost, Plants)
Dispatch(Demand, Plant_Capacity[Plants = Plants_ordered], Plants_ordered)
In a variation of this problem, the island is divided into regions, each with its own demand --
Demand_by_region is indexed by
Region. Since this island has no long-range transmission lines, each region can consume power only from local plants in that region.
Region_by_plant gives the region in which each
Plant is located. We use the optional parameter active to control which plants are available for allocation in each
Index Plants_ordered := SortIndex(Marginal_cost, Plants)
Dispatch(Demand_by_region, Capacity[Plants = Plants_ordered], Plants_ordered, Active: Region_by_plant[Plants = Plants_ordered] = Region)
An investor creates a model that ranks possible investment by quality (perhaps MIrr, for example). He has a fixed budget to invest, and has limits on the maximum amount that can be allocated to any given investment (the maximum varies by investment). He's already sorted his investments by ascending quality. He uses Dispatch to determine how much money to place in each investment.
Dispatch(investment_amount, allocation_maximum, Investments)
A company has a set of potential projects, sorted by expected ROI. They have a fixed budget to invest. Each project undertaken must be funded at a minimum level, or not at all. However, once funded, a project with a better ROI should receive as much funding as possible, up to the full project_cost.
Dispatch(Budget, Project_cost, Project, minimum:Project_minimum)
This example illustrates the difference between the «method»s that can be utilized when some of the resources have a «minimum» or «increment». The presence of a non-continuous resource may mean that you can't match your «demand» precisely. When allocating within a budget, you want to ensure the allocation never exceeds the «demand» (the «demand» parameter here serves as the budget). When dispatching generation capacity you want to meet of exceed «demand»; however, however there are at least two variants on this, reflected by methods 1 and 2.
Demand = 12
Resource Capacity Increment Allocation Method 0 Method 1 Method 2 1 8 0 8 2 8 2 20 10 0 10 10 Total: 8 12 18
Notice that both of methods 1 and 2 meet or exceed the demand of 12. Method 2 operates the first resource at full capacity, and as a result overshoots the demand since it has needs some of resource 2 but can only allocate in increments of 10. Since you will need use 10 units of the second resource no matter what, Method 2 reduces the allocation from the first resource, and hence avoids overshooting the demand.
Dispatching in reverse
In some cases, you may want to dispatch from the end of the «Resource» index first, just because of how you defined your index. For example, you want to may dispatch the oldest along an Age index, where index Age is in increasing order. This is facilitated by creating a reverse index mapping.
Variable ReverseAge := <code>Slice(Age, size(Age) + 1 - @Age)
Each parameter that uses an array indexed by «Resource» is then reversed, and the final result of Dispatch is reversed.
Dispatch(Consumption, Inventory[Age = ReverseAge], ReverseAge, isActive[Age = ReverseAge])[ReverseAge = Age]
Notice that you have to reverse the «capacity», «active», «minimum» and «increment» parameter.