Method and apparatus for allocating, costing, and pricing organizational resources6032123Abstract This invention is a means both to allocate all types of resources for commercial, governmental, or non-profit organizations and to price such resources. A linear programming process makes fulfillment allocations used to produce product units. A Resource-conduit process governs the linear programming process, uses two-sided shadow prices, and makes aperture allocations to allow Potential-demand to become Realized-demand. A strict opportunity cost perspective is employed, and the cost of buyable resources is deemed to be the opportunity cost of tying up cash. Resource available quantities, product resource requirements, and Potential-demand as a statistical distribution are specified in a database. The invention reads the database, performs optimization, and then writes allocation directives to the database. Also determined and written to the database are resource marginal (incremental) values and product marginal costs. The database can be viewed and edited through the invention's Graphical User Interface. Monte Carlo simulation, along with generation of supply and demand schedules, is included to facilitate analysis, explore "what if," and interact with the user to develop product offering, product pricing, and resource allocation strategies and tactics. Claims What I claim is: Description BACKGROUND TECHNICAL FIELD
______________________________________
for (j = 0; j < nRes; j++)
for (i = each group head in column j)
set rcMat [i] [j].allocation = resQuant[j]/(number of group heads in
column j of rcMat)
______________________________________
5. In Box 909, iterate through each column of rcMat and each element of the enumerated column that contains a group head. In other words, iterate through all group heads of rcMat. For each group head,
______________________________________
if (atoeFnPt[nir].allocation < allocation)
set dedaSub = 0
set dedaAdd = 0
set effectiveness = atoeFnPt [nir].effectiveness
set maxSub = allocation - atoeFnPt[nir].allocation
set maxAdd = 0
else
find ir such that:
atoeFnPt [ir].allocation <= allocation and
atoeFnPt [ir+1].allocation > allocation
(Conceptually, atoeFnPt [nir+1].allocation, if it existed, would
be infinity and atoeFnPt [nir+1].effectiveness would be
atoeFnPt [nir].effectiveness.)
if (ir < nir)
set dedaAdd = the slope of line segment ir, i.e., the line
determined by points atoeFnPt [ir] and atoeFnPt [ir+1]
set maxAdd = atoeFnPt [ir+1].allocation - allocation
else
set dedaAdd = 0
set maxAdd = 0
if (atoeFnPt [ir].allocation not = allocation)
set dedaSub = dedaAdd
set maxSub = allocation - atoeFnPt [ir].allocation
else
if (ir not = 0)
set dedaSub = the slope of line segment ir-1
set maxSub = allocation - atoeFnPt [ir-1].allocation
else
set dedaSub = BIG.sub.-- M
set maxSub = 0
set effectiveness = atoeFnPt [ir] .effectiveness +
dedaAdd * (allocation - atoeFnPt [ir].allocation)
set each group element effectiveness = group head effectiveness
______________________________________
(BIG.sub.-- M is an extremely large positive number. It should be set greater than any conceivable relevant applicable number generated by this invention.) 6. In Box 911,
______________________________________
for (i = 0; i < m; i++)
if (group heads or elements exist in row i of rcMat)
set rowEffectiveness[i] = mathematical product of the
effectivenesses of each group head or group element in row i
else
set rowEffectiveness[i] = 1
set bOrg[i] = rowEffectiveness[i] * potentialDemand[i]
______________________________________
7. In Box 913,
______________________________________
clear a, b, c, d
set B as an identity matrix
Place ones along diagonal a[0] [m] through a[mProd-1] [mn-1] of
matrix a.
For each row of the UnitReq table, set the appropriate element in matrix
a equal to the value of reqQt: the field resourceName determines the
appropriate row, with the first resource of the Resource Table
corresponding to row mProd; productName determines the column,
with the first product of the Product Table corresponding to
column m.
set (vector) b = (vector) bOrg
set c[m] through c[mn-1] = prices of the mProd products as indicated in
the Product Table of Database 101
______________________________________
8. In Box 915,
______________________________________
set all elements of matrix dpTie = -1
for (jProd = 0; jProd < mProd; jProd++)
for (i = mProd; i < m; i++)
if (0 < a[i] [m+jProd])
set dpTie[jProd] [i-mProd] = i
set rwiRow = -1
For each group element (including group heads) in rcMat
set subBlk = FALSE;
______________________________________
Initial Linear Programming Process Once Initialization process 701 is completed, process 703 calls the LPP to maximize the formulated linear programming problem. Axis-walk Process Axis-walk process 705 is shown in FIG. 10, and entails the following steps: 1. In Box 1001, iterate through each column of rcMat and each element of the enumerated column that contains a group head. For each group under consideration:
______________________________________
for (i = rcMat row of each group element, including the group head)
while found (find ii such that:
.circle-solid. b[ii] = 0
.circle-solid. B[ii] [i] > 0
.circle-solid. there exists a jj such that:
c[jj] < 0 and a[ii] [jj] < 0)
if (ii found)
Pivot row ii as described below in Box 1117
endwhile
set emcSub = - c[i] * (bOrg[i]/effectiveness) * dedaSub
if ((ir = 0 and allocation = 0) or subBlk)
set emcSub = BIG.sub.-- M
while found (find ii such that:
.circle-solid. b[ii] = 0
.circle-solid. B[ii] [i] < 0
.circle-solid. there exists a jj such that:
c[jj] < 0 and a[ii] [jj] < 0)
if (ii found)
Pivot row ii as described below in Box 1117
endwhile
set emvAdd = - c[i] * (bOrg[i]/effectiveness) * dedaAdd
if (ir = nir)
set emvAdd = 0
set gmcSub = sum of the emcSub values for each group element
set gmvAdd = sum of the emvAdd values for each group element
______________________________________
2. In Box 1003, find the two groups that maximize rcMat[ia][j].gmvAdd minus rcMat[is][j].gmcSub, where j ranges from 0 to nRes-1, and ia and is reference group heads in column j of rcMat. Exclude from consideration groups that have elements in row rwiRow of rcMat. 3. In Diamond 1005, test whether an allocation shift from group rcMat[is][j] to group rcMat[ia][j] is worthwhile. If the answer is "Yes", proceed to Box 1007; if the answer is "No", return to calling routine. 4. In Box 1007, shift allocation as shown in FIGS. 11A and 11B and explained below. Axis-walk Allocation Shift FIGS. 11A and 11B show an enlargement of Box 1007, which entails the following steps. Steps 6 through 9 define a Box 1151. 1. In Box 1101,
______________________________________
set vector bHold = vector b
set rcMat[is] [j].allocationHold = rcMat[is] [j].allocation
set rcMat[ia] [j].allocationHold = rcMat[ia] [j].allocation
______________________________________
2. In Box 1103,
______________________________________
set awQuant = minimum(rcMat[is] [j].maxSub, rcMat[ia] [j].maxAdd)
______________________________________
3. In Box 1105,
______________________________________
set rcMat[is] [j].allocation = rcMat[is] [j].allocationHold - awQuant
set rcMat[ia] [j].allocation = rcMat[ia] [j].allocationHold
______________________________________
+ awQuant
4. In Box 1107, apply Box 909 to groups rcMat[is][j] and rcMat[ia][j] to generate group effectivenesses. 5. In Box 1109, apply Box 911 to generate bOrg. 6. In Box 1111, set vector b equal to the product of matrix B and vector bOrg. 7. In Box 1113, if possible, find i such that: b[i] is minimized, b[i]<0, and bHold[i]=0. 8. In Diamond 1115, test whether an i was found in Box 1113. If the answer is "Yes", proceed to Box 1117; if the answer is "No", proceed to Diamond 1119. 9. In Box 1117, pivot row i as described immediately below, then go to Box 1111.
______________________________________
set irow = row to be pivoted
Find jcol such that
.circle-solid. a[irow] [jcol] < 0
.circle-solid. c[jcol] < 0
.circle-solid. c[jcol]/a[irow] [jcol] is minimized
if (jcol found)
apply prior art to pivot the simplex tableau (matrix a, vectors b and
c, and scalar d) using a[irow] [jcol] as the pivot element
______________________________________
10. In Diamond 1119, test whether any element of vector b is less than 0. If the answer is "Yes", proceed to Box 1121; if the answer is "No", return to calling routine. 11. In Box 1121,
______________________________________
Find i, such that
b[i] < 0 and
bHold[i]/(bHold[i]-b[i]) is minimized
set awQuant = awQuant * bHold[i]/(bHold[i]-b[i])
Generate vector b by reapplying Boxes 1105, 1107, 1109, and
______________________________________
1111
(Because an infinite loop may occur in Box 1151, a limit to the number of times branching from Diamond 1115 to Box 1117 is required. Once this limit is reached, Box 1151 should be exited. If Box 1151 was entered as a result of an Axis-walk, Top-walk, or Lateral-walk call, then the rcMat[is][j] and rcMat[ia][j] pair that led to the infinite loop should be directionally blocked so as to prevent a re-entrance into Box 1151. (Directional blocking is explained as part of the Top-walk process.)) Top-walk Process The Top-walk process considers shifting allocations from every group to every other group in each rcMat column. Because of inherent numerical accuracy limitations on most computers, it is necessary to test whether a Top-walk shift actually increased lad, and if not, reverse the shift and block the considered group-pair shift possibility from further consideration. Such blocking can be accomplished by use of a three dimensional array of size mProd by mProd by nRes. The first index is the rcMat row of the subtraction group-head; the second index is the rcMat row of the addition group-head; and the third index is the rcMat column of the two group heads. Initially all elements of this array are set to 0; when a group pair is blocked, the appropriate element in the array is set to 1.0. Blocking is directional. Also, because of numerical accuracy limitations, essentially a single Top-walk shift may be accomplished by many, similar, infinitesimally-small shifts; to avoid such a possibility and the associated "waste" of CPU cycles, a minimum shifting tolerance can be used. This tolerance (twQuantMin) needs to be set to a non-negative value. The smaller the value of twQuantMin, the more accurate the solution, but the more CPU cycles required. Top-walk works with a chain of group heads, many of which are paired into uv pairs. For each pair, the u-group has its allocation increasing and the v-group has its allocation decreasing. In FIG. 8B, for example, for the 817-819 pair, group 817 is the u-group while group 819 is the v-group. Similarly for the 823-825 pair, group 823 is the u-group and 825 the v-group. Top-walk process 707 is shown in FIG. 12, and entails the following steps: 1. In Box 1201, clear all group-pair blocking for all rcMat columns. 2. In Box 1203,
__________________________________________________________________________
apply Box 1001
for each group element in row rwiRow of rcMat
set emcSub = BIG.sub.-- M
set emvAdd = -BIG.sub.-- M
in element's group head
set gmcSub = BIG.sub.-- M
set gmvAdd = -BIG.sub.-- M
for (each group head in rcMat)
set twmcSub = gmcSub
set twcCol = -1
set twcRow = -1
set twcsRow = -1
set reCycle = TRUE
while (reCycle)
set reCycle = FALSE
for (irow = 0; irow < mProd; irow++)
if (b[irow] = 0 or irow = rwiRow)
for (jcolu = 0; jcolu < nRes; jcolu++)
if (rcMat[irow] [jcolu] is a group head or group element)
set irowuh = group-head row index of the group that has an
element at rcMat[irow] [jcolu]
if (rcMat[irowuh] [jcolu].ir not = nir)
find the group head in column jcolu that has the minimum
twmcSub value, that has a positive allocation, and that
is not rcMat[irowuh] [jcolu]; set irowcs = the row index
of the found group head
for (jcolv = 0; jcolv < nRes; jcolv++)
if (rcMat[irow] [jcolv] is a group head or element and
jcolu not = jcolv)
set irowvh = group-head row index of the group that
has an element at rcMat[irow] [jcolv]
if (rcMat[irowvh] [jcolv].allocation not = 0)
set 1 kqt = TWufvEpsilon(
rcMat[irowuh] [jcolu],
rcMat[irowuh] [jcolu].allocation,
rcMat[irowvh] [jcolv],
rcMat[irowvh] [jcolv].allocation)
set mc = rc[irowcs] [jcolu].twmcSub * 1 kqt
for (i = each rcMat row of group
rcMat [irowuh] [jcolu])
if (rcMat[i] [jcolv] is not an element of
group rcMat[irowvh] [jcolv])
set mc = mc - rcMat[i] [jcolu].emvAdd
* 1 kqt
for (i = each rcMat row of group
rcMat[irowvh] [jcolv])
if (rcMat[i] [jcolu] is not an element of
group rcMat[irowuh] [jcolu])
set mc = mc +
rcMat[i] [jcolv].emcSub
if (mc < rcMat[irowvh] [jcolv].twmcSub)
set rcMat[irowvh] [jcolv].twmcSub = mc
set rcMat[irowvh] [jcolv].twcRow = irowuh
set rcMat[irowvh] [jcolv].twcCol = jcolu
set rcMat[irowvh] [jcolv].twcsRow = irowcs
set reCycle = TRUE
__________________________________________________________________________
3. In Box 1205,
______________________________________
find the group pair that maximizes:
rcMat[ia] [j].gmvAdd - rcMat[is] [j].twmcSub,
such that:
.circle-solid. j ranges from 0 to nRes-1,
.circle-solid. ia and is reference group heads in column j of rcMat,
.circle-solid. the group-pair with the subtraction head at rcMat[is] [j]
and
addition head at rcMat[ia] [j] is not blocked
______________________________________
4. In Diamond 1207, test whether an allocation shift from group rcMat[is][j] to group rcMat[ia][j] is possibly worthwhile. If the answer is "Yes", proceed to Diamond 1209; if the answer is "No", proceed to Diamond 1221. 5. In Diamond 1209, test whether a transfer chain would have more than a single link. Specifically,
______________________________________
if (rcMat[is] [j].twcCol = -1) then
chain has only one link.
______________________________________
6. In Box 1211, construct a chain for shifting allocations as follows:
______________________________________
set twpGroupSub[0] = address of rcMat[is] [j]
set twpGroupAdd[0] = address of rcMat[ia] [j]
set twnLink = 1
set xj = j
set xis = is
set xia = ia
set crossOver = FALSE
while (not crossOver and rcMat[xis] [xj].twcCol not = -1)
set xj = rcMat[xis] [j].twcCol
set xia = rcMat[xis] [j].twcRow
set xis = rcMat[xis] [j].twcsRow
set twpGroupSub[twnLink] = address of rcMat[xis] [xj]
set twpGroupAdd[twnLink] = address of rcMat[xia] [xj]
for (i = 0; i < twnLink; i++)
if (twpGroupSub[i] = twpGroupSub[twnLink] or
twpGroupSub[i] = twpGroupAdd[twnLink] or
twpGroupAdd[i] = twpGroupSub[twnLink] or
twpGroupAdd[i] = twpGroupAdd[twnLink])
set crossOver = TRUE
set twnLink = twnLink + 1
set iSplitVer = -1
set iSplitHor = -1
if (crossOver)
for (i = 0; i < twnLink - 1; i++)
if (twpGroupAdd[i] = twpGroupAdd[twnLink - 1])
set twnLink = twnLink - 1
goto endLoop1
else if (twpGroupSub[i] = twpGroupAdd[twnLink - 1])
set iSplitVer = i
goto endLoop1
else if (twpGroupAdd[i] = twpGroupSub[twnLink] - 1])
{
if (twpGroupSub[i] not = twpGroupAdd[twnLink - 1])
twpGroupSub[twnLink - 1] = twpGroupSub[i]
set iSplitVer = i
goto endLoop1
else
set twnLink = twnLink - 1
goto endLoop1
}
else if (twpGroupSub[i] = twpGroupAdd[twnLink - 1])
set twnLink = twnLink - 1
goto endLoop1
}
endLoop1:
for (i = 0; i < twnLink-1; i++)
if (exactly one of the following is true:
.circle-solid. CrossHAT (twpGroupSub[i])
.circle-solid. CrossHAT(twpGroupAdd[i+1]))
goto Box 1217
if (CrossHAT (twpGroupSub[twnLink-1]) and iSplitVer = -1)
{
for (i = 0; i < twnLink; i++)
if (CrossHAT(twpGroupSub[i]))
{
if (iSplitHor = -1)
set iSplitHor = i + 1
else
set twnLink = i + 1
goto endLoop2
}
goto Box 1217
}
endLoop2:
______________________________________
Function definition:
______________________________________
CrossHAT(pointer group head (pGH))
if (the group whose head is pointed to by pGH has an element in row
rwiRow of rcMat)
return TRUE
else
return FALSE
______________________________________
7. In Box 1213, determine quantities and shift allocations through the chain. This is shown in detail FIG. 13 and explained below. 8. In Diamond 1215, test whether the allocation shifts through the chain proved worthwhile. If the answer is "Yes", proceed to Box 1203; if the answer is "No", proceed to Box 1217. 9. In Box 1217, block the shift group-pair with a subtraction head at rcMat[is][j] and an addition head at rcMat[ia][j] (both group heads were determined in Box 1205) from further consideration. 10. In Box 1219, apply Box 705 (Axis-walk). 11. In Diamond 1221, test whether .vertline.d.vertline. has increased since any group-pair was blocked in Box 1217. If the answer is "Yes", proceed to Box 1201; if the answer is "No", return to calling routine. Top-walk Allocation Shift FIGS. 13A, 13B, and 13C show Box 1213 in detail: 1. In Box 1301, save the following to a temporary memory location that is specific to this Top-walk process: matrix a, vectors b and c, and scalar d matrix rcMat and all contained group head and group elements vectors bOrg and rowEffectiveness 2. In Box 1302,
______________________________________
set vector bHold = vector b
for (i = 0; i < twnLink; i++)
apply to group pointed to by twpGroupSub[i]
set allocationHold = allocation
set effectivenessHold = effectiveness
apply to group pointed to by twpGroupAdd[i]
set allocationHold = allocation
set effectivenessHold = effectiveness
______________________________________
3. In Box 1303, set twQuant, the initial shift quantity:
______________________________________
set twQuant twpGroupAdd[0] -> maxAdd
for (i = 0; i < twnLink-1; i++)
set twQuant = minimum (twQuant, twpGroupSub[i] -> maxSub)
set twQuant = TWufv(twpGroupAdd[i+l],
twpGroupAdd[i+l] -> allocation,
twpGroupSub[i]
twpGroupSub[i] -> allocation,
twQuant)
set twQuant = minimum (twQuant, twpGroupAdd[i+1] -> maxAdd)
set twQuant = minimum (twQuant, twpGroupSub[twnLink-1] -> maxSub)
______________________________________
The following functions are used in Box 1303 and in other Boxes of the Top-walk process. TWufv accepts a quantity being shifted out of a group v and determines the compensating quantity to shift into a group u; TWvfu does the reverse. TWufvEpsilon is the same as TWufv, except the quantity being shifted out of group v, in the mathematical limit sense, is assumed to be an infinitesimally small unit of one, while the compensatory quantity shifted into group u is a multiple of the same infinitesimally small unit.
______________________________________
GenEffectiveness(pointerGroup, newAllocation)
set net = pointerGroup -> effectivenessHold
set diff = newAllocation - pointerGroup -> allocationHold
if (0 < diff)
set net = net + pointerGroup -> dedaAdd * diff
else
set net = net + pointerGroup -> dedaSub * diff
return net
TWufv(pointerUGroup, uAllocation, pointerVGroup, vAllocation, shift)
set ue = GenEffectiveness(pointerUGroup, uAllocation)
set ud = pointerUGroup -> dedaAdd
set ve = GenEffectiveness(pointerVGroup, vAllocation)
set vd = pointerVGroup -> dedaSub
set vi = vd * shift
return (ue * vi/(ud * (ve - vi)))
TWvfu(pointerUGroup, uAllocation, pointerVGroup, vAllocation, shift)
set ue = GenEffectiveness(pointerUGroup, uAllocation)
set ud = pointerUGroup -> dedaAdd
set ve = GenEffectiveness(pointerVGroup, vAllocation)
set vd = pointerVGroup -> dedaSub
set ui = ud * shift
return (ve * ui/(vd * (ue + ui)))
TWufvEpsilon(pointerUGroup, uAllocation, pointerVGroup, vAllocation)
set ue = GenEffectiveness(pointerUGroup, uAllocation)
set ud = pointerUGroup -> dedaAdd
set ve = GenEffectiveness(pointerVGroup, vAllocation)
set vd = pointerVGroup -> dedaSub
return (ue*vd/ud*ve)
TWvfuEpsilon(pointerUGroup, uAllocation, pointerVGroup, vAllocation)
set ue = GenEffectiveness(pointerUGroup, uAllocation)
set ud = pointerUGroup -> dedaAdd
set ve = GenEffectiveness(pointerVGroup, vAllocation)
set vd = pointerVGroup -> dedaSub
return (ud*ve/ue*vd)
______________________________________
4. In Box 1305, shift allocations as follows:
______________________________________
set shift = twQuant
for (i = twnLink-1; 0 <= i; i--)
set twpGroupSub[i] -> allocation =
twpGroupSub[i] -> allocationHold - shift
if (i = iSplitVer)
set shift = shift - twQuant
set twpGroupAdd[i] -> allocation =
twpGroupAdd[i] -> allocationHold + shift
if (i = iSplitHor)
set debt = TWufv( twpGroupAdd[iSplitHor],
twpGroupAdd[iSplitHor] -> allocation,
twpGroupSub[twnLink-1],
twpGroupSub[twnLink-1] -> allocation,
twQuant)
set shift = shift - debt
else
set debt = 0
if (0 < i)
set shift = TWvfu( twpGroupAdd[i],
twpGroupAdd[i] -> allocationHold + debt,
twpGroupSub[i-1],
twpGroupSub[i-1] -> allocationHold,
shift)
generate group effectivenesses for the groups pointed to by
twpGroupSub[i] and twpGroupAdd[i] by applying Box 909
regenerate vectors rowEffectiveness and bOrg by applying Box
______________________________________
911
5. In Box 1307, apply Box 1001 to generate group marginal values for each group pointed to by vectors twpGroupSub and twpGroupAdd. (Note that the linear programming problem and solution is the same as it was in Box 1301.) 6. In Box 1309, do the following to determine rcMat[is][j].twmcSub, given the shifts done in Box 1305:
______________________________________
set mc = twpGroupSub[twnLink-1] -> gmcSub
set shift = 1.0 //(infinitesimal unit)
for (i = twnLink-1; 1 <= i; i--)
set jj = rcMat column of group pointed to by twpGroupAdd[i]
for (ii = each rcMat row of group pointed to by twpGroupAdd[i])
if (group pointed to by twpGroupSub[i-1] does not have group
element in row ii of rcMat)
set mc = mc - rcMat[ii] [jj].emvAdd * shift
if (i = iSplitVer)
set shift = shift - 1.0
if (i = iSplitHor)
set debt = TWufvEpsilon (twpGroupAdd[iSplitHor],
twpGroupAdd[iSplitHor] -> allocation,
twpGroupSub[twnLink-1],
twpGroupSub[twnLink-1] -> allocation)
set shift = shift - debt
set shift = shift * TWufvEpsilon(twpGroupAdd[i],
twpGroupAdd[i] -> allocation,
twpGroupSub[i-1],
twpGroupSub[i-1] -> allocation)
set jj = rcMat column of group pointed to by twpGroupSub[i-1]
for (ii = each rcMat row of group pointed to by twpGroupSub[i-1])
if (group pointed to by twpGroupAdd[i] does not have group
element in row ii of rcMat)
set mc = mc + rcMat[ii] [jj].emcSub * shift
set rcMat[is] [jj].twmcSub = mc
______________________________________
7. In Diamond 1311, test whether the shifting done in Box 1305 is marginally worthwhile, i.e., whether, rcMat[is][j].twmcSub<=rcMat[ia][j].gmvAdd. If the answer is "Yes", proceed to Box 1321; if the answer is "No", proceed to Box 1315. 8. In Box 1315, use bisection method search to find a new value for twQuant so that: it is between 0 and the values set in Box 1303 and after reapplying Boxes 1305, 1307, and 1309 the following condition is met: rcMat[is][j].twmcSub=rcMat[ia][j].gmvAdd 9. In Box 1317, apply Box 1305. 10. In Box 1321, apply Box 1151 to generate vector b. 11. In Diamond 1329, test whether any element of vector b is less than an infinitesimal negative value. If the answer is "Yes", proceed to Box 1331; if the answer is "No", proceed to Box 1333. 12. In Box 1331, use bisection method search to find a new value for twQuant, so that: it is between 0 and the smaller of the values as set in Boxes 1303 and 1315. after reapplying Box 1317 and setting b=B*bOrg, the smallest element in vector b is 0 or infinitesimally smaller than 0. 14. In Box 1333,
______________________________________
if (twQuant < twQuantMin)
set twQuant = minimum of twQuantMin and twQuant as set in
Box 1303
______________________________________
15. In Box 1335, apply Box 1305 using the current twQuant and set b=B*bOrg. 16. In Box 1337, make the current linear programming solution feasible, by, for instance, applying the well known Dual Simplex Method. 17. In Diamond 1339, test whether .vertline.d.vertline. has increased since it was saved in Box 1301. If the answer is "Yes", return to calling routine; if the answer is "No", proceed to Box 1341. 18. In Box 1341, restore the earlier solution by restoring the data saved in Box 1301. Lateral-walk Process Lateral-walk process 709 uses facReduce as a programmer-set tolerance, which needs to be slightly less than 1.0. The closer facReduce is to 1.0, the more accurate the solution, but the more CPU cycles required. Like the Top-walk process, the Lateral-walk process tracks which group-pair shifts proved undesirable and then avoids repeat consideration of such shifts. Process 709 is shown in detail in FIG. 14 and entails the following steps: 1. In Box 1401, clear all group-pair blockings. 2. In Box 1403, apply Box 1301, but use storage that is specific to this Lateral-walk process. Also make a copy of vectorpotentialDemand. 3. In Box 1405,
______________________________________
for (i = 0; i < m; i++)
set limitLoop = a positive integer limit value
while (b[i] = 0 and 0 < limitLoop and
(exists j and jj such that
B[i] [j] not = 0
B[i] [jj] not = 0
j not = jj))
{
set potentialDemand[i] = potentialDemand[i] *
facReduce
apply Box 911
set b = B * bOrg
apply box 1337
set limitLoop = limitLoop - 1
}
______________________________________
4. In Box 1407, apply Boxes 1203, 1205, 1207, 1209, 1211, 1213, and 1219. Exit before applying Boxes 1215 and 1221. When doing Box 1205, respect any pair-blocking done in Box 1419. When doing Box 1213, skip Diamond 1339 and Box 1341. Immediately exit Box 1219, after doing Box 1007. 5. In Box 1409, restore vectorpotentialDemand that was stored in Box 1403. Also apply Box 911 set b=b*bOrg apply box 1337 6. In Diamond 1411, test whether a Top-walk allocation shift was done in Box 1407 i.e., if the answer to the condition of Diamond 1207 was "Yes." If the answer is "Yes", proceed to Diamond 1415; if the answer is "No", proceed to Diamond 1421. 7. In Diamond 1415, test whether .vertline.d.vertline. increased from its value saved in Box 1403. If the answer is "Yes", proceed to Box 1403; if the answer is "No", proceed to Box 1417. 8. In Box 1417, restore the solution saved in Box 1403. 9. In Box 1419, block the group-pair with group heads at rcMat[is][j] and rcMat[ia][j] (as determined in Boxes 1407 and 1205) from further consideration. 10. In Diamond 1421, test whether .vertline.d.vertline. has increased since any group-pair was blocked in Box 1419. If the answer is "Yes", proceed to Box 1401; if the answer is "No", return to calling routine. Ridge-walk Process Ridge-walk process 711 uses three programmer-set tolerances: rwATLrefresh, rwShiftMin, and rwShiftMax. These tolerances need to be positive. Once the increase in rowEffectiveness is greater than rwATLrefresh, the Axis-walk, Top-walk, and Lateral-walk processes are called. Tolerances rwShiftMin and rwShiftMax, with rwShiftMin<=rwShiftMax, determine the minimum and maximum allocation shift per iteration. The smaller each of these three tolerances, the more accurate the solution, but the more CPU cycles required. Ridge-walk process 711 is shown in detail in FIGS. 15A and 15B and entails the following steps: 1. In Box 1501, use rwiRow as an iterator to continually cycle through the first mProd rows of rcMat. Continue until a complete cycle has not resulted in any increase in .vertline.d.vertline.. Specifically:
______________________________________
set rwiRow = 0
set count = 0
do
{
set dHold = .vertline.d.vertline.
if (.vertline.d.vertline. > dHold)
set count = 1
else
set count = count + 1
set rwiRow = rwiRow + 1
if (rwiRow = mProd)
set rwiRow = 0
}
while (count not = mProd)
set rwiRow = -1
______________________________________
2. In Box 1503,
______________________________________
set all elements of vector dpTieSubBlk = FALSE
set baseRowEffectiveness = - BIG.sub.-- M
______________________________________
3. In Box 1505, apply Box 1301, but use storage that is specific to this Ridge-walk process. 4. In Box 1507, drag along Direct-puts: shift group allocations between the groups of row rwiRow and its Direct-put groups in order to relieve constraints on product rwiRow. Specifically,
______________________________________
for (j = 0; j < nRes; j++)
if (dpTie[rwiRow] [j] not = -1)
if (rcMat[rwiRow] [j] is not empty)
set iRW = row of group head of the group that has an
element at rcMat[rwiRow] [j]
else
set iRW = -1
set iDP = dpTie[rwiRow] [j]
set qtRW = bOrg[rwiRow]
set qtDP = (bOrg[iDP]) /(the value of a[iDP] [m + rwiRow] as
originally set in Box 913)
while (qtDP < qtRW)
apply Box 1001 to all groups in column j of rcMat
ia = iDP
is = index of group head in column j of rcMat that has the
smallest gmcSub but is not equal to iDP
if (rcMat[is] [j].gmcSub = BIG.sub.-- M)
break out of while loop
set awQuant = minimum ( rcMat[ia] [j].maxAdd,
rcMat[is] [j].maxSub,
rwShiftMin)
apply Boxes 1101, 1105, 1107, 1109, 1111, and 1337
if (is = iRW)
set dpTieSubBlk[j] = TRUE
set qtRW = bOrg[rwiRow]
set qtDP = bOrg[iDP] / (the value of a[iDP] [m +
rwiRow] as originally set in Box 913)
if (iRW not = -1)
set is = iDP
set ia = iRW
do
apply Box 1001 to groups rcMat[is] [j] and
rcMat[ia] [j]
if (Diamond 1005 is TRUE)
apply Box 1007
while (Diamond 1005 is TRUE)
______________________________________
5. In Diamond 1509, test whether rowEffectiveness[rwiRow] exceeds baseRowEffectiveness plus rwATLrefresh. If the answer is "Yes", proceed to Box 1511; if the answer is "No", proceed to Diamond 1513. 6. In Box 1511,
______________________________________
for (j = 0; j < nRes; j++)
if (rcMat[rwiRow] [j] is not empty)
set rcMat[rwiRow] [j].subBlk = TRUE
if (dpTie[rwiRow] [j] not = -1)
set rcMat[dpTie[rwiRow] [j]] [j].subBlk = TRUE
apply the following:
Axis-walk (Box 705)
Top-walk (Box 707)
Lateral-walk (Box 709)
for (j = 0; j < nRes; j++)
if (rcMat[rwiRow] [j] is not empty)
set rcMat[rwiRow] [j].subBlk = FALSE
if (dpTie[rwiRow] [j] not = -1)
set rcMat [dpTie [rwiRow] [j]] [j].subBlk = FALSE
set baseRowEffectiveness = rowEffectiveness [rwiRow]
______________________________________
7. In Diamond 1513, test whether .vertline.d.vertline. is greater than the last value of .vertline.d.vertline. stored in Box 1505 or 1515. If the answer is "Yes", proceed to Box 1515; if the answer is "No", proceed to Box 1517. 8. In Box 1515, apply Box 1505. 9. In Box 1517, attempt Ridge-walk iteration, which is explained in detail below. 10. In Diamond 1519, test whether a Ridge-walk iteration was done in Box 1517. If the answer is "Yes", proceed to Box 1507; if the answer is "No", proceed to Box 1521. 11. In Box 1521, restore the solution last saved in Boxes 1505 and 1515. Ridge-walk Iteration Ridge-walk iteration 1517 is shown in detail in FIGS. 16A and 16B. 1. In Box 1601,
______________________________________
set applied1007 = FALSE
set all elements of rwpDest and rwpSour equal to NULL
for (j = 0; j < nRes; j++)
set loopRepeat = TRUE
while (loopRepeat and exist group element at rcMat[rwiRow]
[j])
set loopRepeat = FALSE
set rwpDest[j] = address of group head of the group having
an element at rc[rwiRow] [j]
if (rwpDest[j] -> ir = rwpDest[j] -> nir)
exit while loop
apply Box 1001
Attempt to find group head in column j such that:
.circle-solid. gmcSub is minimized
.circle-solid. the group head is not pointed to by rwpDest[j]
.circle-solid. the group head has an allocation greater than 0
.circle-solid. if dpTieSubBlk[j] is TRUE, then the group is not
rcMat(dpTie[rwiRow] [j]] [j]
if (group head is found)
{
set rwpSour[j] = address of found group head
if (rwpSour[j] -> gmcSub < rwpDest[j] -> gmvAdd)
set ia = row of group head rwpDest[j]
set is = row of group head rwpSour[j]
apply Box 1007
set applied1007 = TRUE
set loopRepeat = TRUE
else
set rwpSour[j] = NULL
if (applied1007)
goto Box 1507, i.e. exit Fig. 16 and assume an iteration
______________________________________
2. In Diamond 1603, test whether there exists a jj, such that both rvpDest[jj] and rvpSour[jj] are not NULL. If the answer is "Yes", proceed to Box 1605; if the answer is "No", return to calling routine. If such a jj exists, then a Ridge-walk iteration is possible. The iteration will simultaneously apply to each non-null rwpDest[jj]-rwpSour[jj] pair. (To facilitate exposition, all elements of vectors rwpDest and rwpSour will be assumed to be non NULL.) 3. In Box 1605, for (each group head pointed to by vectors rwpDest and rwpDest) set allocationHold=allocation 4. In Box 1607,
______________________________________
set vector bHold = vector b
for (j = 0; j < nRes; j++)
set rwOldAlloc[j] =
rwpDest[j] -> effectiveness / rwpDest[j] -> dedaAdd
set rwOldMC[j] = rwpSour[j] -> gmcSub
______________________________________
5. In Box 1609,
______________________________________
set rwParaMin = BIG.sub.-- M
set rwParaMax = BIG.sub.-- M
for (j = 0; j < nRes; j++)
set min = minimum (rwpDest[j] -> maxAdd,
rwpSour[j] -> maxSub,
rwShiftMin)
set min = (min + rwOldAlloc[j]) * rwOldMC[j]
set rwParaMin = minimum(min, rwParaMin)
set max = minimum (rwpDest[j] -> maxAdd,
rwpSour[j] -> maxSub,
rwShiftMax)
set max = (max + rwOldAlloc[j]) * rwOldMC[j]
set rwParaMax = minimum(max, rwParaMax)
set rwParameter = rwParaMax
______________________________________
6. In Box 1611,
______________________________________
for (j = 0; j < nRes; j++)
set shift = rwParameter/rwOldMC[j] - rwOldAlloc[j]
if (shift < 0)
set shift = 0
set rwpSour[j] -> allocation =
rwpSour [j] -> allocationHold - shift
set rwpDest[j] -> allocation =
rwpDest [j] -> allocationHold + shift
apply Box 909 to groups pointed to by vectors rwpSour and
______________________________________
rwpDest
7. In Box 1613, generate bOrg by applying Box 911. 8. In Box 1621, apply Box 1321. 9. In Diamond 1623, test whether any element of vector b is less than an infinitesimal negative value. If the answer is "Yes", proceed to Box 1625; if the answer is "No", proceed to Box 1627. 10. In Box 1625, use bisection method search to find a new value for rwParameter, so that: it is between 0 and rwParaMax after applying Boxes 1611 and 1613, and setting b=B*bOrg, the smallest element in vector b is 0 or infinitesimally smaller than 0. 11. In Box 1627,
______________________________________
if (rwParameter < rwParaMin)
set rwParameter = rwParaMin
______________________________________
12. In Box 1629, apply Boxes 1611 and 1613 using the current rwParameter and set b=B*bOrg. 13. In Box 1631, as in Box 1337, make the current linear programming solution feasible. Finalization The finalization process of posting the results to the database (process 713) is shown in FIG. 17 and entails: 1. In Box 1701, generate marginal values by applying Box 1001. 2. In Box 1703,
______________________________________
for (j = 0; j < nRes; j++)
do
set is = index of group head in column j of rcMat that has the
smallest gmcSub, such that is < mProd
if (rcMat[is] [j].gmcSub = 0)
set ia = mProd + j
apply Box 1007, then Box 1001
while (rcMat[is] [j].gmcSub = 0)
set meanUse field in Database 101 Resource Table = (sum of the
allocations to all the group heads in column j and rows 0 through
row mProd-1 of rcMat) + (the quantity of the resource in row
(mProd + j) of matrix a and vector b allocated by the LPP)
set marginalValue = the minimum value of gmcSub contained in all the
group heads in column j of rcMat
______________________________________
3. In Box 1705,
______________________________________
for (each group head in the first mProd rows of rcMat)
set i = group-head rcMat row
set j = group-head rcMat column
Locate the row in the Group Table that corresponds to group head
rcMat[i] [j]; i.e., back trace to the original row used in Box 903
set the meanAlloc field in the Group Table row =
rcMat[i] [j].allocation
set the marginalValue field in the Group Table row =
rcMat[i] [j].gmcSub
______________________________________
4. In Box 1707,
______________________________________
for (iProd = 0; iProd < mProd; iProd++)
apply Boxes 1709 through 1715 to generate data for the Product
Table
______________________________________
5. In Box 1709, for row iProd of the Product Table, apply prior-art linear programming methods to set meanSupply equal to quantity of iProd produced. 6. In Diamond 1711, test whether meanSupply as set in Box 1709 equals 0. If the answer is "Yes", proceed to Box 1715; if the answer is "No", proceed to Box 1713. 7. In Box 1713, set marginalCost=price. 8. In Box 1715,
______________________________________
set mmc = 0
set rwiRow = iProd
if (bOrg[iProd] < 1.0)
apply Box 1301, but use storage specific to this Box
apply Box 1601, but without branching to Box 1507
apply Diamond 1603
if (iteration not possible as per Diamond 1603)
set marginalCost (of row iProd of Product Table) = infinity
exit this Box
apply Boxes 1605 and 1607
set rwParaMin = 0
set rwParaMax = BIG.sub.-- M
set rwParameter = BIG.sub.-- M
Use bisection search method to find rwParameter value so that, after
applying Boxes 1611 and 1613, bOrg[iProd] equals 1. If this is
not possible, continue with bisection to find rwParameter that
maximizes bOrg[iProd].
______________________________________
DETAILED DESCRIPTION PREFERRED EMBODIMENT The preferred embodiment builds upon the previously described basic embodiment and makes possible all the previously described objects and advantages. It entails enhancements to the database, handling of cash related resources, Monte Carlo simulation, operation under a GUI (Graphical User Interface), optimization controls, and generating supply and demand schedules that facilitate analysis. When Monte Carlo simulation is done, the following, which is here termed a scenario, is repeated: potentialDemand values are randomly drawn from user-defined statistical distributions, optimized allocations are made, and the results noted. A set of scenarios constitutes what is here termed a simulation. Once a simulation is finished, mean noted-scenario-results are written to the database. Unfulfilled potentialDemand of one scenario is possibly passed on to the next Each scenario is fundamentally a possibility for the same period of consideration, e.g., the upcoming month. Implicitly, a steady stochastic state is being presumed for the period of consideration. (For purposes of the present invention's making direct allocations as described in the Theory of the Invention Section, a simulation is done with only one scenario; if non-single-point statistical distributions are specified for potentialDemand, then mean values are used for the single scenario.) A Base simulation is the basic simulation done to allocate resources and determine marginal costs/values. A Supply simulation generates the schedule between product price and optimal mean supply quantity. Similarly, a Demand simulation generates the schedule between external resource price and optimal quantities. To facilitate exposition, programming objects are utilized. These are the objects of object-oriented programming, and conceptually consists of a self-contained body of data and executable code. Database The preferred embodiment database has two additional tables: Distribution and Results Tables. All the previous five tables have additional fields. Distribution Table The Distribution Table is in effect a user-defined library of statistical distributions that can be used to express Potential-demand as a statistical distribution. This table has the following fields, one of which is a programming object Those marked with asterisks (*) are determined by the present invention: distName--user defined name; table key. distType--type of distribution, e.g., normal, uniform, Poisson, single-value, etc. distObject--a programming object that: 1. accepts and displays distribution parameters, (for example, for a normal distribution, the mean and standard deviation). 2. draws a graph of the specified distribution. 3. generates random values drawn from the specified distribution. 4. generates mean expected values (for direct allocations). meanGen*--the mean of generated random values for the last executed Base simulation. marginalValue*--the mean marginal value of the potentialDemand(s) generated by distObject. Resource Table The Resource Table has the following additional fields, each of which is set by the user: unit--e.g., liter, hour, etc. availability--either "fixed" or "buyable." WTMD--wear-and-tear market depreciation. This is the market-value depreciation resulting from using the resource. It is different from, and in contrast to, depreciation occurring solely because of the passage of time. payPrice--the full cash price that needs to be paid to obtain a buyable resource. demandObject*--an object that shows a demand (marginal value) schedule and associated data. If availability is "fixed", then WTMD is applicable and payPrice is not applicable. Conversely, if availability is "buyable," then WTMD is not applicable and payPrice is applicable. WI-cash needs to be included as a resource in the Resource Table. Its quantity is the amount of cash that is available to finance buyable resources. Group Table The Group Table has two additional fields. The fixedAlloc field indicates whether the user wishes to manually set a group allocation. If "Yes" is specified, then a fixed allocation quantity needs to be specified in the second field, fxAlQt. If such a manual setting is done, then the initialization process sets the allocation to fxAlQt and the allocation is not changed by the Axis-walk, Top-walk, Lateral-walk, or Ridge-walk processes. Product Table The Product Table has the following additional fields. Those marked with asterisks (*) are determined by the present invention: fillValue--the value to the organization above and beyond the price paid for the product: For governments and non-profits, it is the estimated societal value of providing a unit of product (service), minus the price, if any, paid. It, plus any paid price, is a monetary, quantitative measurement of a fulfilling an organization's mission by providing a unit of product. It can be estimated subjectively or by using the techniques of welfare economics. For commercial concerns, it is the expected value received beyond the paid price. This would be typically used for new products, when initially building market-share and market-size is of predominate importance. It is the value to the organization of getting customers to buy the product, besides and in addition to, the actual price paid. fillValue can also include the value to the organization of being able to supply a product in order to maintain its reputation as a reliable supplier. distName--the statistical distribution to be used to generate potentialDemand values. Joins with field of the same name in the Distribution Table. distPercent--the percent of the generated random value, from the statistical distribution, that should be used as potentialDemand. carryOver--the percentage of unfulfilled potentialDemand that carries over from one scenario to the next. meanPotentialDemand*--mean scenario potentialDemand for the most recent Base simulation. supplyObject*--an object that shows a supply (marginal cost) schedule, an average opportunity cost schedule, and associated data. The fields distName, distPercent and carryOver replace the earlier potentialDemand field of the Product Table. They are used to generate the previously discussed potentialDemand vector. UnitReq Table The UnitReq Table has an additional field named periodsToCash, which is set by the user. This is the number of time periods between purchasing the resource and receiving payment for the product. This field is only applicable for resources whose availability is "buyable." Results Table The Results Table has fields for both accepting user-defined parameters and reporting optimization results. The latter type fields are marked below with asterisks (*) and are means of scenario results for Base simulations. Not listed, but following each field marked with an exclamation point (!), is a field that contains the standard errors of the marked field: Sequence--table key. Internal Producer's Surplus*!--previously explained. Change in WI-cash*!--mean of scenario-aggregate change in WI-cash. WI-cash--start amount for each scenario; same as a availQuant for WI-cash in Resource Table. Marginal Value of WI-cash*!--mean of scenario-aggregate marginal values of WI-cash; same as a marginal value for WI-cash in Resource Table. Sum Fill Value*!--mean of scenario-aggregate fillValues. Sum WTMD*!--mean of scenario-aggregate WTMD. Allocation--either "Direct" or "Indirect." Maximization Type--either "IPS" or "WI-cash." WI-cash Type--either "Spread-out" or "Fold-in." Spread-out signifies that WI-cash need only finance the current period's buyable resources for the current period, i.e., the financing is spread over multiple periods and no concern about future financing is warranted. Fold-in signifies that WI-cash needs to finance the total current period's expenditure for buyable resources, i.e., all current and future financing is folded-into the current period, which WI-cash needs to cover. Rand Seed--random number generator seed. N Sample--number of scenarios per simulation. MC/MV Display--either: "Partial"--meaning that simple marginal costs (gmcSub) should be used for reporting. "Infinite Series"--meaning that Top-walk marginal costs (twmcSub) should be used for reporting. "Quantum"--meaning that the process used to generate supply and demand schedules should be used to determine marginal costs and marginal values used for reporting. Max Base RW Iterations--times mProd is maximum number of times Basic-Ridge-walk-Iteration 1551 should be executed per base scenario. Max Base RW Time--maximum time that should be spent in Basic-Ridge-walk-Iteration 1551 per base scenario. Max S/D RW Iterations--times mProd is maximum number of times Basic-Ridge-walk-Iteration 1551 should be executed per supply and demand scenario. Max S/D RW Time--maximum time that should be spent in Basic-Ridge-walk-Iteration 1551 per supply and demand scenario. The Sequence field enumerates the rows of the Results Table, with the first row having a Sequence value of 0. Each time a Base simulation is done, all the positive Sequence values are incremented by 1; the row with a Sequence value of 0 is duplicated, the simulation results are stored in this duplicate row, its Sequence value is set to 1. Graphical User Interface The preferred GUI embodiment has four windows: Distributions, Resources, Products, and Results. These windows show all database data, which the user can view and edit. The statistical distributions, allocations-to-effectiveness functions, and supply and demands schedule are shown both tabularly and graphically. The data the user enters and edits is in a foreground/background color combination that differs from the foreground/background color combination of the data determined by the present invention. These windows have state-of-the-art editing and viewing capabilities, including (without limitation) cutting-and-pasting, hiding and unhiding rows and columns, font and color changing etc. Such generic windows and generic capabilities are common for: 1) a personal computer, such as the Apple Macintosh and the systems running Microsoft Windows, and 2) computer work stations, such as those manufactured by Digital Equipment Corp., Sun Micro Systems, Hewlett-Packard, and the International Business Machines Corp. The Distribution Table is shown in its own window. An example of such window, with column titles and sample data rows, is shown in FIG. 18. (The small triangle in the figure is to adjust the bottom of the graph.) The Resource and Group Tables are shown in their own window, with groups defined below the resources they use. An example of such a window with the first few rows is shown in FIGS. 19A and 19B. (The empty oval signifies the compression of an empty table and graph; a solid oval signifies the compression of a table and graph containing data). The Product and UnitReq Tables are merged together in their own window. An example of such a window is shown in FIG. 20. The Results Table is shown in its own window, as shown in FIG. 21. The Next column is for the row of Sequence 0; Current is for Sequence 1; Previous(0) for Sequence 2; etc. Additional table rows are inserted as columns between the Next and Previous(0) columns, with the "oldest" immediately to the right of the Next column. Base Simulation The procedure of the preferred embodiment allocation is shown in FIG. 22, which builds upon the procedure shown in FIGS. 7A and 7B, entails the following: 1. In Box 2201,
______________________________________
for (iProd = 0; iProd < mProd; iProd++)
set sumWICash[iProd] = 0
Join Resource, UnitReq, and Product tables where
.circle-solid. ProductTable.productName = UnitReqTable.productName
.circle-solid. ResourceTable.resourceName = UnitReqTable.resourceName
.circle-solid. ProductTable.productName is product iProd
for (each row of joined table)
if (WI-cash Type = Spread-out)
set sumWICash[iProd] = sumWICash[iProd] + payPrice *
reqQt
else
set sumWICash[iProd] = sumWICash[iProd] + payPrice *
reqQt * periodsToCash
______________________________________
2. In Box 2203,
______________________________________
Clear vector c
set c[m] through c[mn-1] = prices of the mProd products as indicated in
the Product Table of Database 101
for (iProd = m; iProd < mn; iProd++)
set c[iProd] = c[iProd] - sumWICash[iProd - m)
if (Maximization Type = IPS)
set c[iProd] = c[iProd] + (fillValue for product (iProd - m))
Join Resource and UnitReq tables where:
.circle-solid. ResourceTable.resourceName =
UnitReqTable.resourceName
.circle-solid. ResourceTable.availability = "fixed"
.circle-solid. UnitReqTable.productName is product iProd
for (each row of joined table)
set c[iProd] = c[iProd] - WTMD * reqQt
______________________________________
3. In Box 2205,
______________________________________
for (iScenario = 0; iScenario < N.sub.-- Sample; iScenario++)
apply Boxes 2207 through 2211
______________________________________
4. In Box 2207,
______________________________________
if (iScenario = 0)
Use randSeed to generate random seeds for each distribution object.
Cause each distribution object to draw a random number from its
distribution.
for (iProd = 0; iProd < mProd; iProd++)
set potentialDemand[iProd] =
(product's distObject's random value) * distPercent +
carryOver *
(unfulfilled potentialDemand for iProd from previous
period, if it existed)
______________________________________
5. In Box 2209, directly apply Boxes 701 through 711, with the following exceptions: use the c vector generated in Box 2203 exclude from matrix and vector loading all buyable resources include WI-cash as a fixed availability resource load into matrix a sumWICash[iProd] as product iProd's requirement of WI-cash limit the number of times Basic-Ridge-walk-Iteration 1551 is executed to baseMaxRWItertions times mProd limit the total time spent in Basic-Ridge-walk-Iteration 1551 to baseMaxRWTime seconds 6. In Box 2211, compute and note scenario results.
______________________________________
apply Box 713, except note, rather than write, resulting data
if (MC/MV Display = "Infinite Series")
When applying Box 713, apply Box 1203, rather than Box 1701, and
set both gmcSub and gmvAdd equal to twmcSub for each group
in rcMat.
if (MC/MV Display = "Quantum")
for each resource
set resourceQuant = availQuant
apply Boxes 2403 thru 2407
note yielded resource price, in Box 2407, as being marginal
value of resource
for each product
Use bisection search method to find productPrice so that ap-
plying Boxes 2303 through 2309 yields an increment of 1.0
in the number of units produced of the considered product.
Note productPrice as being the marginal cost of producing
the considered product.
set scenIPS = 0
set scenWICashChange = 0
set scenfillValue = 0
set scenWTMD = 0
for (each distribution object)
set marginalValue = 0
for (iProd = 0; iProd < mProd; iProd++)
set quant = (LPP's determined quantity for product iProd)
set price = price of product iProd
set fillValue = fillValue for a unit of product iProd
set cashOut = 0
set wtmdOut = 0
Join Resource, UnitReq, and Product tables where
.circle-solid. ProductTable.productName =
UnitReqTable.productName
.circle-solid. ResourceTable.resourceName =
UnitReqTable.resourceName
.circle-solid. ProductTable.productName is product iProd
for (each row of joined table)
set cashOut = cashOut + payPrice * reqQt
set wtmdOut = wtmdOut + wtmd * reqQt
set scenIPS = scenIPS + quant * (price + fillValue - cashOut -
wtmdOut)
set scenWICashChange = scenWICashChange + quant * (price -
cashOut)
set scenfillValue = scenfillValue + quant * fillValue
set scenWTMD = scenWTMD + quant * wtmdOut
while found (find ii such that:
.circle-solid. b[ii] = 0
.circle-solid. B[ii] [iProd] > 0
.circle-solid. there exists a jj such that:
c[jj] < 0 and a[ii] [jj] < 0)
if (ii found)
Pivot row ii as described in Box 1117
endwhile
set pDistObject = pointer to distribution object used to generate
potentialDemand[iProd]
set pDistObject -> marginalValue =
pDistObject -> marginalValue +
(- c[iProd) * bOrg[iProd]/potentialDemand[iProd])
______________________________________
7. In Box 2213, compute means and standard errors of scenIPS, scenfillValue, scenWICashChange, scenWTMD (of Box 2211) and update Results table. For each distribution, compute the mean of scenario marginalValue as calculated in Box 2211 and update distribution table. Compute means of resource and product quantities and marginal values/costs; update appropriate tables. Update GUI database display. Supply Simulation The procedure to generate product supply schedules is shown in FIG. 23. For expository purposes, the supply schedule being generated is for a product iProdSup and will have prices between lowPrice and highPrice with fixed increments. This entails, 1. In Box 2301,
______________________________________
for (productPrice = lowValue; productPrice < highPrice;
productPrice = productPrice + increment)
apply Boxes 2303 through 2309
______________________________________
2. In Box 2303,
______________________________________
apply Box 2201
apply Box 2203, but use productPrice as the price for product iProdSup
for (iScenario = 0; iScenario < N.sub.-- Sample; iScenario++)
apply Boxes 2305 and 2307
______________________________________
3. In Box 2305, apply Boxes 2207 and 2209, except in Box 2209: Limit the number of times Basic-Ridge-walk-Iteration 1551 is executed to S/D.sub.-- MaxRWItertions times mProd Limit the total time spent in Basic-Ridge-walk-Iteration 1551 to S/D.sub.-- MaxRWTime seconds 4. In Box 2307, note produced quantity of product iProdSup. 5. In Box 2309, compute mean of noted produced quantity of Box 2307. This mean and productPrice determine a point of the supply schedule. 6. In Box 2311, write supply-schedule-data points to database. Update GUI database display. To also generate the average opportunity cost curve for iProdSup, the following is required: At the start of Box 2301,
______________________________________
set productPrice = 0
set dSumBase = 0
apply Boxes 2303, 2305, and 2307
immediately after Box 2307, set dSumBase = dSumBase + .vertline.d.vertline
______________________________________
At the start of Box 2303,
_________________________ | ||||||
