Document 11139012

advertisement
Multi-region Capacity Planning Model with
Contracts of Varying Duration under Uncertainty: A
movou
Satellite Capacity Acquisition Case Study
MASSACHUSETTS INSflJTME
OF TECHOLOGY
by
JUN 19 2014
John M. Lydiard IV
LIBRARIES
Submitted to the Engineering Systems Division
in partial fulfillment of the requirements for the degree of
Master of Science in Engineering Systems
at the
MASSACHUSETTS INSTITUTE OF TECHNOLOGY
June 2014
This material is a declared work of the U.S. Government and is not
subject to copyright protection in the United States.
Signature redacted
A uthor ....................................
Engineing Systems Division
May 18, 2014
/ 1
Certified by.................
Signature redacted
Olivier L. de Weck
Professor of Engineering Systems
Thesis Supervisor
Accepted by......Signature
redacted
Richard Larson
Mitsui Professor of Engineering Systems
Chair, Engineering Systems Division Education Committee
Multi-region Capacity Planning Model with Contracts of
Varying Duration under Uncertainty: A Satellite Capacity
Acquisition Case Study
by
John M. Lydiard IV
Submitted to the Engineering Systems Division
on May 18, 2014, in partial fulfillment of the
requirements for the degree of
Master of Science in Engineering Systems
Abstract
This paper highlights the issues associated with and presents a modeling framework
for long-term capacity planning problems constrained in a similar fashion to satellite
capacity acquisition. Although ambiguities exist, the satellite capacity planning problem also contains many clearly defined constraints. In the immediate time horizon,
universal satellite capacity is fixed, as satellite launches are rare, and each incremental
satellite launch only marginally increases capacity. In the world of Commercial Satellite Communications (COMSATCOM), satellites have fixed coverage areas as they are
typically in geo-synchronous orbit. Other military applications such as observation
and satellite phone require, low-earth orbit and medium-earth orbit satellites. The
contracts used to acquire satellite capacity from the commercial sector also clearly define constraints, such as start and end date, bandwidth, price per unit bandwidth and
allocated satellite system, which also implies frequency and available capacity. The
paper first reviews the issues involved with planning capacity acquisition, and then
presents a modeling framework for developing strategies to meet criteria and minimize cost. A simulation environment is developed for testing contracts and satellites
of different parameters against varying demand distributions. A dynamic program is
used to solve the integer program associated with selecting satellite capacity levels to
cover demand.
Thesis Supervisor: Olivier L. de Weck
Title: Professor of Engineering Systems
3
4
Acknowledgments
I thank my advisor, Oli, for providing guidance throughout my time at MIT and for
encouraging me to explore my own interests within Engineering Systems. I also thank
Professor George Kocur for being a tremendous teacher and mentor in and out of the
classroom.
MIT Lincoln Laboratory and the US Air Force provided me the opportunity to
study at MIT. I sincerely appreciate the opportunity. In addition, I acknowledge my
group leader, Dr. Marc Viera, for his support and advice, and Mr. John Kuconis for
his integral role in the Military Fellows Program.
Lastly, I thank my parents for being fantastic role models and for motivating me
in every chapter of my life.
This work was sponsored by the Department of the Air Force under contract FA872105-C-0002. Opinions, interpretations, conclusions, and recommendations are those of
the author and are not necessarily endorsed by the United States Government.
5
6
Contents
1
Introduction
15
1.1
Motivation and Background
. . . . . . . . . . . . . . . . . . . . . . .
15
1.2
Conclusions from DBB Analysis . . . . . . . . . . . . . . . . . . . . .
18
1.3
RAND - Wideband Investment Options . . . . . . . . . . . . . . . . .
18
1.4
RAND - Providers and Contracts . . . . . . . . . . . . . . . . . . . .
23
1.5
Conclusions from RAND Study . . . . . . . . . . . . . . . . . . . . .
24
1.6
Emerging Technological Uses and Growth
. . . . . . . . . . . . . . .
25
1.6.1
Demand Growth Within Contingencies . . . . . . . . . . . . .
26
1.6.2
Global Demand Growth
. . . . . . . . . . . . . . . . . . . . .
27
Where the RAND model left off . . . . . . . . . . . . . . . . . . . . .
30
1.7
2 Mathematical Formulation and DP Model
2.1
2.2
33
Integer Program Formulation
. . . . . . . . . . . . . . . .
. . .
33
2.1.1
Parameters of Interest
. . . . . . . . . . . . . . . .
. . .
33
2.1.2
Decision Variables
. . . . . . . . . . . . . . . . . .
. . .
34
2.1.3
Objective Function . . . . . . . . . . . . . . . . . .
. . .
34
2.1.4
Constraints
. . . . . . . . . . . . . . . . . . . . . .
. . .
35
Dynamic Programming Solver . . . . . . . . . . . . . . . .
. . .
35
2.2.1
Modeling Methodology . . . . . . . . . . . . . . . .
. . .
35
2.2.2
Stages, States, Nodes and Arcs
. . . . . . . . . . .
. . .
36
2.2.3
Modeling Questions . . . . . . . . . . . . . . . . . .
. . .
37
2.2.4
Model Assumptions . . . . . . . . . . . . . . . . . .
. . .
37
2.2.5
Tradeoffs Between Long and Short Term Contracts
. . .
39
7
. . . . . . . . . . . . . . .
39
. . . . . . . . . . . . . . .
44
Pseudo-code . . . . . . . . . . .
. . . . . . . . . . . . . . .
44
Standalone Options . . . . . . . . . . .
. . . . . . . . . . . . . . .
46
2.2.6
2.3
DP Simulation - Adding Uncertainties
2.3.1
2.4
3
49
Results
. . . . . . . . .
. . . . .
49
Deterministic Results . . . . . . . . . .
. . . . .
49
3.2
Results with Options Contracts . . . . . . . .
. . . . .
53
3.3
Results with Multiple Runs
. . . . . . . . . .
. . . . .
53
3.4
Time Complexity . . . . . . . . . . . . . . . .
. . . . .
57
3.4.1
Leading Indicator . . . . . . . . . . . .
. . . . .
57
3.4.2
Adding Detail without Adding Time
.
. . . . .
58
3.4.3
An Alternative Representation . . . . .
. . . . .
60
3.1
Small Deterministic Example
3.1.1
4
Pseudo-code . . . . . . . . . . .
61
Conclusions
4.1
Thesis Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
4.2
Future Work and Potential Uses . . . . . . . . . . . . . . . . . . . . .
62
65
A DP Code - Java
Contract Scheduler . . . . . . . . . . . . .
65
A.2 Demand Generator . . . . . . . . . . . . .
75
A.3 Satellite . . . . . . . . . . . . . . . . . . .
81
A.4 Main() Method . . . . . . . . . . . . . . .
84
A.1
B Web Application Code - Ruby on Rails
93
B .1 V iew . . . . . . . . . . . . . . . . . . . . .
93
Controller . . . . . . . . . . . . . . . . . .
117
B .3 M odels . . . . . . . . . . . . . . . . . . . .
118
B.4 Database Migrations . . . . . . . . . . . .
120
B.2
8
List of Figures
1-1
Defense Business Board - COMSAT Acquisition Approaches
. . . . .
17
1-2
RAND Growth Projections . . . . . . . . . . . . . . . . . . . . . . . .
19
1-3
RAND Contingency Data
. . . . . . . . . . . . . . . . . . . . . . . .
22
1-4
RAND - Effect of Delivery Lag on Sat Purchase . . . . . . . . . . . .
24
1-5
Mbps Used Per 5000 Troops . . . . . . . . . . . . . . . . . . . . . . .
27
1-6
Futron COMSAT Demand Projection . . . . . . . . . . . . . . . . . .
28
1-7
Rising Government Contract Costs
. . . . . . . . . . . . . . . . . . .
28
1-8
Transponder Equivalent and Mbps
. . . . . . . . . . . . . . . . . . .
29
1-9
Futron - Supply Chart by Provider, Region and Frequency . . . . . .
31
3-1
Two Satellite, Three Region, Twelve Mo. Contract Results . . . . . .
50
3-2
Two Satellite, Three Region, Six Mo. Contract Results . . . . . . . .
50
3-3
Two Satellite, Three Region, Three Mo. Contract Results . . . . . . .
51
3-4
BW Provided by Contract and Demanded in Region 1
. . . . . . . .
51
3-5
Cumulative Cost by Contract of a run
. . . . . . . . . . . . . . . . .
51
3-6
Cumulative Costs with Fixed Capacity Contract Types . . . . . . . .
52
3-7
BW Supplied and Demand for Region 1 With Multiple Contract Types 53
3-8
Single Run With Options Contract
3-9
Cost Histogram by Contract for Two Sat, Three Reg
. . . . . . . . . . . . . . . . . . .
54
. . . . . . . . .
55
. . . . . . . . . . . . . . . . . . . .
55
3-11 Cost Histogram - Nine Contract Types . . . . . . . . . . . . . . . . .
56
3-12 Cumulative Cost - Nine Contract Types
. . . . . . . . . . . . . . . .
56
3-13 Number of Steps to Nodes . . . . . . . . . . . . . . . . . . . . . . . .
58
3-10 Satellite Level by Contract Type
9
10
List of Tables
1.1
RAND - Lease Prices and Contract Duration . . . . . . . . . . . . . .
23
1.2
Example Regional Cost Comparison . . . . . . . . . . . . . . . . . . .
30
3.1
Average Utilization for All Regions
. . . . . . . . . . . . . . . . . . .
52
3.2
Utilization as Precursor to Spending
. . . . . . . . . . . . . . . . . .
58
11
12
List of Algorithms
1
Dynamic Program - Contract Scheduler Constructor . . . . . . . . . .
40
2
Dynamic Program - Build Source . . . . . . . . . . . . . . . . . . . .
41
3
Dynamic Program - Build Center . . . . . . . . . . . . . . . . . . . .
42
4
Dynamic Program - Build Sink
. . . . . . . . . . . . . . . . . . . . .
43
5
Dynamic Program - Back Path
. . . . . . . . . . . . . . . . . . . . .
43
6
Distribution Generator . . . . . . . . . . . . . . . . . . . . . . . . . .
44
7
Demand Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45
13
14
Chapter 1
Introduction
1.1
Motivation and Background
The Office of the Deputy Secretary of Defense commissioned a report analyzing the
opportunities in the commercial satellite industry space to address Department of
Defense (DoD) demand for Commercial Satellite Communications (COMSAT). The
tasked force, the Defense Business Board (DBB), found commercially acquired services to account for approximately 40% of DoD satellite communications (SATCOM)
services at $640M annually. The private sector provides many contract vehicles for
acquisition ranging from immediate (i.e. daily or weekly contracts) to annual or
multi-year agreements, with either upfront or periodic costs. However, several policies limit decision making including Federal Acquisition Regulations (FAR), Planning,
Programming, Budgeting and Execution, and statutory limits [5, p. 1].
The SATCOM market can be divided into three sub-categories: Military SATCOM (MILSAT), Civillian Government SATCOM (GOVSAT), and Commerical SATCOM (COMSAT). The DoD controls all MILSAT procurement through the United
States Air Force Space and Missile Command (SMC). The Defense Information Systems Agency (DISA) uses General Services Administration (GSA) contracts to purchase COMSAT solutions. SATCOM comprises 58% of the total satellite market
worldwide.
Within the SATCOM market, COMSAT constitutes 65% of capacity,
where as MILSAT and GOVSAT only represent 15% and 20% respectively
15
[5, p.
2]. Military procured satellites have many different requirements, including nuclear
hardening and additional security measures, as well as different attributes, such as
much longer procurement time horizons and higher associated costs than commercial
satellites. This thesis focuses on the case study of COMSAT acquisition, but the
analysis and model could be extended to incorporate long-term projects and will be
discussed later.
Procurement for COMSAT is split between two categories of contract vehicles:
one year leases and "spot market" purchases which comprise 75% and 25% of services
acquired respectively. According to the report, DISA expenditures are expected to
grow to $3-$5B over the next fifteen years [5, p. 4]. According to Northern Sky Research, DoD's SATCOM needs will increase by 68% over the next ten years due to a
policy shift to focus on Asia-Pacifc affairs, increased Naval activity, increased surveillance of world events and a larger role in the "war on drugs" [5, p. 5]. Technological
advancements have given rise to the COMSAT industry as demand for consumer services such as satellite television, including high definition, satellite internet, and radio
have increased. COMSAT "fill-rates" are as high as 80%, without DoD participation,
DoD must prepare for instances of limited supply, and therefore rising prices [5, p.4].
COMSAT is less expensive and has shorter development cycles than MILSAT.
The average time from concept to launch is 3-4 years in the private sector, and 5-15
years for DoD projects
[5, p. 6]. Considering the tightening military budget con-
straints, and that sequester-level funding returns in 2016, DoD must use every dollar
as efficiently as possible. Given the constricting budget and forecasted rising demand,
COMSAT will play a critical role in supplying the military necessary bandwidth to
accomplish its mission.
"Currently, DISA uses indefinite deliver, indefinite quantity (IDIQ) contracts to
obtain three types of commercial satellite services: (1) "bent pipe" service; (2) buy
bandwidth directly; and (3) provide end-to-end support services"
[5, p. 8].
The
GSA defines the circumstance of IDIQ use as, "when GSA can't determine, above a
specified minimum, the precise quantities of supplies or services that the government
will require during the contract period" [1]. The exact mechanisms of the contract
16
Traditional and non-traditional
approaches for COMSAT acquisition
Traditional and non-traditional obstacles
for COMSAT acquisition
Buy to Lease
Make offer to a commercial operator for system use and
obtain quid pro quo global service access for discount/zero
ch~argetrauyv.loasevcacesdl
tFunds deiglva ser ce acce
Capital Lease
Long term lease for satellite life (>1 yrs)
Anchor Tenancy
Indefeasible Right
of Use (IRU)
st g
to
the national
Programmers resist O&M dollars for investment (termination
liability, competitive annual priorities); Procurement dollars
ineligible for these deals; Existing regulation is for 5 year max
lease option
NASA/NOAA ability to enter into multiyear contracts to serve Termination liability concerns; Statute limited to
NASA/NOAA3 - AT&L offering changes; Cannot be used for
as the anchor tenant for commercial space ventures.
COMSAT unless approved by Congress
Pays for up-front costs; signs agreements with others to get
services and pays a large up-front fee, followed by annual
Failed providers pulling out early; poor pricing methods
charges for maintenance and upkeep
Congress uncomfortable committing dollars beyond first year
Multi-year contracts are limited to 5 years; Termination
liability concern
Multi-year/Long
term lease
Opportunity to reduce cost with longer leases
Hosted Payloads
DoD furnished payload;
Pathfinder
Long term solution with little time to solve near term budget
issues and potential demand with the ongoing challenge
Finding optimal approach to leverage COMSAT technologies; to accept large scale non-traditional approaches to satisfy
long term solution
requirements; acquisition, policy and legal concerns manifest
risk
special
needs; short timeframe
Timely ITU frequency coordination to bring service into use;
current NTIA spectrum certification policy requires project
funding prior to filing; adds significant delay to timeline; US
launch vehicle requirement per Space Trans. Policy
Figure 1-1: Defense Business Board - COMSAT Acquisition Approaches
vehicles in place is unclear, and they likely vary from vendor to vendor. But, one
could assume that the government is paying a premium for the flexibility of "indefinite quantity." Beyond the traditional immediate to year-long leases through IDIQ
contracts, the DBB identified several non-traditional approaches, listed below in a
table from the report [5, p.8].
Buy-to-lease, capital lease, anchor tenancy, and long-term strategies all run into
the same political obstacles, namely that Congress will not commit to leases greater
than 5 years due to "termination liability." As the law states, in the event the government terminates a contract, the government must reimburse the contractor for a
substantial amount of unrecoverable costs for the planned services [11]. Indefeasible
Right of Use utilizes a terrible incentive structure, with most of the cost paid for up
front. Hosted payloads provide a great opportunity for saving on launch costs. However, aside from potentially conflicting launch vehicle requirements between agencies,
this approach still requires unique satellites to be built, meaning high costs and long
time horizons.
The Defense Business Board ultimately recommended a near term aciton to take
17
advantage of long-term/ capital lease agreements. "By implementing commercial capital leases in multiple increments for up to 10-15 years to meet [needs], DoD could
save up to $100M per year" [5, p.10]. This approach is not politically viable, and by
committing to long-term contracts the government inherits tremendous liability risk.
This thesis will suggest alternative solutions which are viable, cost-effective and less
risky, by using optimal allocations of proven contract vehicles.
1.2
Conclusions from DBB Analysis
An important takeaway is the current split in COMSATCOM agreements:
75%
are one year leases and 25% are at "spot market" rates. This ratio will serve as a
benchmark for qualifying model performance. Contract limits have an upper bound
of five years, due to statutory restrictions. COMSAT "fill-rates" should be considered
a source of uncertainty that can affect decision making. For example, if a consumer
knows the possibility that supply may be extinguished for a given time period exists,
the consumer will become more likely to purchase supply in advance of need, as it
becomes available. Although this random variable is not included in the model, future
extensible models should consider this.
The Pathfinder initiative could provide valuable insight if new contract vehicles
are actually evaluated. This thesis hopes to introduce a modeling framework which
could be valuable in identifying theoretical contractual constructs which could then
be used on a micro-scale in the Pathfinder program before being launched at the
national level.
1.3
RAND - Wideband Investment Options
In 2000, RAND published the most comprehensive public study on COMSAT acquisitions to date. The study focused on high-bandwidth (voice, video, data), minimally
protected SATCOM. Motivation for the report stemmed from a growing demand for
satellite communications and a lack of planned military owned capacity. RAND uti18
se
-
isid e sponmm
--
ryaP raiO
moDai ymin
14
.
Prmybayw
n
l
Suppay
S
0
00
Figure 1-2: RAND Growth Projections
lized the Advanced Military Satellite Communications Capstone Requirements Document. Gleaned from this document were two important implicit assumptions: military and political leaders do not want operations constrained by communications, and
whatever bandwidth is necessary will be available [4, p. 7j. Furthermore, increased capacity was deemed necessary due to emerging military doctrine, such as UAV use, and
"uncertainties posed by unknowable timing of future contingencies" [4, p.3j. RAND
projected steady growth over the 2000-2010 time frame, across three types of demand:
1. Crisis Response - Additional capacity needed to respond up to two major theater
wars or four small-scale contingencies
2. Daily military operations
-
Capacity needed for routine patrols, tactical intelli-
gence and training
3. Day-to-day
-
Minimum capacity needed to ensure vital peacetime communica-
tion
The projects attempt to capture the trends at the time, but of course do not account
for the variance inherent in demand.
The illustration is simply useful for under19
standing the shortfall in military capacity for anticipated bandwidth and serves as
motivation for investigating acquisition strategies.
To satisfy the shortfall, the study considered the following investment options:
" DoD-unique satellite purchase
" Whole commercial satellite purchase
" Fractional commercial satellite - transponder or fixed bandwidth lease
" Communications service agreements [4, p. 20]
The military typically makes acquisitions based on operational needs, and cost is
only a criterion for differentiating among viable solutions, not the primary criteria.
Thus, these options were evaluated against the criteria outlined in the Capstone
Requirement Document:
* Capacity - Is enough throughput provided?
" Coverage - Are regions of interest covered?
" Flexibility - Will multiple operation types and applications be supported?
" Interoperability - Can the investment integrate with existing organizations and
technology?
* Access and Control - Will the option be available and accessible when and where
needed?
* Quality of Service - Will the option meet specifications for reliability, bit error
rate and outage responsiveness?
* Protection - Can the option survive attack and can it withstand jamming attempts? [4, p. 22]
These criteria provide the basis for evaluating acquisition options and versions of the
attributes that will be used in modeling. Capacity is more than sufficient in providing
20
DoD the necessary bandwidth. Commercial providers cover the same areas of interest where the military has concerns. To maximize flexibility, the use of both military
and commercial systems is paramount. The Federal Communications Commission
(FCC) has authorized certain frequencies bands within Ulta-high Frequency (UHF),
X-band, and Ka-band as exclusive military use [4, p.18]. However, C and Ku bands
have been authorized as commercial bands and the military can only operate within
these bands on a strictly "noninterferance" basis, meaning DoD wholly owned systems cannot operate in these frequencies. If DoD wants to maximize flexibility, DoD
must lease capacity on commercially owned satellites which operate in C and Ku [4,
p.93]. Interoperability is largely a ground terminal configuration question, which this
thesis will not address.
Satellite purchases provide the greatest degree of access and control. Satellite
orientation and beams can be reconfigured on the fly, whereas with leases the satellite bus will rarely be controllable; the military can only manage the transponders it
leases. On COMSAT buses, spot beams could not be moved without permission of
other users leasing capacity. Flexibility in this case could be enhanced by negotiating
the ability to "reassign transponders rapidly between beams throughout the satellite
coverage area" [4, p.63]. Quality of Service is not a factor in evaluating COMSAT
contract vehicles as providers regularly maintain reliability well over 99%. For example, in 2008, TransCore, a logistics tracking company, announced its satellite network
achieved 99.992% uptime in 2007 [8].
Protection is the one criteria important to military activities which COMSAT
providers do not satisfy, and will not anytime soon. Security measures of any kind are
costly in terms of both development time and expense. Thus, commercial providers
build "minimally protected" satellites in the interest of time and money, as they are
motivated by profits. Fortunately, the government could leverage the relatively less
expensive unit price of commercial capacity to improve surviveability. If DoD leases
some capacity on every satellite in a given region, the task of disrupting or jamming a
military satellite becomes overly complex [4, p. 75]. Other security measures will be
left to the experts. For this thesis, it will be assumed that the demand being satisfied
21
Figure 1-3: RAND Contingency Data
accepts the protection risk.
In addition to providing criteria for evaluating investment options, RAND identified key characteristics of the aforementioned types of military demand. RAND
received US military contingency data from 1990-1997, pictured below [4, p. 100].
Contingencies with more than 100, but less than 5,000 troops were considered smallscale contingencies (SSC), between 5,000 and 15,000 troops were considered mediumscale, and between 5,000 and 45,000 were considered large-scale. On average, ten
contingencies began each year, with 6.5 ongoing. Of the ongoing contingencies, 0.9
were large, 2.7 were medium and 2.9 were small. RAND estimated that any given
time approximately 58,000 troops were deployed in contingencies. The median contingency duration was 3 months [4, p. 90]. Unfortunately, the study did not disclose
the relative frequency on contingencies by region, but only reported global numbers.
The important conclusions from this data is that much of the variance in military demand is derived from contingencies, and this concept presents three random variables
of interest: contingency occurrence, contingency size given contingency occurred, and
contingency duration given contingency occurred. A fourth random variable could be
the decay rate of contingency size as the conflict dwindles.
22
1.4
RAND - Providers and Contracts
Before comparing the investment vehicles, the COMSAT market, which negotiates
trade of long and short term contracts, must be understood. Long term contracts,
generally of durations one year or more, can be preemptible or nonpreemptible. Preemptible service can be taken from one user and given to another with higher priority,
after a "notification period" which can vary between instantaneous to weeks depending on terms. Significant discounts are associated with preemptible capacity. On
the other hand, a consumer could choose to buy additional levels of assurance, for a
premium [4, p. 87].
Capacity not sold in the form of long term contracts is sold on the Ad Hoc Market,
for duration periods less than one year and as short as one day. Ad hoc capacity is sold
directly by satellite owners and can be resold by customers [4, p. 88]. Unfortunately,
DoD does not resell capacity, even when it has excess, due to political limitations,
though this option should be explored by policy makers.
The market tends to dry up when war or natural disaster strikes, as one might
expect, particularly over "thin routes," areas with few systems. This is what happened during the Gulf War '90-'91. In these instances, leaseholders sometimes have
the provider sublet excess capacity [4, p. 89]. The prices in Table 1.1 reflect market
rates in 1999, assuming a 3.6% discount rate and 4% annual declining price trend.
Although the rates themselves are dated, the relative differences are still important
for modeling trade-offs, and are likely persist over time. Despite their attractive
Table 1.1: RAND - Lease Prices and Contract Duration
Acquisition Method Price (Gbps-Year) Duration
Transponder lease
Transponder lease
Transponder lease
Transponder lease
Satellite Purchase
$274M
$154M
$77M
$58M
$48M
1 week
3 months
1 year
10 years
10 years
steady-state appeal, purchasing satellites to cover all demand projections is not ideal
for several reasons. This would limit flexibility as the military is only allowed to use
23
RANW~UN412
I
I
I.
I
I
700o
500
400
'00/1 .0.Purctagee-noY
200
100
0
0
1 2 3 4
5 6
7
8
reeit
Purchae-6year ordsr-"O
feitI
oemm
I.Yearleee
No"
1O0"erl
9 10 11 12 13 14 15 16 17 18
Year
19
8OURCE RAND
Ptgum S. 1Z-Ptmat Cost( IGbp aaPudon of Strategy and Year
Figure 1-4: RAND - Effect of Delivery Lag on Sat Purchase
certain frequencies, and would be excluded from strictly commercial bands (C-band).
Demand is not steady state. It is highly variable and growing. Most significantly,
there is a substantial lag-time between capital investment and return on that investment, in the form of lower marginal costs. The more current Defense Business Board
analysis indicated that commercial satellites take more than 3 years and military
satellite deliveries take longer than five. When the lag time on delivery is factored in,
leases one year and longer are cheaper for the first ten years [4, p. 123].
Unless protection or other special characteristics are worth the discrepancy in
price, satellite purchases are not economically viable, especially when considering the
changing rate of technology.
1.5
Conclusions from RAND Study
The RAND study provides several major insights. The first being criteria to grade
investment options against, and also logical constraints for modeling satellite capacity
acquisition. Assuming rising military satellite bandwidth demand, and realistic delivery times for satellite purchases, demand cannot be satisfied by satellite purchases
24
effectively without exorbitant costs and long lead times.
A baseline for contract
comparisons was also provided, and an step-wise linear equation was derived as an
approximation.
As noted earlier, current protocol has led to purchases of contract vehicles with
durations that do not exceed 1 year. This may be due to providers requiring large
upfront commitments. However, the RAND study shows that savings can be achieved
with longer-term contracts, although diminishing after 1 year. These longer term contracts should be used to satisfy demand which is very likely to wane. For example,
if demand in region 1 is fluctuates around 10 Gbps/year, then long term contracts
should satisfy 1-2 Gbps/year, or some demand which is unlikely to be Furthermore,
the growth rates in use described earlier, indicate a trend in desire for persistent
global coverage. If one can reasonably expect the growth rates to remain positive
for decade, long-term contracts should be invested in. The assumption could be validated by determining what global capacity is needed to have persistent coverage in
all regions for "routine" tasks, and compare that number to actual global coverage
by region.
Assuming that committing to a longer-term contract will cost less, given US payment track record and that contractually obligated payments eliminate revenue risk
on the provider-side, DISA should negotiate a payment schedule which does not provide an up-front cost, but rather slightly higher payments that yields the same NPV.
The private sector is interested in immediate payment due to their risk profile associated with satisfying shareholder interests sooner rather than later. The desired
payment schedule of the private-side indicates that the possibility of options contracts
may be well received.
1.6
Emerging Technological Uses and Growth
Many modern factors contribute to COMSAT growth worldwide in both the public and private domains. For worldwide consumers, demand has spiked for satellite
television, internet and high definition broadcasting. For the US government, the
25
first important factor to be considered is the growth in UAVs, both domestically and
abroad. In February 2012, Congress passed the FAA Reauthorization Act to enable
the testing and commercial licensing of domestic drones by 2015. According to the
FAA, as many as 30,000 drones could be patrolling the continental United States
by 2020. [191. Undoubtedly, part of this surge will be used for border patrol in the
increased fight against the "war on drugs" as the Defense Business Board report indicated. Other domestic uses will begin to surface in the coming years, as innovators in
the domestic economy attempt to profit off the new regulations. For example, Amazon has announced Amazon Prime Air, a service which plans to deliver goods from
its warehouses in thirty minutes or less utilizing Amazon UAVs. The company claims
to be ready launch as soon as the FAA establishes governing rules, and is anticipating
a 2015 launch [6].
1.6.1
Demand Growth Within Contingencies
In many contingencies similar to the ones examined by RAND, the US military has
seen growth in satellite use per troop over recent years. Col Patrick Rayerman examined conflict usage data for recent Middle Eastern conflicts and found a relationship
between Mbps per 5000 troops in conflicts over time. The graph below contains his
published results [18].
Certainly this data alone would suggest increased satellite
usage within the last decade. This data is normalized by conflict size. However, it
is conceivable that conflicts in the future will require less personnel and may be won
through strategic and technological superiority. Furthermore, recent political statements, executive orders and actions from the executive branch indicate a political
shift to a "leaner force," focused on special operations
[7].
This data should only
be treated as a possible indicator of increased reliance on satellite communications.
Trends in conflict size need to be measured.
26
Alctual and Projected
350-
Mbps
Used
per
5,000
Military
Members
300-W
250200-
# T
150100-
0-
Desert
so
1990
4
Enduirlpna
Freedom
lrqi Freedom
Noble
Anv
1995
2000
2005
201 0
2015
2020
Figure 1-5: Mbps Used Per 5000 Troops
1.6.2
Global Demand Growth
The demand RAND projected in 2000 has been realized. In 2010, Futron published
its military segment forecast which showed realized demand in 2009. According to
Futron, the US comprises an estimated 90% of the global military demand provided
commercially [16].
This demonstrates that the growth was realized and still anticipated by industry
experts in the future. Furthermore, the differences in projections by region illustrate
that demand distributions can vary widely by region for any given time period.
In
addition to rising total usage, DoD also faces rising prices per unit bandwidth. In
the graphic below, a prominent government contract vehicle, DSTS-G, is compared
against the market average in Europe and the Middle East [9]. Transponder Equivalent (TPE) is simply a normalized metric for comparing bandwidth consumption, and
typically represents 36 MHz of capacity [12]. The exact number of bits-per-second
for a given TPE depends largely on the signal-to-noise ratio, which is a result of
the technology used and physical distances. RAND explains that the achievable data
rate depends on "waveform used, the effective isentropic radiated power (EIRP) of the
satellite beam, and the size of the ground terminals used" [4, p.28]. Futron published
a forecast on the average relationship between Mbps and TPE [14]. Understanding
27
. .........
. ........
-
SuuVew
fast
A"M
(%AI
AsiaifA
EtaMu AP
SWibSahwAii Afrca JSSA
SMifr
Eail & Nortti Africa MI[NA
fauMrfuropIEEUP
MI E
UI
aW e oe n fEu r cipe( W Ef
Il
suum
6 Not"v
Figure 1-6: F
Amewa~
Amci.a
C MAill De an PXrocl
Figure 1-6: Futron COMSAT Demand Projection
$2.5
$2.1
$2.2
$2.1
$2.0
$1.5
$1.0
2009
2008
2010
Fiscal Year
m Europe and Middle East/Africa Market Average TPE Cost
Europe and Middle East/Africa DSTS-G Average TPE Cost
Source: FY 2010 Commercial Satelite Communicaions Usage Report
Figure 1-7: Rising Government Contract Costs
28
iSAMI
CNAM
C
North American Demand
2009 - 2019
2,500
0
0
9
2
140
120
2
100
~1~ooo6040D
5W0
20
0
0
2009
2011
2013
2015
2017
2019
TPEs 4@9Mbps
Source: Futron's 2010 Forecast of Global Satellite Services Demand
Figure 1-8: Transponder Equivalent and Mbps
the relationship between TPE and Mbps is important as different resources use both
bits per second and Hz to compare bandwidth.
In 2009, the ratio was roughly 57
kbps per TPE, based on the Futron graph.
The Defense Information Systems Network (DISN) created the Satellite Transmis-
sion Service-Global (STS-G) contract (DSTS-G) to leverage both long-term pricing
advantages as well as options. Government contracts include both DSTS-G and NonDSTS-G. DSTS-G represents a 3-year contract with 7 one year options [2].
Thus,
due to bulk purchasing, the contract should be less expensive than the average mar-
ket rate. For the first time, DSTS-G surpassed the average market rate in 2010
[91.
The reason for DSTS-G surpassing the market rate is due to differences in regional
mix, as a larger portion of DoD capacity is focused in more constrained regions such
as Europe and the Middle East. Thus, trade-offs between unit pricing by region is
important to consider for planning purposes. An example of what differences could
like is in the table below.
This table is strictly for illustrative purposes.
As there are many confounding
variables. For example, although certain regions may be more expensive, it may be
due to providers in the region, frequency bands employed, or combinations thereof.
29
Table 1.2: Example Regional Cost Comparison
Middle East/Africa
$M
MHz
$/Hz
Rate/Avg.
Avg ($/Hz)
300
3900
0.07692
0.805245871
0.09552744
North America
Europe South America
120
100
1900
1500
0.06316
0.06667
0.661149241 0.69787975
20
180
0.11111
1.163132924
Asia
North Africa
Sub-saharan Africa
15
80
0.18750
1.96278681
20
250
0.08000
0.837455706
25
300
0.08333
0.872349693
A complete data set on all price points for all satellites, with all attributes, including
provider, frequency, capacity, reliability and so forth should be maintained in order
to separate effects on each component for modeling purposes.
Spending not only varies across contract type, but also varies across frequency
band. For FSS, the frequency bands employed are C, Ku, C-Ku (Crossband), Ka and
X. Each band has a different frequency range and thus different attributes which allow
for different applications. For example, C-band is used for television broadcasting and
raw satellite feeds. It is also widely used in regions affected by heavy rainfall as it
is less susceptible to "rainfade" (absorption of signal by atmospheric rain), than its
popular counterpart Ku-band [3]. Thus, DoD is interested in utilizing all frequency
bands for application access as well as redundancy to ensure reliability.
The supply chart below, by band and vendor, illustrates realistic constraints in regions
[13].
This reality makes price comparisons by vendor and operator also important.
As previously mentioned, a full statistical analysis on a complete satellite data,
or complete contract set, which includes attributes for frequency band, vendor and
operator, should be performed for vendors and operators.
The aforementioned factors, namely contract duration, region, capacity, frequency,
and provider, serve as important attributes in modeling contractual decision-making.
1.7
Where the RAND model left off
RAND's modeling efforts in 2000 utilized global demand projections, and examined
the trade-offs between long and short term contracts without regard to regional differences or the inherent discrete nature of satellites. The analytical method they
developed for determining optimal capacity is based on their expected cost equation
30
GEO COMMERCIAL FSS SATELLITE CAPACITY SUPPLY DISTRIBUTION 10/201
and
Ku-band
-ftw
C-be
r o"A'zj
C-bsnd
P.
Ku-band
KiU-band
04obnd
I
Ku-band
Intelsat
SES
Telesat
Eutelsat
Other
Figure 1-9: Futron - Supply Chart by Provider, Region and Frequency
which is listed below [4, p. 137J:
(x
C = Pa +Ps j
-
a)f(x)dx
" pa is the price of a
* a is the amount of fixed capacity
" p, is the spot market price
* x is communications demand
* f(x) is the distribution of demand x
This may serve as a useful bounds in individual regions if extreme prices are used
for Pa and p. However, this analytical method is not sufficient for determining how
capacity should be allocated across satellites, and ultimately contract vehicles which
must specify the satellite being used.
31
RAND concluded, where access and control and protection are not critically important to the mission, commercial assets can be leveraged to satisfy military demand
and improve criteria related to flexibility, capacity, coverage and average cost. In
terms of allocation strategy, the recommendation was "it may be more economical
to make long-term commitments and 'waste' some capacity than to underestimate
need and make up the shortfall with short-term contracts" [4, p.130]. With advances
in computing power over the last decade, larger state spaces can be explored in real
time for this type of decision making, and the universe of qualified satellites available
should be investigated. The model presented establishes a framework for investigating contractual decisions with respect to time, satellites, regions, contract duration
and other relevant variables.
The research and projections presented demonstrate a need for satellite capacity
planning to efficiently allocate tax-payer dollars. If careful capacity planning provides
a method for the exploration of possible options and a solution or set of strategies
that minimize expected expenditures while satisfying requirements, the cost savings
can be spent elsewhere to maximize tax-payer benefit.
32
Chapter 2
Mathematical Formulation and DP
Model
2.1
Integer Program Formulation
Within this section, the mathematical formulation of the problem is discussed.
2.1.1
Parameters of Interest
" A: Set of arcs. Each arc represents a set of contract decisions. The contract
"decisions" are the chosen capacity levels across the set of satellites at a decision
node.
-
as...s: Capacity level for each satellite on a given arc.
- ca: Associated cost with set of satellite capacity levels, as a function of
base cost and satellite parameters.
-
ba:
Vector of bandwidth by region associated with each arc. For satellites
which cover multiple regions, the bandwidth provided during the time
period is divided equally among the regions covered.
* ba,r: Bandwidth for region r from capacity levels in arc a.
" S: Set of satellites.
33
- q,: The fixed maximum capacity of bandwidth, for satellite s. The satellite
can be thought of as a vendor of bandwidth.
r,: The set of regions satellite s covers.
- M: Cost multiplier for satellite s, as a function of regions covered, satellite
provider, and frequency type.
* R: Set of regions. Each region realizes demand for each time step, which must
be met.
* D: Vector of realized demand by region.
- dt: Realized demand for time period t.
* dt,r: Realized demand for region r in time period t.
* 1: Contract length, or duration, for each model instance.
* T: Set of time periods. Each time period represents a "stage."
2.1.2
Decision Variables
The decision variables are the arc choices at each time period. The set of decisions,
from time period 0 to T, where T is the last time period, that satisfy the below
constraints represent a solution.
Va E At E T
Ya,t
2.1.3
Objective Function
Contract Costs:
T
min
A
I:Ca,tya,t
t=O a=0
34
(2.1)
2.1.4
Constraints
y is binary:
Va c A, t c T
Ya,t C 0, 1
(2.2)
Only one decision per time period:
Vt E T
1
Ya,t
(2.3)
a
Decision lasts for contract period:
Ya,t < Ya,t+1 ...
Ya,t+l
Va C A, t C T
(2.4)
Vr C Rit E T
(2.5)
State is feasible:
13
br,a,tya,t
> dr,t
a
Satellite level is less than fixed satellite capacity:
Va C A, s C S
a. < q,
(2.6)
Satellite coverage is split evenly across its regions:
ba,
2.2
2.2.1
-
Va c A, s E S, r C R
I
(2.7)
Dynamic Programming Solver
Modeling Methodology
Capacity planning over time for a given set of demand can be modeled effectively
using a variety of methods.
In particular, dynamic programming fits the problem
well as the time dimension maps well to stages and the set of region capacity levels
35
maps well to states.
2.2.2
Stages, States, Nodes and Arcs
In the DP solver, each stage is a time period. The time step between stages is 3
months, a convenient measure for comparing contracts along the steep part of the
price function, those with durations between 0 and 12 months.
The state in each stage consists of all the values of concern including: contract
decision for the next period (capacity level on each satellite), cost, capacity coverage
over each region, and predecessor.
It is computationally straining to manage every integer combination of region
capacity coverage. The nodes serve as a representation of granularity for the levels of coverage by region. For example, the first node in given stage corresponds
to zero capacity coverage in all regions. The last node in a given stage (the last
stage-node) corresponds to the highest region demand set by user input. The nodes
in between depend on the level of granularity specified by the user. For example, if
the maxRegionDemand is 18, and nRegLevels is 6, then each node in a given will
represent a unique combination of capacities across all regions from 0 to 18 incremented by 3. Since the graph implementation utilizes adjacency arrays each node
can be thought of as a single entry in the table below, where each column is actually
managed as a separate array.
e K: Set of nodes. Each node represents a set of capacity levels provided to the
set of regions. The length of nodes is equal to "states" times "stages" plus two,
for a source and sink node.
- bn: Bandwidth for set of regions at each node n. This represents the
minimum threshold for each state. It also acts as a way to set granularity
of region-capacity levels investigated.
* b,,: Region bandwidth for a given node.
36
- P: Vector of predecessor nodes, indexed by actual node. For example, if
P6
equals 4, than the predecessor to node 6 is node 4, and an arc exists
between the two.
- 6: Vector of decision points, indexed by node. If a node is a decision point,
contract decisions/ purchases can be made at that node.
- X: Actual bandwidth supplied at each node.
This differs from node-
bandwidth, as "actual" can be greater than node-bandwidth. The actual
bandwidth is the least expensive bandwidth achievable at each node, while
satisfying all other constraints. In the event of a cost tie, the greatest bandwidth is kept. The re-labeling criteria is minimum cost, then maximum
capacity.
- k: Number of stage-nodes, or the number of states per stage. This constant
provides indexing access by stage for an adjacency array implementation.
Arcs represent contract decisions. All of the adjacency arrays stem from conversions
on a vector of satellite levels.
2.2.3
Modeling Questions
The questions this modeling effort seeks to answer are as follows:
" Can a "test-bed" be created to compare contracts under varying assumptions?
* Which types of contract decisions tend to perform better?
" How can one compare relative value of satellites?
2.2.4
Model Assumptions
Without knowing the breakdown of frequency and provider by region, it is impossible
to separate the effects on price. With a totality of usage data, the effects could be
separated to model new satellites and contracts. This thesis and associated model
will assume an equal distribution of bands per region, and regions for each bandwidth
37
type.
Military "demand" is what is deemed critical or required in subsequent periods.
This may be due to contingency efforts or for routine observation or communication. The model makes decisions for FSS contracts. Satellites are in geosynchronous
orbit, which is a common case for communication satellites. All contracts are nonpremptible. The market has enough liquidity to provide contracts at every decision
stage. Satellites do not fail.
The solver schedules contract purchases for Fixed Satellite Services (FSS). FSS describes service between geosynchronous satellites and fixed satellite antennae. Geosynchronous satellites orbiting over the equator at the same rate of Earth's rotation are
in the same position relative to any landmass, and thus satellite dishes can remain in
a "fixed" direction [12]. Historically, FSS has been the predominant architecture for
SATCOM. However, increasingly DoD is investing in Mobile Satellite Services (MSS)
due to emerging technology which can facilitate both uplink and downlink to FSS
and MSS, across multiple frequencies, including L and S-band [171.
Based on the historical aforementioned relationships that exist between price and
contract duration, the step-wise approximation of the relationship is given below.
Although the actual prices may fluctuate over time, the relative relationship between
long and short term contracts is likely to be robust, unless risk profiles of the participants drastically change, or certain principles of time value of money change.
The model assumes capacity available in any region exceeds demand and, for each
region, one or more satellites provides coverage.
Punit
243.2 - 14.7 * d
if 0 < d < 12
77
ifd= 12
79.6 - 0.2 * d
if 12 < d < 120
0
otherwise
=
38
2.2.5
Tradeoffs Between Long and Short Term Contracts
Aside from the price difference, utilization rates will vary by contract in a time period
with non-constant demand. In general, utilization will always be better for short-term
contracts. Put another way, utilization cannot be better for long-term contracts.
Variance of demand drives the utilization rate of long-term contracts. If variance
was zero, the long-term capacity could be perfectly predicted and utilization would
be 1. If variance is greater than zero, utilization falls for a given demand that long
term contracts must satisfy in all periods. Thus, when variance is small, long term
contracts out perform short term contracts, and when variance is large short-term
contracts can outperform long-term contracts for the same demand-periods.
The
extreme case illustrates this point. If you have a long term contract which covers 4
time periods, at price PL and short term contracts that follow demand perfectly at a
much higher price at PS. Assuming both contracts cover all demand in the 4 periods,
then the cost of long-term is:
CL = QL * PL
CS =(QL *
Where
UL)
*
PS
Q is the number of units, P is the unit price per contract
type and U is average
utilization rate over the time period. Based on this illustrative relationship, cost of
short term contracts for a given time period will be less expensive when UL <
P.
This is useful for getting a sense for when long or short term contracts should be
used, and is useful for allocating portions of projected demand into contract vehicles.
2.2.6
Pseudo-code
The pseudo code for the Dynamic Program constructor, buildSourceO, buildCenter(),
buildSink, and backPath() functions are covered in Algorithms 1, 2, 3, 4, and 5.
The actual source code is included in the appendix.
39
Algorithm 1 Dynamic Program - Contract Scheduler Constructor
Initialize data structures and constants
Create adjacency array structure
procedure CONTRACTSCHEDULER(S, 1, D, maxRegDemand, regLevels)
Get array of fixed satellite capacities
satLevels +- matrix of sat level combinations
for each level i in satLevels do
for each satellite j do
Get cost of satLeveli, level and add to satLeveli
end for
Get regionBWi for satLeveli
end for
regLevels <- matrix of region level combinations, from 0 .. .maxRegDemand
> Stage nodes
Calculate number of nodes
Dimension adjacency arrays for:
nodeCost
a cost
decisionPt
> decision node boolean
nodeSatBW
> BW on ea sat at node
nodeRegionBW
> min Reg BW constraint at node
actualBW
> actual BW supplied (can be greater than nodeSatBW)
predecessor
> pointer to node in stage before
end procedure
40
Algorithm 2 Dynamic Program - Build Source
procedure BUILDSOURCE (ContractScheduler)
Set source as decisionPt
for each state in first time period do
> first set of stageNodes
if node is feasible given realized demand then
for each possible satLevel (arc) do
if satLevel is feasible then
if Node has not been visited then
Set nodeSatBW according to satLevel index
Set nodeCost according to satLevel index
Set actualBW according to satLevel index
Set predecessor to source node
if duration, 1, equals stage time increment then
Set as decisionPt
else
Set intermediate nodes for contract duration
Set last intermediate node as decisionPt
end if
else
> node has been visited
if satLevel cost < current cost then
Re-label node and re-label intermediate nodes, if applicable
end if
end if
end if
end for
end if
end for
end procedure
41
Algorithm 3 Dynamic Program - Build Center
procedure BUILDCENTER(ContractScheduler)
for each stage E T do
for each node in stage do
if predecessor exists then
if node is feasible then
for each node in next stage do
if next-stage node is feasible then
for each satLevel (arc) do
if satLevel is feasible then
if node has not been visited then
Set nodeSatBW
Set nodeCost
Set actualBW
Set predecessor
if duration, 1,equals stage time increment then
Set as decisionPt
else
Set intermediate nodes for contract duration
Set last intermediate node as decisionPt
end if
> node has been visited
else
if satLevel cost < current cost then
Re-label node
Re-label intermediate nodes, if applicable
end if
end if
end if
end for
end if
end for
end if
end if
end for
end for
end procedure
42
Algorithm 4 Dynamic Program - Build Sink
procedure BUILDSINK (ContractScheduler)
Get sink node
for each node in last stage do
if node has predecessor then
if sink node has not been visited then
Set sink nodeCost
Set sink nodeSatBW
Set sink nodeRegionBW
Set sink actualBW
Set predecessor
else
if nodeCost < sink nodeCost then
Re-label
end if
end if
end if
end for
end procedure
Algorithm 5 Dynamic Program - Back Path
procedure BACKPATH (ContractScheduler)
Set last position in path to sink node
for each stage, i, from last... 0 do
Set pathi <- predecessor[pat hj±1 ]
end for
end procedure
43
E>
Last node
2.3
DP Simulation - Adding Uncertainties
The model specifies one type of uncertainty, demand, from two sources, as its generated from "regular " operations and a similarly specified distribution for "contingency"
demand.
The model assumes contingency demand to be sampled from an identical distribution as day-to-day demand, which is consistent with RAND's assessment of relative
magnitude of contingencies relative to daily operations. Furthermore, the model assumes that if a contingency does occur, it lasts for two periods, or six months.
After period 0, each subsequent day-to-day demand distribution incorporates a
region-growth factor, to accurately portray expert forecasts of market behavior. After observing the importance of controlling for utilization, the military should be
more open to long-term contracts, under the assumption that demand will grow for
the foreseeable future. If the assumption holds, then utilization rates globally will
tend to rise, making long-term contracts even more cost-effective.
2.3.1
Pseudo-code
Algorithm 6 Distribution Generator
Set Max Region Demand constant
procedure GETDISTRIBUTIONS
Inititalize random number generators and AbstractRealDistribution arrays
Get vector of region types
for all regions do
if distribution type equals type index then
if defaults enabled then
Set preset values for dist type parameters
else
Get dist type parameters
end if
end if
end for
return Array of distributions of length |7I
end procedure
44
Algorithm 7 Demand Generator
procedure GETDEMAND(numPeriods, Distributions[] daily, Distributions[] contingency, numRuns, growth[], warProb[] )
Create array for active contingencies and three-dimensional demand array
for each run do
Create array for demand by period
Create distribution array for growth in mean parameter
for each period do
Create new realized demand array
for each region do
if first period then
Region distribution remains unchanged
else
Create new distribution with growth in mean parameter
end if
Sample from distribution
while Sample is out of bounds do
Re-sample
end while
if contingency is active then
Decrement contingency duration counter
if Counter equals zero then
Set active contingency to false
end if
Sample from contingency demand distribution
while Combined sample is out of bounds do
Re-sample
end while
Add contingency sample to daily sample
else
Draw uniform random number between 0 to 1
if Draw is less than warProb then
Sample from contingency demand distribution
while Combined sample is out of bounds do
Re-sample
end while
Add contingency sample to daily sample
Set contingency to active
Set duration to conflict duration
end if
end if
end for
Set demand for period
end for
Set demand for run
end for
return Demand for simulation
45
end procedure
2.4
Standalone Options
In a similar fashion to purchasing fixed capacity in advance, options contracts for a
fixed amount of capacity to be used for a certain time period could have a similar
affect on cumulative costs. In many industries, it is common practice to purchase
options contracts to limit downside risk, while consequently limiting upside potential
(or cost savings) since this requires some fixed up front cost. In effect, an option
purchasing strategy constrains variance on spending (or loss, or gains, depending on
perspective).
According to the Federal Acquisition Regulation 17.2 - Options, contracting officers may negotiate options contracts when "it is in the Government's interest," and
(when using "sealed bidding") "there is a reasonable liklihood that the options will be
exercised" [10]. Many additional provisions exist, but these two are first and foremost.
Given that the plausibility of options contracts, they should be explored to examine
their effects.
Before incorporating options contracts in the model, logical pricing bounds must
be determined. For pricing options the following parameters are significant:
" p -unit price of bandwidth under fixed price contract
" q - reservation price for one unit of capacity (contract price; the price for the
right to buy)
" e - exercise price for option (difference paid if right to buy is used)
The following are assumed:
p < q+ e
p> q
If p > q + e, the government would never buy fixed price capacity in the immediate
term. If p < q, the government would never purchase options [15, p.30].
If a contract is to be purchased in time period t, and the option for this contract
must be purchased one contract period in advance, t - d, then the unit price, p,
46
according to the step function aforementioned would be:
{243.2 - 14.7 * 2d
Punit
if 0 < d < 12
With this in mind, the following relationships were established to capture the logical
bounds, and a decreasing total cost, q + e, for higher, q, due to increased risk on the
part of the buyer. The value of this risk is already represented in the step function
which provides the buyer with a lower per unit cost if purchasing capacity in advance.
However, what the options allow, is the ability to get longer term prices, without the
constraint of purchasing capacity for each period in the contract.
If the reservation price is zero, this describes a normal contract, without an option,
purchased at time t. If the execution price is zero, then the reservation price must
be equal to unit price of the contract purchased for two periods, at time t - d. The
upper bounds for reservation price and execution price are described below:
qupper
24 3.2 - 14.7 * r
if 0 < r < 12
77
if r = 12
79.6-0.2*r
if 12 < r < 120
0
otherwise
24 3.2 - 14.7 * d
if 0 < d < 12
77
if d= 12
79 .6 - 0.2 * d
if 12 < d < 120
0
otherwise
=
where r = 2d.
eupper
For a given reservation price, the base option execution price is:
e=-
eupper *q+epper
qupper
47
The concept of buying options is very similar to purchasing fixed capacity in
advance, but there exists another degree of flexibility which can be valuable when
managing capacity over many sources of uncertainty as the government must do
when accounting for many regions of demand. In essence, whatever reservation price
is spent, that is the portion of satellite capacity purchased in advance, and the cost
savings are proportional to
q
qupper
times the difference between d and 2d baseline
contract prices times satellite multiplier.
Once an option price curve is negotiated between supplier and consumer, the
question on the consumer side, is what reservation price and how many contracts to
purchase. It may be conceivable, that depending on calculated usage probabilities,
some contracts will be purchased with high reservation prices (those likely to be used),
and some with low reservation prices (those less likely to be used). This also largely
depends on risk tolerances.
48
Chapter 3
Results
3.1
Small Deterministic Example
To illustrate the complexities and trade-offs of satellite capacity planning, a small
scale example is presented with results. Below are the parameters for a 2 satellite, 3
region problem.
* Satellite 0:
-
O = 10
- ro
{0, 1}
- mo = 1.1
* Satellite 1:
- qi
3.1.1
10
- r
= {1, 2}
- m
=1.0
Deterministic Results
The optimal the allocation of bandwidth for each satellite, across different contract
durations, for the same demand, is not intuitive.
49
.. . . .............
......
-- 1
.........
........
..
..
SatLevels 12-mo Contracts
40
730
-o
41
-~20
10 0
5
10
15
20
25
Time Period (3mo)
+ sat 25
+- sat 26
Htghthartls co,
Figure 3-1: Two Satellite, Three Region, Twelve Mo. Contract Results
SatLevels 6-mo Contracts
40
30
.L
20
_J
10
0
0
5
10
15
Time Period (3mo)
Ssat 25
20
25
-- sat 261
H~ghcharts
m
Figure 3-2: Two Satellite, Three Region, Six Mo. Contract Results
The solutions pictured above represent the least expensive set of contracting decisions, for a type of contract, for given set of realized demands. These solutions
also represent the decisions for maximum utilization of each contract type for a given
starting period.
Alone, these results only illustrate the best one can do for a given set of demand,
and if forced to use only one type of contract. These do however provide bounds on
what can be achieved with the given contracts.
Looking at the Figure 3-5, one might infer incorrectly that just buying long-term
contracts is the answer to satellite capacity planning. The above results demonstrate
50
SatLevels 3-mo Contracts
40
30
20
10
i0
0
5
15
10
20
25
Time Period (3mo)
-sat25
*-sat26
Figure 3-3: Two Satellite, Three Region, Three Mo. Contract Results
Bandwidth and Demand for Region 1
20
10
5
0
10
5
0
15
20
25
Time Period (3mo)
+ Bandwidth for 12-mo contracts + Bandwidth for 6-mo contracts
* Bandwidth for 3-mo contracts +A- Demand
Figure 3-4: BW Provided by Contract and Demanded in Region 1
Cumulative Cost of Run
300k
200k
10.
0
........
Ok
0
S
15
10
20
25
Time Period (3mo)
- Cumulative Cost for 12-mo contracts
a- Cumulative Cost for 3-mo contracts
-- Cumulative Cost for 6-mo contracts
Figure 3-5: Cumulative Cost by Contract of a run
51
Cumulative Cost of Run
200k
150k
100k
5ok
014
50k
0
5
10
15
Time Period (3mo)
20
25
+ Cumulative Cost for 12-mo contracts - Cumulative Cost for 6-mo contracts
m Cumulative Cost for 3-mo contracts -* Cumulative Cost for Fixed 1+3-mo contracts
Cumulative Cost for Fixed2+3-mo contracts - Cumulative Cost for Fixed3+3-mo contracts
Figure 3-6: Cumulative Costs with Fixed Capacity Contract Types
one example of the "best fit" of contracts for a given set of demand, and utilization is
maximized for each contract type. The results below show what different strategies
return on another set of randomly generated data. Fixed1 represents purchasing 5
units of bandwidth on each satellite for all periods, and 3 mo contracts for all demand
not covered. Fixed2 represents purchasing 8 units of bandwidth on each satellite for
all periods, and 3 mo contracts for all demand not covered. Fixed3 represents purchasing 11 units of bandwidth on each satellite for all periods, and 3 month contracts
for all demand not covered.
This shows that there are possibly diminishing returns
on buying fixed capacity, as utilization goes down, as does cost effectiveness, with
bulk purchasing for this set of demand. The average utilization rates can be seen in
the table below.
Table 3.1: Average Utilization for All Regions
6 mo
3 mo Fixed1 Fixed2 Fixed3
12 mo
0.4301
0.4624
0.5400
0.5210
52
0.4539
0.3977
Bandwidth and Demand for Region 1
15
10
~0
5
0
5
10
15
20
25
Time Period (3mo)
-+- Bandwidth for 12-mo contracts
+ Bandwidth for 6-mo contracts
-a-Bandwidth for 3-mo contracts -*- Demand - Bandwidth for Fixed1+3-mo contracts
-0+Bandwidth for Fixed2+3-mo contracts -+ Bandwidth for Fixed3+3-mo contracts
Figure 3-7: BW Supplied and Demand for Region 1 With Multiple Contract Types
3.2
Results with Options Contracts
Purchasing options contracts and purchasing fixed capacity in advance represent different levels of commitment. As a result, the potential savings vary in proportion
to the commitment, as do the downside losses. Buying an option contract is akin to
purchasing a small portion of fixed capacity in advance. This is due to the bounds
placed on q + e. Pictured in Figure 3-8 is a representative effect of options contracts. This particular level of options contracts purchased in advance just slightly
outperforms the "immediate term" contracts. However, similar to the fixed capacity
results, for a given set of demand distributions, there exists an optimal strategy which
yields the lowest cost expectation. One strategy to find this level would be to increase
the options level on each satellite, until a direction reversal is detected in the cost
expectation of one thousand runs.
3.3
Results with Multiple Runs
Simulation parameters:
* 2 satellites
* 3 regions
53
Cumulative Cost of Run
250k
200k
150k
0
50K
Ok
50k
0
5
15
10
20
25
Time Period (3mo)
- Cumulative Cost for 12-mo contracts
Cumulative Cost for 6-mo contracts
r* Cumulative Cost for 3-mo contracts + Cumulative Cost for Fixed +3-mo contracts
-- Cumulative Cost for Fixed2+3-mo contracts +- Cumulative Cost for Fixed3+3-mo contracts
Cumulative Cost for Options1+3mo Contracts
Figure 3-8: Single Run With Options Contract
- normal demand distribution (Af(5, 2))
- normal contingency demand distribution (AP(5, 2))
- maxRegDemand = 20
- contingencyDuration= 2
- growth = 1.01, 1.012, 1.005
- warProb = .05, .01, .01
* 30 periods
* 6 contract types
* 30 runs for each contract
Satellite 53 has a negative skew in all like cases, relative to satellite 54, indicating it
tends to be more preferred in the minimum cost solutions. This may indicate that
capacity on satellite 53 should have a priority in acquisition for all overlapping areas
covered jointly by satellite 53 and 54. This behavior is also a result of the relative
price differences, distribution shapes of demand and growth in regions covered.
The Figure 3-11 shows another simulation with 9 contract types, including three
54
..
........
Cost Histogram
to
3MO C ntract Costs
FIXed2+3rn Curve
12mo Contract Camt
6MO Contrat Costs
-
oxed3+3mno Curve
FRxed I+ Contract Costs
Fxhd2 +Contraco Costs
Fixed3 + Contwat Costs
--
3mo Cumv
6mo Curve
-12aw
Cumv -
fxed1+3mo cut"
Figure 3-9: Cost Histogram by Contract for Two Sat, Three Reg
Figure
3-90:CostlitHistgra
700
by Contract
rToST
SatI> lHistogram
hreee
o0
Soo
4010
200
100
53 12 MO sat 53 6 ma
3 ="Curve
SSat
S- sat s54
saw 53 3mo-sat S3 12 mo Curv
F
r
-
- sat
53 6 moCurve
sa 53 3 mo Cumv
te -----
Lr
55
saw
54 12 mo
sam
54 6 mo
sat S4 3 iss-
saw 54 12 mo Curve
--
sat 54 6 too Curve
Cost Histogram
2
3OMoosts
FxO + 3ds+M
Cost
Fixodl
oMCosts
Fixed2
6moConracttCosts
12mo Contract Costs
5moContract Cot
Unlto Cum -FIed1.3to Curve - F~xed2 3mo Curv - Roa3+3ro Crve - Optionsl + 3 Mo Costs 3moCurve oCurve
0optnos, +3Mo Costs
Optm2 + 3 MaCosts
Opto
- 3 MoCosts -ptoos 3+ 3 MoCosts
Options3 + 3MoCots
Figure 3-11: Cost Histogram - Nine Contract Types
Cumulative Cost of Run
250k
200k
150k
0
100k
50k
Ok
-50k
0
5
10
15
Time Period (3mo)
20
25
+ Cumulative Cost for 12-mo contracts - Cumulative Cost for 6-mo contracts
Cost for 3-mo contracts -+- Cumulative Cost for Fixedl+3-mo contracts
Cost for Fixed2+3-mo contracts + Cumulative Cost for Fixed3+3-mo contracts
Cumulative Cost for Optlons1+3mo Contracts
-w Cumulative Cost for Optlons2+3m Contracts
* Cumulative Cost for Options3+3mo Contracts
-a- Cumulative
- Cumulative
-+
Htqh lar%or
Figure 3-12: Cumulative Cost - Nine Contract Types
different options strategies. The curves for all three options strategies overlap due
to the small differences in cost between each strategy and a lack of granularity at
the binning in the histogram. The figure 3-12 shows how slightly the results vary
by option contract on a given run. This is due to the default reservation price being
very small, and thus any realized savings will be small. But, the risk of not utilizing
an options contract drops, if normalized by cost. The parameters to experiment with
would be reservation price and number of contracts purchased in advance.
56
3.4
Time Complexity
This problem grows in multiple dimensions. State space grows as one of the following
increases:
" Granularity
/
Region Levels increases, thereby increasing number of nodes per
stage.
* Number of regions increases, increasing number of nodes per stage.
* Number of time periods grows, increasing number of stages, and thus the total
number of nodes.
" Adding detail to the node states. For example, if a node represents frequency
band, by region, instead of blanket region demand, the number of nodes increases for the same level of granularity.
* Adding satellites increases the number of arcs or possible decisions, but does
not increase nodes.
To examine the time complexity of this dynamic programming formulation, the number of steps required to solve each problem is approximated with a counter which
tallies visits and re-labels at nodes. The number of steps approximations is totaled
for an increasing number of arcs, holding nodes constant, and an increasing number
of nodes, holding arcs constant.
The Figure 3-13 shows a linear relationship between nodes in the DP graph and
number of steps required to solve. The number of steps is an approximation which
counts the number of nodes labeled or re-labeled. This excludes pre-processing time
and does not count in feasible arcs which are still looped through. For this figure,
satellites were held constant at two.
3.4.1
Leading Indicator
As mentioned in Section 2.2.5, there seems to exist a strong relationship between
utilization and cost effectiveness of contracts. Using rough approximations for price
57
Number of Steps to Nodes
25000
y=
0.2132x + 586.73
R'= 0.94809
20000
15000
4
E
S10000
number steps
-Linear
(number steps)
0
0
10000 20000 30000 40000 50000 60000 70000 80000 90000 100000
Number of Nodes
Figure 3-13: Number of Steps to Nodes
of contract (independent of which satellite is being used), averageprice/utilization
yields a good ranking metric for cost performance.
In the example provided by
Figure 3-12, the six contracts in the table perform in the same order as the simple
metric dictates. This is important because for certain contracts payment may occur
after the period is over.
Costs may not be realized until payment.
utilization (amount used on satellite
/
If real time
amount owned on satellite, for all satellites
under contract) can be maintained or approximated, then certain contracts may be
modified mid-period to account for changing trends, where utilization is spiking or
diving.
Table 3.2: Utilization as Precursor to Spending
12 mo
6 mo
3 mo
Fixedi
Avg Price / Utili zation
Rank on Metric
Actual Rank
3.4.2
161.5786
1
1
336.6633
5
5
366.1078
6
6
176.5948
4
4
Fixed2
Fixed3
143.2822
2
2
157.0599
3
3
Adding Detail without Adding Time
It is possible to consider a more detailed state space, while having a minimal impact
on solve time. For example, consider adding a frequency-level constraint to each re58
gion. Regions 1 to R must clear a threshold for C-, Ka- and Ku- bands, in addition to
all other constraints. One could add to the nodes directly, storing frequency specific
levels for each region. But this would cause the number of nodes to increase, since the
number of possible combinations of region-frequency-levels is greater than the number
of possible combinations of region-levels, assuming the same delimiter for granularity
at each node. Rather than add directly to the node, one can add information about a
node or arc by expanding the use adjacency arrays. In the constructor of the problem,
a frequency array can be created alongside the satellite-level arc array, in which the
frequency level at index i corresponds with the satellite level combination at index
i. This will allow for easy pruning at each stage by frequency constraints without
adding to the number of nodes. The only additional time consumed by node creation
is O(a) in pre-processing, where a is the number of arcs.
In the current formulation, time complexity is a function of live nodes above the
lower demand constraint. The upper bound is an arbitrary maxRegDemand value
that is some value above demand level the user cares about. Since the dynamic program solver runs after realizing the demand, the upper bound should be determined
for each run as the next viable node above the highest realized demand vector in a
given period. There is a trade-off in pre-processing time if this is to be done for each
run, as a new ContractScheduler object would need to be instantiated. Two options
to consider would be a new instance of the solver for each run with lowest viable node
for all periods as the upper bound, or the lowest viable node for all periods for all
runs with one instance of the solver.
Time can also be saved with an early break from the arc assignment loop. If the
contract decisions (arcs) are properly sorted, in relation to the loop which iterates
over all arcs, it could be possible to determine if all arcs following a certain arc are
more expensive. For example, if the satellites are sorted by price multiple, then [0,11
will always be cheaper than [1,0], and marginal capacity on the cheaper satellite will
be preferred to satisfy demand in regions serviced by both satellites.
59
3.4.3
An Alternative Representation
When certain conditions are met, node representation can be altered to save on time
complexity. If regional combinations exceed satellite level combinations, the nodes
should be represented as "satellite levels" rather than "region levels." The arcs would
remain unchanged, but an adjacency array for region demand would be created,
similar to the existing actualBW array.
60
Chapter 4
Conclusions
4.1
Thesis Conclusions
This thesis concludes that DoD should reevaluate its use of longer term contract vehicles, such as the DSTS-G contract. Fixed capacity should be purchased in advance.
Two questions remain: how much fixed capacity should be purchased, and on which
satellites? This model serves as a basis to answer those questions. With the proper
parameters, both questions could be answered, as the results show. The government
and its decision makers need a "testing" environment for approximating how contracts will preform in a changing fiscal and political environment. Potential contract
constructs need to be tested before being deployed. Satellites need to be pruned, as
well as model satellites with new attribute combinations. This model provides such
capabilities. Furthermore, the model provides the mechanism for testing the provision, reasonable likelihood, for options contracts.
The dynamic program presented could be a sub-problem to a larger optimization
algorithm which solves this problem over many iterations across different uncertainty
sets, which may encompass many expert opinions of reasonable combinations of distribution type and growth parameters. Certainly such a large optimization problem
will be slow, as it currently stands. The sub-problem DP algorithm needs to revisited
and improved upon for maximum efficiency.
DoD should consider making the bulk of its contractual decisions at regular in61
tervals.
It is unrealistic to suggest that all contract decisions could be made at
regular time stages, as this paper discusses the irregularity inherent in contingencies,
but making regular larger, long-term purchases could be valuable. This would allow
modeling of the process to better represent reality. More importantly, measurement
and evaluation from period to period could be standardized and more easily assessed.
For example, it is much easier to compare a budget overshoot in one 6 month period
to a budget undershoot in following 6 month period, than it would be comparing decisions made across 4 weeks followed by 2 weeks of performance after another round
of bandwidth purchases. Perhaps most importantly, data collection could become a
regular exercise and could be more consistent.
The government should work on developing heuristics for when variance is too high
to consider long term fixed capacity contracts in advance. Lastly, the use utilization
as a proxy for cost, if its values are determined at known at different times from
actual realized cost, could be useful for guiding tactical contractual decision making.
4.2
Future Work and Potential Uses
The biggest issue seems to be data collection. Data is inconsistent from report to report, and accounting for both bandwidth and expenditures is flawed. The first thing
SMC or the like should accomplish is a thorough enumeration of every COMSAT
contract with corresponding costs and bandwidths and service types explained.
As yearly cash outflows for certain projects may happen at irregular times, capacity utilization and contract type by satellite for all contracts should be regularly
maintained. With price approximations and utilization rates, cost estimates can be
updated with usage reports which may be maintained daily, hourly or minutely. This
may be useful for projecting where costs are heading by satellite or region before year
or quarter end.
This type of model is ideally suited for evaluation of contract performance. Once
empirical usage reports become available, contracts of all types can be compared to
gauge historical performance, as well as theoretical performance if certain assets were
62
used in different areas, or by different DoD agencies.
Mobile Satellite Services(MSS) represent a significant and increasing contribution
to total expenditures. Orbits would have to be modeled to include coverage areas
during discretized time periods, using software such as STK.
Additional contract types should be incorporated into the model, including the
trade-offs between leasing capacity directly and end-to-end solutions, in terms of cost
and lag time. Additional constraints should be included for orbital slots, "friendly governments," interaction between available supply and price and frequency constraints.
Additional sources of uncertainty should be incorporated including: satellite capacity
availability, and satellite region-coverage.
This model may be useful for determining relative value of satellites approaching
"end-of-life." Attributes associated with most valuable satellites for projected future
can be used to rank existing military systems. Those systems with the best projected
value that are approaching end-of-life can be prioritized for upgrade or replacement.
63
64
Appendix A
DP Code - Java
A.1
Contract Scheduler
import
java.util.ArrayList;
import
java.util.Arrays;
import
org.apache.commons.math3.distribution.AbstractRealDistribution;
public
class
ContractScheduler
private
int
private
Satellite[]
private
int
private
double [] []
private
int
endTime;
nbrRegions;
{
numberSteps;
satellites;
nbrSatellites;
demand;
private
int
private
int[]
private
int
private
int H]
private
double[]
private
double[][]
regBWFromSatLevel
private
double[][]
actualBW;
private
int
private
int
private
int
private
int
duration;
private
int
nodes;
private
double[]
private
int
H H
private
int
[] ] nodeRegionBW;
private
int[]
private
boolean[]
decisionpt;
private
boolean[]
decisionStage;
path;
totalCost;
[
satLevels ;
satLevelCost;
/
1,
maxRegionDemand;
nRegLevels;
regLevels
[] [I
i, t
r;
1
nodeCost;
nodeSatBW ;
pred;
%I
65
int
private
stageNodes;
double[]
optionsContractCosts;
double[]
optionsReservationCosts;
double[]
optionsExecutionCosts;
int[][]
optionsExecuted;
int[][]
excessSatLevels;
double []
excessCost;
double [][]
boolean[]
optionsAndExcessCost;
optionReservationStages;
double [][]
optionsUpperBounds;
double totalOptionsCost;
double[]
cumulativeOptionsCost;
double []
cumulativeCostWithOptions;
public
ContractScheduler(Satellite[]
s,
in t
dur,
double [][]
d,
int
maxRegD,
int
regDLevels)
numberSteps=0;
nRegLevels = regDLevels;
maxRegionDemand = maxRegD;
=
duration
dur;
satellites = s;
demand = d;
endTime = demand.length;
nbrRegions = demand[0].length;
nbrSatellites = satellites.length;
path = new int[endTime+1];
int
satLevelComb
for
(Satellite
1;
=
sat
:
satLevels
[]
n
intt]
for
Nr
=
new double [satLevelComb];
=
new
=
(sat.getCapacity(+),
new int[satLevelComb][satellites.length];
=
satLevelCost
int
{
satellites)
satLevelComb *=
int[satellites.length];
new int [satellites.length];
(int i=0;
i<Nr.length;i++){
Nr[i]=satellites[i].getCapacity();
regBWFromSatLevel
= new double [satLevels.length]
[nbrRegions];
satLevels = getCombinationsMatrix(n, Nr);
for
(int
i=0; i<satLevels.length;i++){
satLevelCost[i]=0;
for(int j=0;
j<satLevels[i]
length;
j++)
{
satLevelCost[i]+=satellites[j].getPrice(satLevelsti][j],
}
regBWFromSatLevel[i]=
int[]
n2 =
int[]
Nr2 =
new
new
convertToRegBW(satLevels[i]);
int[nbrRegions];
int[nbrRegions];
int regLevelComb=l;
66
duration);
{
for
(int
i=0;
i<Nr2.length;i++)
{
Nr2[i]=nRegLevels;
regLevelComb*=(nRegLevels+1);
}
regLevels
=
new
regLevels
=
getCombinationsMatrix(n2, Nr2);
int
int[regLevelComb][nbrRegions];
demandMultiplier
=
maxRegionDemand
System.out.println("nRegLevels:
for(int
i =0;
for
"+nRegLevels+",anddemandMultiplior:
i<regLevels.length;
(int
nRegLevels;
/
j=0;
{
i++)
j<nbrRegions;
j++)
{
regLevels[i][j]*=demandMultiplier;
nodes
(regLevels.length)*(endTime)
=
nodeCost
new
=
decisionPt
for(int
double[nodes];
new
=
boolean[nodes];
i<decisionPt.length;
i=0;
2;
+
i++)
{
decisionPt[i]=false;
nodeSatBW
new
=
int[nodes][nbrSatellites];
nodeRegionBW
new
int[nodesi[nbrRegions];
actualBW
new
double[nodesl[nbrRegions);
int
=
counter
for (int
0;
node=1;
node <nodeRegionBW .length;
nodeRegionBW[node]=
node++)
regLevels[counter];
counter++;
if
(counter ==
(regLevels.length))
{
counter=0;
decisionStage=
for(int
i =0;
new
boolean[demand.length+l];
<decisionStage.length;
i
i++)
decisionStage(i]=false;
I
pred
for
=
new
(int
int[nodes];
i =0;
predii]
i
<
=
nodes;
i++)
-1;
}
stageNodes
=
regLevels.length;
}
public
void
csd()
{
buildSource
();
67
{
{
"+demandMultiplier)
buildCenter
();
buildSink();
backPath();
I
private
void
buildSource()
{
nodeCost[0]= 0;
for
(int i =0;
i<satellites.length; i++) {
nodeSatBW[0][i]=0;
I
for (int
i=0; i<nbrRegions; i++) {
nodeRegionBW[0][i]= 0;
I
decisionPt [0]=true;
for
(int
i =1
int
if
; i<stageNodes+1;
toNode
(
=
i++) {
i;
isFeasibleNode(nodeRegionBW[i],
for
(int
satLev=0;
if
satLev++)
(isFeasibleLevel(regBWFromSatLevel[satLev],
if
{
demand[i/(stageNodes+1)]))
satLev<satLevels.length;
(pred(toNode]==-1)
{
AL
AV/f
nodeRegionBW[i]))
{
{
numberSteps++;
nodeSatBW toNode=satLevels[satLev];
nodeCost[toNode]=satLevelCost[satLev];
actualBW[toNode]=regBWFromSatLevel [satLev]
pred[toNode]=0;
if(duration/3
==1)
{
decisionPt[toNode]=true;
else{
setIntermediateNodes(toNode , satLevels[satLev],
nodeCost[toNode],
regBWFromSatLevel[satLev]);
}
}
else
if (satLevelCost [satLev]
<
nodeSatBW [toNode]
nodeCost [toNode]
nodeCost [toNode])
{
satLevels [satLev]
satLevelCost [satLev]
setIntermediateNodes(toNode , satLevels[satLev],
nodeCost[toNode],
regBWFromSatLevel[satLev]);
numberSteps++;
}
}
68
private
void
for
{
buildCenter()
(int
stage=1;
for(int
stage<endTime;
node=
stage++)
{
(stage -1)*stageNodes+1;
if(pred[node]
stage*stageNodes;
node++)
{
{
if(decisionPt[node])
if
node<=
{
0)
>=
( isFeasibleNode(nodeRegionBW[node],
demand[node/(stageNodes
{
+1)]))
if(
stage < endTime)
int nextStage
for(int
toNode<=
nextStage*stageNodes;
toNode++)
toNode=
stage+1;
(nextStage -1)*stageNodes+1;
{
if
demandltoNode/(stageNodes+1)]))
=
(isFeasibleNode(nodeRegionBW[toNodel,
{
for
(int
satLev=0;
if
regBWFromSatLevel[satLev],
nodeRegionBW[toNode]))
(isFeasibleLevel(
{
if
]==-1)
satLev<
{
satLev++)
satLevels.length;
(pred[toNode
{
nodeSatBW
[toNode]=satLevels[satLev];
nodeCost[
toNode]=satLevelCost[satLev];
actualBW[
toNode]=regBWFromSatLevel[satLev];
pred[
toNode]=node;
numberSteps
if
duration/3==1)
(
{
decisionPt
[toNode]=true;
else
{
setIntermediateNodes
(toNode ,
satLevels[satLev],
nodeCost[toNode],
regBWFromSatLevel[satLev]);
}
else
{
if
satLevelCost[satLev]
<
(
nodeCost[toNode])
nodeSatBW
(toNode]
=
satLevels[satLev];
[toNode]
=
satLevelCost[satLev];
nodeCost
actualBW
[toNode]=
regBWFromSatLevel[satLev];
setIntermediateNodes
(toNode ,
satLevels[satLev],
nodeCost [toNode],
regBWFromSatLevel[satLev]);
numberSteps
69
}
}
private
void
buildSink()
{
int stage=endTime;
int sinkNode = endTime*stageNodes+1;
if
node<= stage*stageNodes;
(stage -1)*stageNodes+1;
for(int node =
node++)
{
(pred[node]>= 0) {
if
(
isFeasibleNode(nodeRegionBW[node],
if(pred[sinkNode]==-1)
demand[node/(stageNodes+l)]))
{
nodeCost[sinkNode]=nodeCost[node];
nodeSatBW[sinkNode]=nodeSatBW[node];
nodeRegionBW[sinkNode]=nodeRegionBW[node];
actualBW[sinkNode]=actualBW[node];
pred[sinkNode]=node;
numberSteps++;
}
(nodeCost[node] < nodeCost[sinkNodel){
if
else
nodeCost[sinkNode]=nodeCost[node];
nodeSatBW[sinkNode]=nodeSatBW[node];
nodeRegionBW[sinkNode]=nodeRegionBW[node];
actualBW[sinkNode]=actualBW[node];
pred[sinkNode]=node;
numberSteps++;
}
}
}
}
}
public
void
backPath()
{
path[endTime]=(endTime)*stageNodes
+
1;
System.out.println(path[endTime]);
for
(int
stage
=
endTime-1;
stage>=0;
stage--)
{
if(path[stage+1]!= -1) {
path[stage]
=
pred[path[stage+1]];
System.out.println(path[stage]);
}
else
{
System . out . println (" Predeccessoruisabeyonduroot
}
public
void
outputDecisions()
for(int
stage=0;
{
stage < endTime;
stage++){
70
onabackupath!")
{
if
!=
(path[stage]
{
-1)
totalCost+=nodeCost[path[stage]];
System. out. println("Stage
for(int i=0;
:"+stage);
( "Cumulat iVe cost
System. out. printin
i<nodeSatBW[0].length;
"+totalCost)
i++){
System.out.println("Satellite
:e"+i+",Leve1:
"+nodeSatBW[path[stage]][i]);
}
System.out.println("ActualBW
supplied:,"+Arrays.toString(actualBW[path[stage]]))
}
{
else
System. out. print("
Cannot
print.results
f orBW
on,,nonex
ist antpathinode
\n)
}
}
}
public
boolean
for
isFeasibleNode(int[]
(int
i=0;
if(
nodeBW,
i<nodeBW.length;
(nodeBW[i]+0.0
return
double[]
i++)
-d[i])
{
d)
{
< 0.0000001)
{
false;
}
}
return
true;
}
public
boolean
for(int
isFeasibleLevel(double[]
i=0;
convertedRegBW,
i<demand.length;i++)
if(convertedRegBW[i]
return
demand[i]
-
int[]
demand)
{
{
<
{
0.0000001)
false;
}
}
return
true;
}
public
void
set IntermediateNodes (int
to,
int[]
satLvl,
double
cost,
double
[] regBW)
{
int predecessor = to;
for(int stage=1;
stage < duration/3;
if(to+stage*stageNodes
<
stage++) {
nodes) {
if(isFeasibleNode (nodeRegionBW(to+stage
/(stageNodes+1)]))
e
{t',
so
d ,
,, t
t * i, ,
stageNodes],
,
nodeSatBW[to+stage*stageNodes]
actualBW[to+stage*stageNodes]
=
satLvl;
= regBW;
nodeCost[to+stage*stageNodes]= cost;
pred[to+stage*stageNodes] = predecessor;
numberSteps++;
predecessor+=stageNodes;
if
(stage==
((duration/3)
-1))
{
decisionPt[to+stage*stageNodes] =
}
}
else
{
break;
71
true;
demand[(to+stage*stageNodes)
}
satCapOwned) {
convertToRegBW(int[]
public double[]
double[] regBW = new double(nbrRegions];
for
i=0; i<nbrRegions; i++) {
(int
s=0; s<satCapOwned.length; s++) {
for (int
(int r
for
{
satellites[s).getRegions()
:
if(r==i) {
satCapOwned[s]
regBW[i]+=
/
(satellites[s].getRegions().length
+0.0);
}
}
}
regBW;
return
public
void
static
if
(idx
==
getPermutations(int [I n,
int ] Nr,
n.length) {
idx,
ArrayList<ArrayList<Integer>>
ch,
U-
ArrayList<Integer>()
i++)
i=0; i<n.length;
for(int
th
n
new
w
ArrayList<Integer>
int
{
w.add(n[i]);
I
combs.add(w);
return;
}
for
i =
(int
<=
i
0;
n(idx]
=
getPermutations(n,
public
i++)
Nr[idx];
Nr,
idx+1,
n,
getCombinationsMatrix(int[]
int [I]
{
i;
combs);
int
[
Nr)
{
int levels=1;
for(int i=0; i<Nr.length; i++)
{
levels*=(Nr[i]+1);
I
int[]f]
combMatrix = new int[levels][n.length];
ArrayList<ArrayList<Integer>>
int
idx
=
getPermutations(n, Nr, idx,
for(int
combs = new ArrayList<ArrayList<Integer>>);
0;
i=0;
i
for(int
combs);
<combMatrix.length;i++){
j=0; j<combMatrix[0].length;
j++){
combMatrix[i][j] = combs.get(i).get(j);
return combMatrix;
public
getSats()
Satellite[]
{
return satellites;
}
public double [][
return
public
intt]
getDemand()
{
demand;
getPatho
{
72
combs)
{
return
path;
public double[]
getNodeCost()
{
return nodeCost;
}
public
int[][]
getNodeSatBW()
{
return nodeSatBW;
I
public
doublef[][]
return
getActualBW()
actualBW;
I
public
int
{
getDuration()
return duration;
I
public
boolean[]
getDecisionStages()
{
return decisionStage;
I
public
boolean[]
return
getDecisionPts()
{
decisionPt;
}
public int
{
getStageNodes()
return stageNodes;
I
public
void
getOptionsCost(int[]
optionsPurchasedSatPer,
double
reservationPer,
int
duration)
{
setDecisionStageso;
cumulativeOptionsCost = new double[demand.lengthl;
cumulativeCostWithOptions
double[]
new double[demand.length];
=
optionsBase=Satellite.getOptionsBase(reservationPer,
duration);
optionsContractCosts = new double[demand.length];
optionsReservationCosts=new double[satellites.length];
optionsExecutionCosts = new double[satellites.length];
optionsUpperBounds
for(int
= new double[satellites.length][2];
i=0; i< optionsExecutionCosts.length;
i++) {
optionsExecutionCosts[i]=optionsBase [1]*satellites[i].getSatPriceMult(;
optionsReservationCosts[i]=optionsBase [0]*satellites[i].getSatPriceMult(;
optionsUpperBounds
i] [0]=optionsBase [21* satellites
optionsExecuted=
excessSatLevels
new
=
new
getSatPriceMult
(i]
optionsUpperBounds Ci] [1]=optionsBase [3] *satellites
);
i]. getSatPriceMult ()
int[demand.length][satellites.length];
int[demand.length][satellites.length];
for(int per=O; per<demand.length;
if(decisionStage[per])
per++) {
{
for(int sat=O; sat<satellites.length;
sat++)
{
int diff = nodeSatBW[path[per]] [sat]
-
if(diff>O)
optionsPurchasedSatPer[sat];
{
excessSatLevels[per][sat]=diff;
optionsExecuted[per][sat]=optionsPurchasedSatPer[sat];
}
else
if (diff <
0){
73
optionsExecuted[per][sat]=
int diff2
nodeSatBW[path[per]][sat];
= nodeSatBW[path[per]][sat]-optionsExecuted[per][sat];
excessSatLevels[per][sat]=diff2;
}
else
{
excessSatLevels[per][sat]=0;
optionsExecuted[per][sat]=optionsPurchasedSatPer[sat];
}
}
}
else
{
optionsExecuted[per]=new int[satellites.length];
r
pt,
zero!
n1
excessSatLevels [per]=nodeSatBW[path [per)];
}
}
double cum0ptionsC=O;
for(int
i =0; i< optionsContractCosts.length;
double
i++) {
sumSatContracts=O;
if(decisionStage[i]==true)
for(int
{
sat=0;
sat<optionsPurchasedSatPer.length;
double
satContractCost
double
satExecuteCost
sat++) {
optionsReservationCosts[sat]*
=
optionsPurchasedSatPer[sat];
=
optionsExecutionCosts[sat]*optionsExecuted[i][sat
sumSatContracts+=(satContractCost+satExecuteCost);
}
cumrptionsC+=
sumSatContracts;
}
optionsContractCosts[i]=sumSatContracts;
cumulativeOptionsCost[i]=cumOptionsC;
}
excessCost= new double[demand.length];
double cumExcess=O;
for
i=0;
(int
i<excessSatLevels.length;i++){
excessCost[i]=0;
for(int j=0;
j<excessSatLevels[i].length;
j++)
{
excessCost[i]+=satellites[j].getPriceDouble(excessSatLevels[i][j],
I
cumExcess+excessCost[i];
cumulativeCostWith0ptions [i]=cumExcess+cumulativeOptionsCost [i]
}
optionsAndExcessCost
=
new double [2] [demand. length]
optionsAndExcessCost [0] =optionsContractCosts
optionsAndExcessCost[l]=excessCost;
}
public void outputOptionsResults()
System.out.println('----------Options
ContractCosts ------- ")
System . out .println(Arrays . toString (optionsContractCosts));
System.out.println(----------OptionsuReservationaCosts-------System . out . println (Arrays . toString (optionsReservationCosts));
System.out.println("----------OptionsExecutionCosts-------")
System . out . printin (Arrays . toString (optionsExecutionCosts))
74
duration);
onand, Execution");
System.out.println("UpperBoundonleservati
for(int
i =0;
i <optionsUpperBounds.length;
i++)
{
System.out.println("Satellite,,"+i+"ReservationUB:,;"+optionsUpperBounds[i][0]);
System.out.println(Satellite
"+i+",ExecutUion
UB:+optionsUpperBounds[i[1]);
}
System.out.println("
for(int
i=0;
----
---
i<demand.length;
OptionsExecuted---------")
i++
{
)
System. out .println(Arrays
toString
(optionsExecuted [iI));
}
System.out.println("
-OptionsuCostsePer
i=0;
i++)
for(int
i<demand.length;
Period -------
");
{
System.out.println("Period:,,"+i);
System.out.printin(optionsAndExcessCost [0][i]);
}
System.out.println(
for(int i
=0;
i
ExcessAmountaandCostsPerPeriod,,-----"
< demand.length;
i
{
++)
System.out.println("Period:
"+i);
System.out.println("ExcessIevel
System. out. println
:"+Arrays.toString(excessSatLevels[i]));
("Excess,
cost:
"+excessCost [iI);
}
}
public
void
setDecisionStages()
{
decisionStage [0]=true;
for(int
node=1;
node<
nodes;
node++)
if(decisionPt[node]==true)
decisionStage
{
{
[(node/(stageNodes+1))+1]=true;
node+=stageNodes;
}
}
}
public
int
getNumberStepso)
return
numberSteps;
}
public
int
getNodes()
return
{
nodes;
}
public
int
getNumSatLevels()
return
{
satLevels.length;
}
}
A.2
Demand Generator
import
java.util.Arrays;
import
java.util.Random;
import
javax.swing.J0ptionPane;
import
org.apache.commons.math3.distribution.*;
import
org.apache.commons.math3.random.RandomGenerator;
public
class
Demand
{
75
private static
double
private static
int
public
static
MAXREGIONDEMAND
= 20;
CONTINGENCY-DURATION = 2;
AbstractRealDistribution[]
getContingencies(int[]
distributionTypes,
boolean
defaultEnabled
int nbrRegions = distributionTypes.length;
double normal-mu;
double normal-sigmaSq;
AbstractRealDistribution[]
contingencies = new
for(int i=0; i<nbrRegions;
i++) {
if(distributionTypes[i]==1)
if
AbstractRealDistribution[nbrRegions];
{
(defaultEnabled) {
normal-mu = 5;
normal-sigmaSq = 2;
NormalDistribution
n = new NormalDistribution(normal-mu,
normal-sigmaSq);
contingencies[i] = n;
}
else
{
String normal-mu- string = J0ptionPane.showInputDialog("Enteruaumuuvalueu
forLthe)normaladistributionudescribinguregiona"
normal-mu = Double.parseDouble(normal-mu-string);
String normal-sigmaSq-string
=
JOptionPane.showInputDialog("Enterasigma
-squaredovalueuforudistributionu"+i+":j");
normal-sigmaSq = Double.parseDouble(normal-sigmaSq-string);
NormalDistribution
n = new
contingencies[i]
n;
=
NormalDistribution(normalmu,
normalsigmaSq);
}
}
}
return
contingencies;
}
public
static
int
AbstractRealDistribution[]
nbrRegions
double
=
getDistributions(int[]
distributionTypes,
boolean
distributionTypes.length;
normal-mu;
double normal-sigmaSq;
double
beta-alpha;
double beta-beta;
double
cauchy-x;
double cauchy-y;
double
chisquared-k;
double exponential-lambda;
double fisherSnedecor-dl;
double fisherSnedecor-d2;
double gamma-k;
double gamma-theta;
RandomGenerator levy-randgen;
double levymu;
double
levy-c;
double lognormal-mu;
double lognormal-sigmaSq;
double uniform-lower;
double uniform-higher;
double weibull-lambda;
double
weibull-k;
AbstractRealDistribution[]
distributions
76
new AbstractRealDistribution[nbrRegions];
defaultEnabled
Random
ri
=
for(int i=0;
new
Randomo;
i<nbrRegions;
{
i++)
{
if(distributionTypes[i]==1)
{
(defaultEnabled)
if
normal-mu
5;
=
normal-sigmaSq =
2;
NormalDistribution
distributions
[i]
n
new
=
NormalDistribution(normal-mu,
normal-sigmaSq);
= n;
}
{
else
String
forothe
normal-mu-string
normalLdistributionedescribingeregionu"+i+"
normal-mu
String
-squaredevalue,
=
JfptionPane.showInputDialog("Enter
amuevalue
:");
forLadistributiont-"+i+"
:,")
Double.parseDouble(normal -mu-string);
=
normal-sigmaSq-string
=
JOptionPane.showInputDialog("EntermaLsigma
;
normal-sigmaSq
= Double.parseDouble(normal_sigmaSq-string)
NormalDistribution
n =
distributions[i]
=
n;
BetaDistribution
n
=
distributions[i]
=
n;
new
NormalDistribution(normalmu,
normal-sigmaSq);
}
}
else
if(distributionTypes[i]==2)
if
{
(defaultEnabled)
= 5;
beta-alpha
beta-beta
2;
=
new
BetaDistribution(betaalpha,
beta-beta);
}
else
{
String
valueforothebeta
beta-alpha.string
JOptionPane.showInputDialog("Entercamalpba,
distributionsdescribingregion,"+i+":,");
beta-alpha =
String
,forotheebetaedistributionedescribi
Double.parseDouble(beta-alpha-string);
beta-betastring
=
JOptionPane.showInputDialog(Entereaubetavalue
ngregionu"+i+":j");
beta-beta =
Double.parseDouble(beta-beta-string);
BetaDistribution
n
distributions[i]
= n;
=
new
BetaDistribution(betaalpha,
betabeta);
}
}
else
if(distributionTypes
if
{
i]==3)
(defaultEnabled)
{
cauchy-x
=
5;
cauchy-y
=
2;
CauchyDistribution
n =
distributions
n;
[i]
=
new
CauchyDistribution(cauchyx,
cauchy-y);
}
else
{
String
the
cauchy-x-string
=
JOptionPane.showInputDialog("Enter
aux
valuefor
cauchyadistributionudescribigjregionn"+i+:e");
cauchy-x
String
,theecauchy
=
Double.parseDouble(cauchy-x-string);
cauchy-y-string
=
JOptionPane.showInputDialog("Enter
aeyvaluefor
distributiondescribingaregion"+i+:");
cauchy-y
=
Double.parseDouble(cauchy-y-string);
CauchyDistribution
n
distributions[i]
=
n;
if(distributionTypes[i]==4)
{
}
else
if
(defaultEnabled)
{
77
=
new
CauchyDistribution(cauchy-x,
cauchy-y);
chisquaredk
=
5;
ChiSquaredDistribution n = new
distributions[i] =
ChiSquaredDistribution(chisquaredk)
n;
}
else {
String
chisquared-k-string = JOptionPane.showInputDialog("Enteruaukvalue
uforutheuchi-squaredudistributionudescribingaregionu"+i+":,");
chisquared-k = Double.parseDouble(chisquared-k-string);
ChiSquaredDistribution n = new ChiSquaredDistribution(chisquared-k);
distributions[i] = n;
}
}
else if(distributionTypes[i]==5) {
if
(defaultEnabled)
{
exponential-lambda = 5;
ExponentialDistribution
=
n
new ExponentialDistribution(
exponential-lambda);
= n;
distributions[i]
}
else
{
String exponential-lambda-string
JOptionPane.showInputDialog("Enterua,
=
I ambda:value)forotheexponent:ialdistribut)iondescribing)region,"+i+":,");
= Double.parseDouble(exponential-lambda-string)
exponential-lambda
ExponentialDistribution n = new ExponentialDistribution(
exponential-lambda);
=
distributions[i]
n;
}
}
else
if(distributionTypesi]==6) {
if
(defaultEnabled) {
fisherSnedecor-di
5;
=
fisherSnedecor-d2 = 2;
new
FDistribution n =
FDistribution(fisherSnedecor-dl,
fisherSnedecor-d2)
n;
distributions[i]
}
else {
String fisherSnedecor-dlstring
= JOptionPane.showInputDialog("Enteraudl
,valuefortheFisher-Snedecordistribution1describinguregion"+i+":,");
fisherSnedecor-di = Double.parseDouble(fisherSnedecor-dl-string);
String fisherSnedecor.d2_string
=
J~ptionPane.showInputDialog("Enteruaudu
valueuforotheFisher -Snedecoradistributionudescribinguregion,"+i+":,");
fisherSnedecor-d2
FDistribution
=
parseDouble(fisherSnedecor-d2_string)
Double
n = new FDistribution(fisherSnedecor-d1,
distributions(i]
fisherSnedecord2)
=n;
}
}
else
if(distributionTypes[i==7) {
if
(defaultEnabled) {
gamma-k = 5;
gamma-theta = 2;
GammaDistribution
n = new
distributions[i] =
GammaDistribution(gammak,
gammatheta);
n;
}
else
String gamma-k-string = J3ptionPane.showInputDialog("Enterakvalueforu
theugammaudistributionAdescribinguregion,"+i+":'");
gamma-k = Double.parseDouble(gamma-k-string);
String gamma-theta-string
value
fortheugammaudistributionadescribinguregion"+i+":
78
=
);
JOptionPane.showInputDialog("Entereautheta
gamma-theta
=
Double.parseDouble(gamma-theta-string);
GammaDistribution
n
new
=
distributions[i]
GammaDistribution(gamma-k,
gamma-theta);
n;
}
}
{
if(distributionTypes[i]==8)
else
if
{
(defaultEnabled)
levy-randgen
levy-mu
(RandomGenerator)
=
new
Random()
5;
levy-c
5;
LevyDistribution
n
=
distributions
=
n;
i]
new
LevyDistribution(levy-randgen,
levy-mulevy-c);
}
{
else
String
levy-mu-string
,theelevydistributiondescribinguregionu"+i+":
levy-mu
String
theelevy
JOptionPane.showInputDialog("Enteramu
=
valuefor
");
distributionedescr
ibing
=
Double.parseDouble(levy-mu-string);
levy-c-string
region, "+i+";
=
levy-c
J~ptionPane.showInputDialog("EnteruaLc
=
value
foru
");
Double.parseDouble(levy-c-string);
levy-randgen
(RandomGenerator)
=
LevyDistribution
n
=
distributions[i]
=
n;
new
new
Random()
LevyDistribution(levy.randgen,
levy-mulevyc);
}
else
{
if(distributionTypes[i]==9)
if
{
(defaultEnabled)
lognormal-mu =
5;
= 2;
lognormalsigmaSq
LogNormalDistribution
n
new
LogNormalDistribution(lognormal-mu,
lognormal-sigmaSq);
distributionsfi]
n;
=
}
else
{
String
value
forLtheolognormal
lognormal mu-string
distributionjdescribingaregion"
lognormal-mu
String
=
=
JOptionPane .showlnputDialog ("Enter, amu,
+i+":e");
Double.parseDouble(lognormal-mu-string)
lognormal-sigmaSq-string
=
J3ptionPane.showInputDialog("Entersa,
sigma-squareduvalue.forotheilognormaldistributionadescribingLregion,"+i+":,");
lognormal-sigmaSq
Double.parseDouble(lognormal-sigmaSq-string);
=
LogNormalDistribution
n
=
new
n
=
LogNormalDistribution(lognormalmu,
lognormal-sigmaSq);
distributions
[i]
n;
=
}
}
else
{
if(distributionTypes[i]==10)
if
(defaultEnabled)
{
uniform-lower
5;
uniform-higher
2;
UniformRealDistribution
new
UniformRealDistribution(uniform_lower,
uniformhigher);
distributions[i]
=
n;
}
else
String
uniform-lower-string
J~ptionPane.showInputDialog("Enterailower,
=
valueeforthe,,uniformdistributiondescribingregion,"+i+":'");
uniform-lower
String
highervalue
=
Double.parseDouble(uniform_lower-string);
uniform-higher-string
=
JOptionPane.showInputDialog("Ente,,a
fortheoparetadistributionadescribingeregion,"+i+" :");
uniform-higher
= Double.parseDouble(uniformhigher-string);
79
UniformRealDistribution
n
=
new
UniformRealDistribution(uniformlower,
uniformhigher);
= n;
distributions[i]
}
}
else
{
if(distributionTypes[i]==11)
if
(defaultEnabled)
{
weibull-lambda
weibullk =
= 5;
2;
n
WeibullDistribution
=
weibull-k
WeibullDistribution(weibull-lambda,
new
= n;
distributions[i]
}
{
else
String
weibull-lambdasstring
J3ptionPane.showInputDialog("EnteruaL
=
lambdauvalueuforotheuweibulladistributionadescribingLregionu"+i+":,");
weibull-lambda
String
= Double.parseDouble(weibull_lambda_string);
weibull-k.string
=
J~ptionPane.showInputDialog("Entereaukuvalue,
forotheuweibulldistributiondescribingaregion"+i+":u");
weibullik
=
Double.parseDouble(weibull-k-string);
n
WeibullDistribution
=
distributions[i]
=
new
weibullk
WeibullDistribution(weibull-lambda
n;
}
}
else
{
System.out.println("DistributiontypenotLsupported.");
}
}
return
distributions;
}
public
static
double
[[][]
boolean[]
periods,
getDemand(int
contingencies
AbstractRealDistribution[]
int
,
activeContingencies
new
=
contDurationLeft
double [][][]
for
(int
i
=
new
=
simulatedDemand
0;
double
Random
i
<
[][]
ri
runs;
int
new
growth,
double
warProb)
[]
{
boolean[distributions.length];
length];
double [runs] [periods] [distributions.
{
demandPeriods
=
[]
[distributions.length];
= new
i++)
distributions,
AbstractRealDistribution[]
double
false);
Arrays.fill(activeContingencies,
int[]
runs,
=
new
length];
double [periods] [distributions.
Randomo;
= new
distributionsRun
AbstractRealDistribution[]
AbstractRealDistribution[distributions.
length];
for(int
period
=
double[]
for
0;
d
(int
new
reg=O;
if
period++)
period<periods;
=
{
double [distributions.length];
reg++)
reg<distributions.length;
{
(period==0)
{
double
g
double
mu=distributions[reg].getNumericalMean);
double
var=
=
growth[reg];
distributions
[reg].getNumericalVariance(;
new
distributionsRun[reg]=
NormalDistribution(mu,
}
else
if
(period>0)
{
double
g =
double
mu=distributionsRun[reg].getNumericalMean);
double
var=
80
growth[reg];
distributionsRun[reg].getNumericalVariance(;
Math.sqrt(var))
distributionsRun[reg]=
double
while
sample
=
distributions
(sample
<
0
sample =
d[reg]
new
11
NormalDistribution(mu*g,
(reg] . sample
sample
>
Math.sqrt(var
()
MAXREGIONDEMAND)
{
distributionsRun[reg].sampleo;
sample;
=
if(activeContingencies(reg]==
{
true)
contDurationLeft[reg]--;
{
if(contDurationLeft[reg]==0)
activeContingencies[reg]=false;
}
double
while
contSample=
(contSample
contingencies[reg.sampleo;
0
<
contSample
=
11
contSample
>
(MAXREGIONDEMAND-sample))
contingencies[regl.sampleo;
d[reg]+=contSample;
}
else
{
double
warDraw
=
rl.nextDouble(;
if(warDraw<warProb~reg])
double
while
sample))
{
1
{
contSample=
(contSample
contingencies[regJ.sampleo;
0
<
11
contSample
>
(MAXREGIONDEMAND-
t
contSample
=
contingencies(reg].sampleo;
d[reg]+=contSample;
activeContingencies[reg]=true;
contDurationLeft[reg]=CONTINGENCYDURATION;
}
}
}
demandPeriods[period]=d;
}
simulatedDemand[i]=
demandPeriods;
}
return
simulatedDemand;
}
A.3
public
Satellite
class
Satellite
{
private
String
private
int[]
private
int
private
double
optionPrice;
private
double
executionPrice;
name;
regions;
capacity;
81
1re
1
I:IC2
nt.
12r
h11
(t'tr
private static double ] regPriceMult
=
gion
new double[]
{1,
1.1,
0.9,
private double companyMult;
private
public
satPriceMult;
double
(int[]
Satellite
=
regions
=
capacity
double
int c, String n,
r,
companyM)
{
r;
c;
= n;
name
]
double
=
satPriceMultArr
new
double [r.length];
companyMult=companyM;
satPriceMult=l*companyMult;
for(int
i =0;
for
i<satPriceMultArr.length;
(int j=0;
i++
) {
j<regPriceMult.length;
if(regions[i]==j)
j++)
{
{
satPriceMult*=regPriceMult[j];
}
}
}
public
r) {
[
void setRegions(int
regions = r;
I
public
{
getRegions()
int[]
regions;
return
}
public
getName()
String
{
name;
return
}
public
c)
setCapacity(int
void
{
capacity = c;
I
public
int
getCapacity()
return
{
capacity;
}
getSatPriceMult() {
public double
satPriceMult;
return
}
getPrice(int capUsed, int
public double
duration)
double base;
if
{
(duration < 12)
base= (243.2 -
14.7*duration)*capUsed;
I
else
if
(duration
>
12)
base= (79.6 -
{
0.2*duration)*capUsed;
I
else
{
base= 77*capUsed;
82
0.8,
1,
1,
1,
1.2,
1.3,
1.4,
1,
1};
return
public
base*satPriceMult;
double
getPriceDouble(double
double
if
capUsed,
int
duration)
{
base;
(duration
{
< 12)
base=
(243.2
14.7*duration)*capUsed;
-
}
else
if
(duration >
12)
base=
(79.6 -
base=
77*capUsed;
0.2*duration)*capUsed;
}
{
else
}
return
base*satPriceMult;
}
public
static
double
int
sum =0;
for
(int
getPrice(int[]
i=0;
caps,
i<caps.length;
i++)
int
duration)
{
{
sum+=caps [i]
}
if
(duration
<
12)
return
-
(243.2
14.7*duration)*sum;
}
else
if
(duration
>
return
else
12)
(79.6
-
{
0.2*duration)*sum;
{
return 77*sum;
}
public
static
double[]
get0ptionsBase(double
double
lowerBoundRes;
double
upperBoundRes;
double
lowerBoundEx;
double
reservationPer,
duration)
{
upperBoundEx;
double
[]
int[]
unitCap
optionsBase
=
upperBoundRes=
lowerBoundRes
lowerBoundEx
new
new
double [4];
{1};
Satellite.getPrice(unitCap,
duration*2);
0;
Satellite.getPrice(unitCap,
double
res
double
executionP
=
=
int[]
0;
=
upperBoundEx =
duration);
reservationPer*upperBoundRes;
=
-(upperBoundEx/upperBoundRes)*res
optionsBase [0=res;
optionsBase[1]=executionP;
optionsBase [2]=upperBoundRes;
optionsBase [3]=upperBoundEx;
return
int
optionsBase;
83
+
upperBoundEx;
Main() Method
A.4
import
java.sql.Connection;
import
java.sql.ResultSet;
import
java.sql.SQLException;
import
java.sql.Statement;
import
java.util.Arrays;
import
java.util.Random;
import
org.apache.commons.math3.distribution.AbstractRealDistribution;
public class
MainMethod {
public
static
void
main(String[]
args)
{
boolean
isMultContractDurations=true;
boolean
isTimingRuns =false;
int[]
sir = new
Satellite
int(]
s2r = new
Satellite[]
{0,1};
Satellite(s1r,
int[]
s2 =
Satellite
int
int[]
si = new
new
40, "Apollo11", 1.1);
{,2};
40, "Apollo,13" , 1.0);
Satellite(s2r,
sats= new Satellite[]
{s1,s2};
duration=12;
int []
distTypes=new
double[]
growth
double[]
warProb
int [] {l,,i};
new
double []{i.01,1.012,1
new double []{.05,.01,.01
AbstractRealDistribution[] distributions
AbstractRealDistribution[] contingencies
o,"f
r
numRuns
=
/ TI 11
int
r
int [
I11
s1,
1-ula i
Demand.getDistributions(distTypes,
true);
Demand.getContingencies(distTypes,
true);
r
1;
optAmt = new int[]
doublet]
try
11 n
=
optionsCumCosts
{5,
=
10,
15};
new double
[optAmt.length];
{
Connection con = null;
ResultSet rs-lastSat
=
null;
ResultSet rs-lastSim = null;
ResultSet rs-lastTimeStep = null;
84
ResultSet
=
rs-durationID
null;
Class.forName("org. sqlite .JDBC");
con
=
java.sql.DriverManager
getConnection("jdbc:sqlite:/Users/jlyd/rails-projects/
sat-planner/db/developmtentcsqlite3");
System.out . println("Connected
Statement
stit
con.createStatement();
=
insertSimulation
String
" INSERT
INTO, Simulations(namne)
"+
"VALUES(I'Fi rstSim ')";
stmt.executeUpdate(insertSimulation);
rs-1astSim
int
=stmt .executeQuery(SELECT,,idFROM LlSimulation
s ORDEREBY
id
DESCLIMIT
1")
lastSim=-I;
while
(rs-lastSim.next)){
lastSim
= rs-1astSim.getInt(id");
}
{
if(isMultContractDurations==true)
double []][]
numRuns
,
growth,
simulatedDemand
=
Demand.getDemand(30,
distributions,
contingencies,
capacity
usimulationlD)
warProb);
System.out.println("Demandsucreated.");
int[]
satIDs
=new
int satIDCounter
for(Satellite
int[sats.length];
=
s
0;
{
sats)
stmt.executeUpdate("INSERTINTSaelltetes,(name
,
"VALUES,('NoName
rs-lastSat
=stmt
.
',"+s.getCapacity()+"
executeQuery (SELECT,
,"+lastSim+")');
idFROMSate 11 itesORDERBYad
DESC
,LIM IT,);
int
lastSat=-l;
{
while(rslastSat.nexto)
lastSat
=
rs-lastSat.getlnt("id");
satIDs[satIDCounter]
for(int
reg=0;
=
lastSat;
reg< s.getRegions().length;reg++)
{
stmt.executeUpdate("INSERT,,INTOSatelliteRegions(satelliteID,
regionID),I"+
"VALUES("+lastSat+",u"+(s.getRegionso[reg]+l)+")
satIDCounter++;
for(int
run=0;
int[]
for(int
run<simulatedDemand.length;
timeStepIDs
per=O;
=
new
run++)
{
int[simulatedDemand[0].length];
per<simulatedDemand[0).length;
per++)
{
stmt . executeUpdate("INSERT, JNTOutime-stepsu(run ,period,
simulationID)u,"+
"VALUES ("+run+" ,"+per+",
85
"+lastSim+")");
=stmt.executeQuery("SELECT
rs-lastTimeStep
iduFROMutime-stepsu
ORDERBYuidDESCuLIMITA");
int
lastTimeStep=-i;
{
while(rs-lastTimeStep.nexto)
lastTimeStep = rs-lastTimeStep.getInt("id");
}
timeStepIDs[per]=lastTimeStep;
}
for(int d=3; d<duration+1; d*=2) {
18,
d,
c = new ContractScheduler(sats,
ContractScheduler
simulatedDemand[run],
6);
Systemout.println("DurationAis:,"+d);
c.csd();
c.outputDecisions(;
rs-durationID = stat .executeQuery("SELECTidFROMu
contract-durationSu"+
"WHEREmonths=e" +c.getDuration());
int durationID
-1;
=
while(rs_durationID.next()){
durationID
=
rsdurationID.getInt("id");
}
double
cumCost=O;
per++)
per=O; per<c.getDemand).length;
for(int
{
for(int r=O; r<c.getDemand()[per].length;
stat .executeUpdate ( "INSERTu INT
r++)
{
Demands
(
timeStepID,regionID,-quantity ,uactual-bw ,LcontractDurationID)u"+
"VALUES("+timeStepIDs[per]+" ,j"+(
r+1)+" ,"+c.getDemand()
[per] [r]+" ,-1"+c.getActualBW() [c.getPath() [per]] [r]+" ,j"+durationID+")")
}
!=
(c.getPath()[per]
if
-1)
{
cumCost +=c.getNodeCost () [c .getPath
for(int sat=O;
[per]];
sat<c.getNodeSatBW)[0[].length;
sat++){
stmt.executeUpdate("INSERTINTO.
sat_levels,(timeStepID,asatelliteID,abandwidth,acost
,contractDurationID
,cumCost),"+
"VALUES("+timeStepIDs [per
,"+c.getNodeCost
[sat]+"
J+" ,,"+satIDs [sat)+",u"+c.getNodeSatBWo(c.getPatho(per]]
() [c.getPath()[per]]+
",u"+durationID+"
,"+
cumCost+")")
}
if(
d== 3)
{
for(int
optIndex=O;
optIndex<optAmt.length;
optIndex++) {
int optionQuant
86
=
optAmt[optIndex];
int[]
optionsPurchased
=
new
int[sats.
length]
for(int i
=0;
i<sats.length;
{
i++)
optionsPurchased[i]=optionQuant;
}
c.getOptionsCost(optionsPurchased,
.1,
d)
c.outputOptionsResults();
for(int
sat=O;
sat<
sats.length;
{
sat++)
stmt.executeUpdate("INSERT.INTO,
options.costs,(timeStepID
ecumOptC,
,optionsExecuted
,optionsPurchased
excessCost ,cumTotalC,,contractDurationID
,ureservationPrice
,
executionPrice
,-optionsCost
,satelliteID),"+
"VALUES("+
timeStepIDs[per]+",e"+c.optionsExecuted[per][sat]+",
"+optionQuant+",,"+c.optionsReservationCosts
c.optionsExecutionCosts[sat]+",..."+c
opt ionsContractCosts
-"+
[sat]+"
[per]+" ,e"+c .cumulative~ptionsCost [per]+
",_"+c.excessCost
[per]+","+c.cumulativeCostWithptions[per]+",+optionContractLookup(optionQuant)+",_"+satIDs
[sat]+")
}
optionsCumCosts[optlndex]=c.
cumulativeCostWith0ptions[c.getDemand().length-1];
stmt.executeUpdate (INSERT
,run,
INTO, runcosts
(cumCost
,simuIationID,
contractDurationID),"+
"+lastSim+",_"+run+",
"VALUES("+cumCost+",
"+
durationID+")
{
if(d==3)
for(int
i=0;
i<optionsCumCosts.length;i++)
stmt.executeUpdate("INSERT
{
INTOrun
costs,,(
cumCost,osimulationlD,,run,,contractDurationID),"+
"VALUES("+optionsCumCosts[i]+",,"
+lastSim+",_"+run+",
"+optionContractLookup(optAmt [i])+)");
int]
for(int
fixedLevelArray
f=0;
new
=
int[]
8,
{5,
f<fixedLevelArray.length;
111;
{
f++)
int
fixedLevel
=
fixedLevelArray(f];
int
contractID
=
contractTableLookup(fixedLevel);
int[]
fixedSatLevels=
double
fixedCostPer
i
for(int
=0;
i
=
new
int[sats.length];
0;
<sats.length;
fixedSatLevels[i]
fixedCostPer+=
int
nbrRegions
=
i++)
sats[i].getPrice(fixedLevel,
fixedDemandCovered
=
for
i=0;
i++)
for
i<nbrRegions;
(int
s=0;
for
new doublefnbrRegions];
{
s<fixedSatLevels.length;
(int
r
:
{
{
s++)
sats[s].getRegionso)
if(r==i)
87
12);
simulatedDemand [01[0].length;
double[]
(int
{
fixedLevel;
=
{
fixedDemandCovered[i]+
fixedSatLevels[s]
/
(sats[s].getRegions().length+0.0);
}
modifiedDemand
double []]
=
new
double [simulatedDemand[0].length
][nbrRegions];
for(int i=0; i<modifiedDemand.length; i++) {
for(int
j=0; j<modifiedDemand[0].length;
j++) {
double diff = simulatedDemand[run][i][j]
-
fixedDemandCovered[j];
if(diff< 0.0000001) {
modifiedDemand[i][j]
= 0;
modifiedDemand[i][j]
=
else {
ContractScheduler
modifiedDemand,
18,
diff;
cSpec = new ContractScheduler(sats,
3,
6);
cSpec.csd();
cSpec.outputDecisionso(;
double cumCost=0;
for(int
per=O; per<cSpec.getDemando.length;
for(int
r=0;
per++)
{
r<cSpec.getDemando)[per].length;
r++)
{
stmt.executeUpdate("INSERTeINT0,Demands(
timeStepID,aregionID
Lquantity ,actual-bw
,contractDurationID),"+
"VALUES("+timeStepIDs[per+",,"+(
r+)+",,"+(simulatedDemand[run)[per] [r)+,,"+(cSpec.getActualBWO[cSpec.getPatho)[per]][r]+
fixedDemandCovered[r])+",,"+contractID+")");
d
if
t
(cSpec.getPath()[per]
-1) {
cumCost+=(cSpec.getNodeCosto[cSpec.getPath()[per
]]+
fixedCostPer);
for(int sat=0;
sat<cSpec.getNodeSatBW()[0].length
sat++)(
stmt.executeUpdate("INSERTeINTO,
sat levelsu(timeStepIDusatelliteID,
bandwidth ,cost
,_contractDurationID ,cumCost),"+
"VALUES("+timeSteplDs[per
]+","+satIDs(sat]+",L"+(cSpec.getNodeSatBWO)[cSpec.getPatho)[per])[sat]+
getNodeCost 0)[cSpec.getPatho)[per]]
fixedSatLevels[sat])+"LJ"+(cSpec.
+fixedCostPer)+
",,"+contract1D+",,"+
cumCost+")");
88
stmt.executeUpdate ("INSERT
(cumCost
INT0run-costs
,simulationID,
"+
,run,contractDurationID)
"VALUES("+cumCost+",
"+astSim+","+run+",
"+
contractID+")");
}
}
}
if(isTimingRuns
==
true)
{
int
maxRegions = 4;
int
maxSats=5;
for(int
timeRegions=3;
for(int
timeRegions<maxRegions;
numSats=2;
int[]
numSats<maxSats;
growthTiming
double[]
warProbTiming
rangeMinG
double
rangeMaxG= 1.010;
double
rangeMinW
double
rangeMaxW =
"
r=0;
double[timeRegions];
1.00;
=
0;
=
0.05;
r<distTypesTiming.length;
Random
rand
double
randomValueG
=
new
r++)
{
Randomo;
=
rangeMinG
+
(rangeMaxG
-
rangeMinG)
+
(rangeMaxW
-
rangeMinW)
rand.nextDouble();
growthTiming[r]
double
*
double[timeRegions];
new
=
double
for(int
1);
new
=
{
int[timeRegions];
distTypesTiming=new
Arrays.fill(distTypesTiming,
double[]
{
timeRegions++)
numSats++)
rand.nextDouble
randomValueG;
=
randomValueW
rangeMinW
=
();
warProbTiming[r]
randomValueW;
=
}
Satellite
int
[]
satsT
new Satellite [numSats];
=
satCap=82;
if(timeRegions==3)
{
if(numSats==2)
int[]
{
siTreg
Satellite
Apollo,11",
new
int[]
{0,1};
Satellite(slTreg,
satCap,
"
satCap,
"
satCap,
"
satCap,
"
1.1);
int[]
Apollou13",
new
=
s1T =
=
s2Treg
new
Satellite
s2T =
satsT[0]=
s1T;
int[]
{1,2};
new Satellite(s2Treg,
1.0);
satsT[1]=s2T;
else
if(numSats==3)
int[]
Satellite
Apollo,11",
=
new
s1T =
int[]
{0,1};
new Satellite(slTreg,
1.1);
int[]
s2Treg
Satellite
Apollo,13",
{
slTreg
=
new
=
s2T
int[]
{1,2};
new Satellite(s2Treg,
1.0);
int[]
89
s3Treg
=
new
int [
{0};
FalconSat6",
Satellite
s3T
satsT[01=
slT;
= new Satellite(s3Treg,
satCap,
0.9);
satsT[1] =s2T;
satsT [2]=s3T;
}
else if(numSats==4) {
int[]
sITreg = new int []
Satellite
Apollo1I",
s2Treg = new int[]
Satellite
=
s2T
satCap,
new
{l,2};
Satellite
(s2Treg,
satCap,
s3T = new Satellite(s3Treg,
satCap,
1.0);
int[]
s3Treg = new int[]
Satellite
FalconSat6",
{0,1};
new Satellite(siTreg,
=
1.1);
int[]
Apollo,13",
s1T
{0};
0.9);
int [
s4Treg
Satellite
=
new
{2};
int[
s4T = new Satellite (s4Treg,
satCap,
ElonMusk", 1.11);
satsT[0]= s1T;
satsT [1] =s2T;
satsT [2] =s3T;
sats
[3]=s4T;
}
}
else
if(timeRegions==4)
int []
{
siTreg = new int]
Satellite
=
sIT
new
{0,1,3};
Satellite
(slTreg,
satCap,
"Apollol11"
satCap,
"Apollo,13"
satCap,
"Apollol1l"
satCap,
Apollo.13"
,1.1);
int
] s2Treg = new int[]
1,2};
{
Satellite s2T = new Satellite (s2Treg,
1.0);
satsT[O0]=
s1T;
satsT [1]=s2T;
else if(timeRegions==5)
int[]
Satellite
sITreg
s1T
{
new
=
=
new
int[]
Satellite
{0,1,3};
(slTreg,
1.1);
int[]
s2Treg = new
Satellite s2T = new
int[]
{1,2,4};
Satellite (s2Treg,
1.0);
satsTO]= s1T;
satsT
1]=s2T;
AbstractRealDistribution[]
getDistributions(distTypesTiming,
true);
90
distributionsTiming
=
Demand.
AbstractRealDistribution[]
getContingencies(distTypesTiming,
int
runsPerRegSet
for(int
=
Demand.
run=O;
=2;
run<runsPerRegSet;
int
timingRuns
int
numPeriods=30;
double [][][]
distributionsTiming,
contingenciesTiming
true);
contingenciesTiming,
timingRuns,
timingDemand
growthTiming,
for(int
i=1;
int
run++)
{
1;
=
=
Demand.getDemand(numPeriods,
warProbTiming);
i<2;
{
i++)
levels=1;
{
if(i==l)
levels
=
2;
levels
=
3;
(i==3)
{
levels
=
}
else
{
if(i==2)
}
else
if
4;
}
else
{
if(i==4)
levels=6;
}
else
{
if(i==5)
levels=8;
}
levels=4;
ContractScheduler
satsT,
3,
timingDemand[0],
24,
cTime
=
new ContractScheduler(
levels);
cTime.csd();
stmt . executeUpdate
simulat ionID
,
run ,numPeriods
,numSats
,
numSatLevels ,anumReg ,numNodes
,
"INSERTINTO,,t
numSteps)
im ing-runs(
"+
VALUES("+lastSim+" ,"+run+",
numPeriods+",,"+satsT.length+,-"+cTime.getNumSatLevels
()+",,"+timeRegions+,"+cTime.getNodes
getNumberSteps()+")");
System.out.println("levelsudone:
"+levels);
}
System.out.println("Runadone:,"+run);
System.out.println("TimeRegNumu"+timeRegions+",done.");
System.out.println("NumSatsdone:,"+numSats);
}
}
}
stmt.close();
con.close();
catch(SQLException ex)
System.out.println("\n
{
-- SQIExceptionacaught--\n
91
"+
0)+,"+cTime.
!=null){
while(ex
u"+ex.getMessage());
System.out.println("Message:
System.out.println("SQLState:u,,"+ex.getSQLState ());
System. out. println("ErrorCode :u"+ex. getErrorCode 0)
ex=ex.getNextException);
System.out.println("");
}
catch(Exception e) {
e.printStackTrace 0;
public
static
if
int
contractTableLookup(int
(fixedL
==
return
else
if(
fixedL)
{
{
5)
4;
fixedL
==8
) {
return 5;
else {
return 6;
}
}
public
static
int
optionContractLookup(int
optAmt)
if(optAmt==5) {
return
if(optAmt==10)
else
7;
{
return
8;
returs
9;
{
92
{
Appendix B
Web Application Code
-
Ruby on
Rails
B.1
View
The view utilizes a proprietary package, Highcharts.js, to display simulation results.
The package is free to use for non-commercial websites. For package details and
download, see www.highcharts.com.
<h2>Simulation
Stats</h2>
<table>
<tr>
<th>Number
of Time
<th>Number
of
<th>Number
of Satellites</th>
<th>Number
of regions</th>
<th>Test
Steps</th>
Runs</th>
query</th>
</tr>
<tr>
<td><%=
TimeStep.stepsOnSim(CcurrentSim).count
%></td>
<td><%= TimeStep.stepsOnSim(OcurrentSim).select(:run).distinct.count
<td><X= Qsats.count
X></td>
%></td>
<td><%= OdemandLevels.select(:regionID).distinct.count
<td><%=
X/></td>
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(0,17,51,1)
%></td>
</tr>
</table>
<hl>Sat
<X=
Levels</hl>
form-tag
<%=
select-tag
nil,
method:
:simulation,
:get
do %>
optionsfrom
collectionforselect(Simulation.all,
93
;id,
:id,
CcurrentSim.try(:id))
"Chooseasimulation",
<%= submit-tag
<% end
<% if
name: nil
%>
%>
TimeStep.stepsOnSim('currentSim).select(:run).distinct.count
<script
$(function()
type="text/javascript"
=1
%>
charset="utf-8">
{
new Highcharts.Chart({
chart:
{
renderTo:
title:
"satLevels_12_chart"
{
text: "SatLevelsu12-mouContracts"
},
xAxis:
{
type: "dateTime",
title: {
text: "TimeuPeriodO(3mo)"
}
},
yAxis: {
title:
{
text
:
"Level,(Gbps)"
},
series:
<%
Csats.each
do
Isat I %>
{
isatd%>
name :"sat<=
data:
atTimeStepSat (ts , sat .id , 3) tof
<%=
(TimeStep.stepsOnSim(OcurrentSim)).map
%>
}.inspect
},
<V.
end
V.>
});
</script>
$(function()
-8">
charset="utf
type="text/javascript"
<script
{
new
Highcharts.Chart({
chart:
{
renderTo:
"satLevels_6-chart"
},
title:
text:
"SatLevels,6-moContracts"
type:
"dateTime",
},
xAxis:
{
title:
{
text:
"TimePeriod,(3mo)"
yAxis:
title:
{
text:
"Levelu(Gbps)"
94
{
IteSatLevel.
series:
Osats.each
<%
do
%>
IsatI
name : "sat, <%=,sat . id,%>" ,
<%=
data:
atTimeStepSat(ts,
sat.id,
2).to_f
<%
}.inspect
(TimeStep.stepsOnSim(
currentSim)).map
{
Its SatLevel.
Y>
end %>
</script>
<script
$(function()
type="text/javascript"
charset="utf
-8">
{
new
Highcharts.Chart({
chart :
{
renderTo:
"satLevels 3
chart"
{
title:
text:
"SatLevels
3-moeContracts"
},
xAxis:
{
type:
title:
"dateTime",
{
text:
"TimePeriod(3mo)"
text:
"Level
},
yAxis:
{
title:
{
(Gbps)"
},
series:
<%
Csats.each
do
%>
IsatI
{
name:
data:
atTimeStepSat(ts
sat.id,
1).to.f
<% end
"sat,
<%=
}.inspect
<%=sat.id,%>
(TimeStep.stepsOnSim (OcurrentSim)).map
%>
%>
I
});
</script>
<script
$(function()
type="text/javascript"
charset="utf-8">
{
new
Highcharts.Chart({
chart:
{
renderTo:
"cumulativecost-chart"
},
title:
{
text :
"CumulatIve-Cst of
},
xAxis:
{
95
Run"
{
Its
SatLevel.
type:
"dateTime",
title:
{
text:
"TimePeriod,(3mo)"
yAxis:
title:
{
text:
"Cost,($)"
series:
{
name:"Cumulative
ts,
CostJforul2-moucontracts",
{
Itsl
SatLevel.cumCost(
map {
Itsl
SatLevel.cumCost(
{ Itst
SatLevel.cumCost(
{ Itsl
SatLevel.cumCost(
data: <%= (TimeStep.stepsOnSim(CcurrentSim)).map { Itsi
SatLevel.cumCost(
data:
<%= (TimeStep.stepsOnSim(DcurrentSim)).map
3, Osats.first).to-f }.inspect *1>
1,
name:"CumulativeuCostofor,6-mocontracts",
data:
ts,
2,
Osats.first).to_f
}.inspect
<%=
(TimeStep.stepsOnSim(CcurrentSim))
%>
{
name:"CumulativeCostofor,3-moucontracts",
data:
ts,
1,
Osats.first).to.f
<%=
(TimeStep.stepsOnSim(OcurrentSim)).map
}.inspect %>
},
{
name:"CumulativeUCostoforoFixedl+3-moucontracts",
data:
ts,
4,
Osats
}.inspect
first).to-f
<%= (TimeStep.stepsOnSim(CcurrentSim)).map
%>
},
{
name:"CumulativeuCostuforuFixed2+3-mo
ts,
5, Osats first).to-f
contracts",
%>
}.inspect
name:"CumulativeCostoforFixed3+3-moucontracts",
data:
ts,
6,
Osats.first).to-f
}.inspect
<%=
(TimeStep.stepsOnSim(OcurrentSim)).map
{
Itsi
SatLevel.cumCost(
%>
{
name:"CumulativeCostoforuOptionsl+3mouContracts",
data:
cumCost(ts,
7,
Osats
first)
<%= (TimeStep.stepsOnSim(DcurrentSim)).map
to_f }.inspect
{ Itsl
OptionsCost.
%>
},
{
name:"CumulativeUCostoforuOptions2+3mouContracts",
data: <%=
cumCost(ts,
8, Osats.first).to_f
}.inspect
(TimeStep.stepsOnSim(OcurrentSim)).map {
Itsl
OptionsCost.
Itsl
OptionsCost.
%>
{
name:"CumulativeuCostofru~ptions3+3mouContracts",
data:
cusCost
(ts , 9, Csats
first).tno.f
<4=
}.inspect
(TimeStep.stepsOnSim(CcurrentSim)).map {
V.>
96
});
</script>
<script
type=" text
/javascript"
charset="utf
-8">
{
$(function()
new
Highcharts.Chart({
chart:
{
renderTo:
"cumulativecost-optionschairt"
{
title:
text:
"CumulativeCosteofRun"
type:
"dateTime",
},
{
xAxis:
title:
{
text:
"TimePeriod(3mo)"
text:
"Cost,($)"
}
{
yAxis:
title:
{
}
series:
{
name:"CumulativeuCostforu3-moucontracts,
data:
ts,
1,
Qsats.first).tof
}.inspect
<%=
(TimeStep.stepsOnSim(OcurrentSim)).map
{ ltsI
SatLevel.cumCost(
{ Itsl
OptionsCost.
{
tsl
OptionsCost.
{
ts
%>
name:"CumulativeCostforOptionsl+3moContracts,
data:
cumCost(ts,
7,
Osats.first).to~f
<%=
}.inspect
(TimeStep.stepsOnSim(OcurrentSim)).iap
%>
},
name:"Cumulative
data:
cumCost(ts,
8,
<%=
Options2+3moContracts,
%>
}.inspect
Qsats.first).to-f
Costufor
(TimeStep.stepsOnSim(OcurrentSim)).map
name:CumulativeCostforOptions3+3moContracts",
data:
cumCost(ts,
9,
Osats.first).tof
<%=
}.inspect
(TimeStep.stepsOnSim(OcurrentSim)).map
%>
},
})
;
</script>
<script
$(function()
type="text/javascript"
charset="utf
{
new
Highcharts.Chart({
chart:
{
97
-8">
l
OptionsCost.
"bw-demand-chart"
renderTo:
title:
i
text:
"BandwidthuanduDemanduforuRegionul"
1,
xAxis:
{
type:
title:
"dateTime",
{
text:
"TimeuPeriodO(3mo)"
yAxis:
title:
{
text:
"Level,(Gbps)"
}
series:
name:"Bandwidthofor,12-moucontracts",
data:
atTimeStepRegConActual(ts,
1, 3).to-f
<%=
(TimeStep.stepsOnSim(QcurrentSim)).map
}.inspect
{
Itsl
Demand.
{
Itsl
Demand.
{
Itsl
Demand.
{ ItsI
Demand.
Itsl
Demand.
Itsi
Demand.
{ Itsi
Demand.
%>
{
name:"Bandwidthoforu6-moucontracts",
data:
atTimeStepRegConActual(ts,
<%=
(TimeStep.stepsOnSim(CcurrentSim)).map
1, 2).to-f }.inspect %>
{
name:"Bandwidthoforu3-moucontracts",
data:
atTimeStepRegConActual(ts, 1, 1).tof
<%=
(TimeStep.stepsOnSim(OcurrentSim))
map
}.inspect Y>
{
name:"Demand",
data:
atTimeStepRegConQuantity(ts,
1
1).tof
<%=
(TimeStep.stepsOnSim(currentSim)).map
}.inspect 7.>
1,
{
name:"BandwidthoforFixedl+3-moucontracts",
data:
atTimeStepRegConActual(ts,
1, 4).tof
<%=
(TimeStep.stepsOnSim(CcurrentSim))
}.inspect
map {
%>
{
name:"BandwidthoforFixed2+3-moucontracts",
data:
atTimeStepRegConActual(ts,
<%=
(TimeStep.stepsOnSim(CcurrentSim)).map
1, 5).to-f }.inspect
{
V>
{
name:"BandwidthoforFixed3+3-moucontracts",
data:
<%=
(TimeStep.stepsOnSim(CcurrentSim)).map
atTimeStepRegConActual(ts, 1, 6).to-f }.inspect %>
1);
</script>
<div
id= "satLevels-12_chart"
style= "width:600px;,height:350px;"></div>
98
<div
id=
"satLevels_6-chart
style=
"width:600px;,hoight :350px;"></div>
<div
id=
"satLevels3-chart
style=
"width:600px;,height
<div
id=
"cumulativecost-chart"
style=
<div id=
"cumulativecost-options-chart"
<div
"bw-demand-chart"
<% else
id=
style=
style=
350px;"></div>
"width:600px;,height:450px;"></div>
"width:800px;,height
%>
<script
type=" text/javascript"
charset="utf
-8">
{
$(function()
new
Highcharts.Chart({
{
chart:
renderTo:'cost-histogram',
defaultSeriesType:'column',
borderWidth:0,
backgroundColor:'#eee',
borderWidth:1,
borderColor:
#ccc',
plotBackgroundColor:'#fff',
plotBorderWidth:1,
plotBorderColor:'#ccc'
credits:{enabled:false},
exporting:{enabled:false},
title:{text:
Cost
Histogram},
legend:{
//enabled:false
tooltip:{
borderWidth:1,
formatter:function()
return
{
'<b>Range:</b><br/>
'<b>Count:</b>
'+
'+
this.x
+'<br/>)+
this.y;
}
plotOptions:{
column:{
shadow:false,
borderWidth:.5,
borderColor:'#666',
pointPadding:0,
groupPadding:0,
color:
spline
'rgba(204,204,204,.85)'
:{
shadow:false,
marker:{
radius:1
}
areaspline
:{
color:'rgb(69,
114,
fillColor:'rgba(69,
:700px;"></div>
"width:600px;,height :350px;"></div>
167)',
114,
167,.25)',
shadow:false,
marker:{
radius:1
99
xAxis :{
0 < 20','>=
['>=
categories:
40','>=
20
140', '>=
140 < 160', '>=
160
<
180', '>=
280','>=
280
300
<
320',
300','>=
<
40
<
180
320
'>=
< 60','>=
200', '>=
340',
<
200
60
< 80','>=
<
220', '>=
340
'>=
<
360',
<
80
220
'>=
<
360
100','>=
<
<
100
240', '>=
380',
120', '>=
240
<
'>=
380
<
120
260', '>=
260
<
400'],
<
labels :{
rotation:-90,
y:20,
style:
{
fontSize:'8px',
fontWeight:'normal',
color:'#333'
lineWidth:0,
lineColor:'#999',
tickLength:70,
tickColor:'#cccl,
{
yAxis:
title:
{
text:
"Frequency"
}
series:
{
name :"3moContractCosts",
data:
[<%=
RunCost.onSim(CcurrentSim).countBetween(0,20000,
RunCost.onSim(8currentSim) .countBetween(20000,40000,
1)
1)
%>,<=
%>,<V= RunCost.onSim(OcurrentSim) .countBetween
1) %>,< %= RunCost .onSim(8currentSim).countBetween(60000,80000,
1) %>,<V= RunCost.onSim(
OcurrentSim).countBetween(80000,100000, 1) %>, <%= RunCost.onSim(6currentSim).countBetween(100000,120000,
%>,<%= RunCost.onSim(currentSim).countBetween(120000,140000,
1) %>, <%= RunCost.onSim(OcurrentSim).
(40000,60000,
countBetween(140000,160000,
1)
%>,<%= RunCost .onSim(OcurrentSim) .countBetween(160000,180000,
RunCost .onSim(OcurrentSim) .countBetween(180000,200000,
(200000,220000,
1)
%>,
<%= RunCost.onSim(
OcurrentSim) .countBetween(240000,260000,
1)
%>,
1)
%>,
<%=
%>,
RunCost .onSim(OcurrentSim)
<%= RunCost.onSim(OcurrentSim).countBetween(280000,300000,
countBetween(300000,320000,
RunCost .onSim(OcurrentSim)
(360000,380000,
1)
%>,
1)
%>,
<%=
1)
%>,
<%=
1)
1) %>,
<%=
RunCost.onSim(
.countBetween(260000,280000,
.>, <%= RunCost.onSim(#currentSim).
RunCost.onSim(QcurrentSim).countBetween(320000,340000,
.countBetween(340000,360000,
%>,
<%= RunCost.onSim(OcurrentSim) .countBetween
currentSim).countBetween(220000,240000,
1)
1)
1)
1)
%>,
<%=
<%= RunCost.onSim(OcurrentSim) .countBetween
<%= RunCost.onSim(OcurrentSim).countBetween(380000,400000,
1)
%>
{
name:"6mouContractCosts",
data:
[<%=
RunCost.onSim(
RunCost.onSim(OcurrentSim) .countBetween(20000,40000,
(40000,60000,
2)
V.>,<V=
2)
currentSim).countBetween(0,20000,
2)
%>,<%=
%>,<V= RunCost.onSim( OcurrentSim) .countBetween
RunCost .onSim(OcurrentSim).countBetween(60000,80000,
2)
%>,<V= RunCost .onSim(
OcurrentSim) .countBetween(80000,100000,
2) %>,
<.= RunCost.onSim(OcurrentSim) .countBetween(100000,120000
%>,< %= RunCost.onSim(OcurrentSim).countBetween(120000,140000,
2) %>, <%= RunCost.onSim(OcurrentSim).
countBetween(140000,160000, 2) %>,<%= RunCost.onSim(OcurrentSim).countBetween(160000,180000,
2) %>, < =
RunCost .onSim(
(200000,220000,
currentSim) .countBetween(180000,200000,
2)
%>,
<%=
%>,
<%= RunCost .onSim(OcurrentSim)
countBetween(300000,320000,
2)
%>,
2)
%>,
<%=
.countBetween(280000,300000,
2)
%>,
2)
%>,
2)
%>,
<%= RunCost.onSim(
.countBetween(260000,280000,
<%= RunCost.onSim(OcurrentSim).
<%= RunCost.onSim(CcurrentSim).countBetween(320000,340000,
2)
%>,
2)
%>,
<%=
<%= RunCost.onSim(CcurrentSim).countBetween
<%= RunCost.onSim(CcurrentSim).countBetween(380000,400000,
2)
%>
{
name:"
12moContract,,Costs",
data:
[<%=
RunCost.onSim(OcurrentSim).countBetween(0,20000,
RunCost.onSim(CcurrentSim).countBetween(20000,40000,
3)
100
2)
<V= RunCost.onSim(OcurrentSim) .countBetween
RunCost .onSim(CcurrentSim)
RunCost.onSim(OcurrentSim).countBetween(340000,360000,
(360000,380000,
%>,
RunCost.onSim(OcurrentSim).countBetween(220000,240000,
OcurrentSim) .countBetween(240000,260000,
2)
2)
,
3)
%>,<%=
%>,<%= RunCost.onSim(CcurrentSim).countBetween
(40000,60000,
3)
%>,<%= RunCost.onSim(OcurrentSim).countBetween(60000,80000,
OcurrentSim).countBetween(80000,100000,
%>,<%= RunCost.onSim(CcurrentSim).countBetween(120000,140000,
countBetween(140000,160000,
3)
%>,<%=
3)
%>,
<%=
%>,
3)
3)
%>,
3)
%>,
3)
%>,
%>,
<%=
%>,
3)
<%=
3)
%>,
<%= RunCost.onSim(
<%= RunCost .onSim(OcurrentSim) .countBetween(260000,280000,
3)
%>,
<%= RunCost.onSim(CcurrentSim).
<%= RunCost .onSim(CcurrentSim) .countBetween(320000,340000
RunCost.onSim(CcurrentSim).countBetween(340000,360000,
3)
3)
<%= RunCost.onSim (CcurrentSim).
<%= RunCost.onSim(OcurrentSim).countBetween
<%= RunCost.onSim(OcurrentSim).countBetween(280000,300000,
countBetween(300000,320000,
(360000,380000,
%>,
RunCost.onSim(OcurrentSim).countBetween(220000,240000,
CcurrentSim) .countBetween(240000,260000,
3)
RunCost.onSim(
RunCost.onSim(CcurrentSim).countBetween(160000,180000,
RunCost.onSim(CcurrentSim).countBetween(180000,200000,
(200000,220000,
%>,<%=
3)
<%= RunCost.onSim(CcurrentSim).countBetween(100000,120000,
3) %>,
3)
%>,
,
3)
<%=
%>,
<%= RunCost.onSimOcurrentSim).countBetween
RunCost.onSim(OcurrentSim).countBetween(380000,400000,
3)
%>
},
{
name: "Fixedl,+,3,MoCosts",
[<%=
data:
RunCost.onSim(OcurrentSim).countBetween(0,20000,
RunCost.onSim(CcurrentSim).countBetween(20000,40000,
(40000,60000,
%>,<%=
4)
4)
RunCost.onSim(OcurrentSim).countBetween(60000,80000,
OcurrentSim).countBetween(80000,100000,
4)
%>,
RunCost .onSim(OcurrentSim)
(200000,220000,
4)
%>,
<%=
4)
4)
%>,
<%=
4)
4)
%>,
<%=
4)
%>,
<%=
4)
%>,
<%=
<%=
4)
%>,
4)
%>,
<V=
RunCost.onSim(OcurrentSim) .countBetween
4)
<V=
4)
RunCost.onSim (currentSim).
%>,
4)
<V= RunCost.onSim(
%>,
.countBetween(260000,280000,
<%= RunCost.onSim(OcurrentSim).
<%= RunCost.onSim(OcurrentSim).countBetween(320000,340000,
RunCost.onSim(OcurrentSim).countBetween(340000,360000,
%>,
%>,
RunCost .onSim(OcurrentSim)
RunCost.onSim(OcurrentSim).countBetween(280000,300000,
4)
%>,<%= RunCost.onSim(
RunCost.onSim(OcurrentSim).countBetween(220000,240000,
countBetween(300000,320000,
(360000,380000,
4)
%>,<%= RunCost.onSim(OcurrentSim).countBetween(160000,180000,
.countBetween(180000,200000,
OcurrentSim) .countBetween(240000,260000,
%>,<V=
<%= RunCost.onSim(OcurrentSim).countBetween(100000,120000,
%>,<V= RunCost.onSim (currentSim).countBetween(120000,140000,
countBetween(140000,160000,
4)
%>,<V= RunCost.onSim(CcurrentSim).countBetween
4)
<%=
%>,
RunCost.onSim (currentSim).countBetween
RunCost.onSim(OcurrentSim).countBetween(380000,400000,
4)
%>
{
name:
Fixed2,+,3,MoCost s"
data:
[<%= RunCost.onSim(OcurrentSim).countBetween(0,20000,
RunCost.onSim(OcurrentSim).countBetween(20000,40000,
(40000,60000,
5)
5)
'.>,<V=
V>,<V.= RunCost.onSim(OcurrentSim).countBetween(60000,80000,
OcurrentSim).countBetween(80000,100000,
5)
%>,
<V=
5)
%>,<%=
OcurrentSim)
5)
%>,
5)
%>,
<V=
5)
5)
V>,
<%=
5)
%>,
5)
%>,
<%= RunCost.onSim(
<V=
5)
V.>,
<%=
5)
5)
%>,
<%=
RunCost.onSim(OcurrentSim).countBetween
5)
%>,
5)
<%= RunCost.onSim(
%>,
.countBetween(260000,280000,
<%= RunCost.onSim(OcurrentSim).
OcurrentSim).countBetween(320000,340000,
RunCost.onSim(OcurrentSim).countBetween(340000,360000,
%>,
RunCost.onSim(
<%= RunCost.onSim ( currentSim).
<%= RunCost .onSim(QcurrentSim)
<V= RunCost.onSim(OcurrentSim).countBetween(280000,300000,
countBetween(300000,320000,
5)
%>,
RunCost.onSim(OcurrentSim).countBetween(220000,240000,
.countBetween(240000,260000,
(360000,380000,
%>,<%=
5)
RunCost.onSim(OcurrentSim).countBetween(160000,180000,
RunCost.onSim(currentSim).countBetween(180000,200000,
(200000,220000,
%>,<%=
RunCost.onSim(CcurrentSim).countBetween(100000,120000,
%>,<= RunCost.onSim(OcurrentSim).countBetween(120000,140000,
countBetween(140000,160000,
5)
RunCost.onSim(CcurrentSim).countBetween
5)
%>,
<%=
RunCost.onSim(CcurrentSim).countBetween
RunCost.onSim(OcurrentSim).countBetween(380000,400000,
5)
%>
]
},
{
name:
Fixed3,+ 3uMouCosts
data:
[<%= RunCost.onSim(OcurrentSim).countBetween(0,20000,
RunCost.onSim(OcurrentSim).countBetween(20000,40000,
(40000,60000,
6)
6) V>,<%=
V>,<V.= RunCost.onSim(CcurrentSim).countBetween
6)
%>,<%= RunCost.onSim(OcurrentSim).countBetween(60000,80000,
6)
%>,<V= RunCost.onSim(
OcurrentSim).countBetween(80000,100000, 6) %>, <%= RunCost.onSim(CcurrentSim).countBetween(100000,120000,
%>,<%= RunCost.onSim(OcurrentSim).countBetween(120000,140000, 6) %>, <%= RunCost.onSimn(CcurrentSim).
countBetween(140000,160000,
RunCost.onSim(
(200000,220000,
6)
%>,<%= RunCost.onSim(CcurrentSim).countBetween(160000,180000,
currentSim).countBetween(180000,200000,
6)
%>,
</=
%>,
%>,
6)
%>,
RunCost.onSim(
(360000,380000,
6)
%>,
%>,
<%=
6)
%>,
<%=
<%= RunCost.onSim(
6)
%>,
<%= RunCost.onSim(OcurrentSim).
<%= RunCost.onSim(OcurrentSim).countBetween(320000,340000,
currentSim).countBetween(340000,360000,
6)
%>,
<%= RunCost .onSim(CcurrentSim) .countBetween(260000,280000,
<V= RunCost.onSim(OcurrentSim).countBetween(280000,300000,
countBetween(300000,320000,
6)
<%= RunCost.onSim( OcurrentSim).countBetween
RunCost.onSim(OcurrentSim).countBetween(220000,240000,
OcurrentSim) .countBetween(240000,260000,
6)
6)
6)
%>,
<%=
RunCost.onSim(OcurrentSim).countBetween(380000,400000,
{
101
6)
%>,
<%=
RunCost.onSim(OcurrentSim).countBetween
6)
%>
]
6)
name:"Optionslu+u3uMouCosts",
data:
[<%= RunCost.onSim(CcurrentSim).countBetween(0,20000,
RunCost .onSim(OcurrentSim) .countBetween(20000,40000,
(40000,60000,
OcurrentSim)
7)
%>,<Y=
7)
%>,<%=
RunCost.onSim(OcurrentSim).countBetween(60000,80000,
.countBetween(80000,100000,
%>,
7)
%>,<%=
7)
7)
(200000,220000,
%>,
%>,
7)
<%=
7)
7)
%>,
<%=
7)
<%=
%>,
%>,
7)
<%=
7)
<%= RunCost.onSim(OcurrentSim).
7)
%>,
<%=
RunCost.onSim(CcurrentSim).countBetween
7)
%>,
<%=
RunCost.onSim(
%>,
7)
<%=
RunCost.onSim(CcurrentSim).
7)
<%= RunCost.onSim(OcurrentSim).countBetween(320000,340000,
RunCost.onSim(currentSim).countBetween(340000,360000,
%>,
%>,<%= RunCost.onSim(
RunCost.onSim(CcurrentSim).countBetween(260000,280000,
RunCost.onSim(CcurrentSim).countBetween(280000,300000,
7)
%>,
<%= RunCost.onSim(OcurrentSim).countBetween(220000,240000,
countBetween(300000,320000,
(360000,380000,
7)
RunCost.onSim(CcurrentSim).countBetween(160000,180000,
RunCost.onSim(QcurrentSim).countBetween(180000,200000,
OcurrentSim).countBetween(240000,260000,
%>,<%=
<%= RunCost.onSim(CcurrentSim).countBetween(100000,120000,
7>,<7= RunCost.onSim(OcurrentSim).countBetween(120000,140000,
countBetween(140000,160000,
7)
RunCost.onSim(OcurrentSim).countBetween
7)
%>,
<%=
%>,
<%= RunCost.onSim(CcurrentSim).countBetween
RunCost.onSim(currentSim).countBetween(380000,400000,
7)
%>
{
name:"Options2,+u3AMouCosts',
data:
(40000,60000,
8)
8)
7>,<%=
8)
8)
%>,
<%=
%>,
8)
<%=
8)
%>,
8)
<%=
%>,
8)
%>,
%>,
<%=
8)
%>,
<%=
8)
%>,
<%= RunCost.onSim(
RunCost.onSim(OcurrentSim).countBetween(260000,280000,
8)
%>,
<%= RunCost.onSim(OcurrentSim).
<%= RunCost.onSim(OcurrentSim).countBetween(320000,340000,
8)
RunCost.onSim(CcurrentSim).countBetween(340000,360000,
8)
8)
<%= RunCost.onSim(OcurrentSim).
<%= RunCost.onSim(CcurrentSim).countBetween
RunCost .onSim(OcurrentSim) .countBetween(280000,300000,
countBetween(300000,320000,
(360000,380000,
%>,
RunCost.onSim(OcurrentSim).countBetween(220000,240000,
OcurrentSim).countBetween(240000,260000,
8)
%>,<%= RunCost.onSim(
%>,<%= RunCost.onSim(CcurrentSim).countBetween(160000,180000,
RunCost.onSim(OcurrentSim) .countBetween(180000,200000,
(200000,220000,
8)
<%= RunCost.onSim(OcurrentSim).countBetween(100000,120000,
%>,
RunCost.onSim(6currentSim).countBetween(120000,140000,
countBetween(140000,160000,
%>,<%=
%>,<%= RunCost.onSim(CcurrentSim).countBetween
%>,<%= RunCost .onSim(OcurrentSim) .countBetween(60000,80000,
8)
OcurrentSim).countBetween(80000,100000,
8)
[<%= RunCost.onSim(OcurrentSim).countBetween(0,20000,
RunCost.onSim(CcurrentSim).countBetween(20000,40000,
%>,
8)
<%=
%>,
<%= RunCost.onSim(OcurrentSim).countBetween
RunCost.onSim (currentSim).countBetween(380000,400000,
8)
%>
{
name:"Options3u+u3uMoCosts",
data:
[<*/=
RunCost.onSim(CcurrentSim).countBetween(0,20000,
RunCost.onSim(OcurrentSim).countBetween(20000,40000,
(40000,60000,
9)
7.>,<%=
9)
%>,<%=
RunCost.onSim(OcurrentSim).countBetween(60000,80000,
9)
OcurrentSim) .countBetween(80000,100000,
9)
%>,<%=
(200000,220000,
9)
%>,
%>,
9)
9)
9)
%>,
9)
%>,
9)
%>,
RunCost.onSim(
<%=
9)
<%= RunCost.onSim(CcurrentSim).
9)
%>,
<%=
9)
%>,
<%=
RunCost.onSim(
<%= RunCost.onSim(OcurrentSim).countBetween(260000,280000,
.>, <%= RunCost.onSim(CcurrentSim).
9)
RunCost.onSim(ScurrentSim).countBetween(320000,340000,
RunCost .onSim(CcurrentSim) .countBetween(340000,360000,
%>,
%>,<%=
<%= RunCost.onSim(CcurrentSim).countBetween
<%= RunCost.onSim(OcurrentSim).countBetween(280000,300000,
9)
%>,
<%= RunCost.onSim(CcurrentSim).countBetween(220000,240000,
countBetween(300000,320000,
(360000,380000,
9)
RunCost.onSim(CcurrentSim).countBetween(160000,180000,
RunCost.onSim(CcurrentSim).countBetween(180000,200000,
OcurrentSim).countBetween(240000,260000,
%>,<%=
<%= RunCost.onSim(CcurrentSim).countBetween(100000,120000,
%>,
%>,<%= RunCost.onSim(CcurrentSim).countBetween(120000,140000,
countBetween(140000,160000,
9)
RunCost.onSim(CcurrentSim).countBetween
9)
%>,
9)
%>,
<.=
<%= RunCost.onSim(CcurrentSim).countBetween
<%= RunCost.onSim(8currentSim).countBetween(380000,400000,
9)
%>
{
name:'3mo Curve',
type:
spline
,
visible:false,
data:
[<%= RunCost.onSim(currentSim).countBetween(0,20000,
countBetween(20000,40000,
1)
onSim(CcurrentSim).countBetween(60000,80000,
1)
%>,
1)
%>,<%=
1)
%>,
1)
%>,
<%=
1)
1)
1)
%>,
%>,<%=
RunCost.
%>,<%= RunCost.onSim(OcurrentSim).
1)
%>,
1)
%>,<%=
<%= RunCost.onSim(CcurrentSim).countBetween
<%= RunCost.onSim(OcurrentSim).countBetween(200000,220000,
OcurrentSim).countBetween(220000,240000,
%>,
RunCost.onSim(OcurrentSim).
<%= RunCost.onSim(OcurrentSim).countBetween(140000,160000,
RunCost.onSim(OcurrentSim).countBetween(160000,180000,
(180000,200000,
V>,<V=
RunCost.onSim(CcurrentSim).countBetween(80000,100000,
<%= RunCost.onSim(OcurrentSim).countBetween(100000,120000,
countBetween(120000,140000,
1)
1)
%>,<%= RunCost.onSim(OcurrentSim) .countBetween(40000,60000,
1)
%>,
<%=
RunCost.onSim(
<%= RunCost .onSim(OcurrentSim).countBetween(240000,260000,
RunCost.onSim(CcurrentSim).countBetween(260000,280000,
102
1)
%>,
<%= RunCost.onSim(OcurrentSim).
countBetween(280000,300000,
1) %>, <%= RunCost.onSim(CcurrentSim).countBetween(300000,320000,
1) %>,
<V=
RunCost.onSim(CcurrentSim).countBetween(320000 340000, 1)
.>, <%= RunCost.onSim(CcurrentSim).countBetween
(340000,360000,
1) .>, <%= RunCost.onSim(OcurrentSim).countBetween(360000,380000,
1) %>,
<%= RunCost.onSim(
CcurrentSim) .countBetween(380000,400000,
//color:
V> ]
1)
'rgba(204,204,255,.85)'
},
{
name:'6mo Curve',
type:'spline
,
visible:false,
data:
[<%= RunCost.onSim(OcurrentSim).countBetween(0,20000,
countBetween(20000,40000,
2)
%>,
countBetween(120000,140000,
2)
2)
<%= RunCost.onSim(CcurrentSim).countBetween(140000,160000,
%>,
RunCost.onSim(CcurrentSim).countBetween(160000,180000,
(180000,200000,
2)
<%=
%>,
%>,
2)
countBetween(280000,300000,
2)
%>,<%=
%>,
<%= RunCost .onSim(currentSim) .countBetween(240000,260000,
%>,
2)
<%=
%>,
%>,
2)
%>,
<%= RunCost.onSim(OcurrentSim).
RunCost.onSim(OcurrentSim).countBetween(300000,320000,
RunCost.onSim(CcurrentSim).countBetween(320000,340000,
2)
%>,
2)
2)
<%=
%>,
<%= RunCost.onSim(CcurrentSim).countBetween
RunCost.onSim(OcurrentSim).countBetween(360000,380000,
<%=
OcurrentSim) .countBetween (380000 ,400000,
//color:
2)
RunCost.onSim(CcurrentSim).countBetween(260000,280000,
(340000,360000,
2)
<%= RunCost.onSim(CcurrentSim).countBetween
<%= RunCost.onSim(OcurrentSim).countBetween(200000,220000,
2) %>, <%= RunCost.onSim(
CcurrentSim) .countBetween(220000,240000,
2)
V>,<V= RunCost.onSim(OcurrentSim).
2) %>,<%= RunCost.
%>,<%= RunCost .onSim(CcurrentSim) .countBetween(80000,100000,
<%= RunCost.onSim(CcurrentSim).countBetween(100000,120000,
2) %>,<%= RunCost.onSim(OcurrentSim).
onSim(CcurrentSim).countBetween(60000,80000,
2)
2)
%>,<%= RunCost.onSim(CcurrentSim).countBetween(40000,60000,
2)
%>,
<%=
RunCost.onSim(
%>
'rgba(204,204,255,.85)'
{
name:'12mo Curve',
type:'spline
,
visible:false,
data:
[<%= RunCost.onSim(OcurrentSim).countBetween(0,20000,
countBetween(20000,40000,
3)
onSim(OcurrentSim).countBetween(60000,80000,
3)
%>,
3)
%>,<V= RunCost.onSim(OcurrentSim).
3) %>,<= RunCost.
%>,<V= RunCost.onSim(OcurrentSim).countBetween(80000,100000,
<%= RunCost.onSim(CcurrentSim).countBetween(100000
countBetween(120000,140000,
3)
%>,<%= RunCost.onSim(OcurrentSim).countBetween(40000,60000,
3)
120000,
3)
%>,<%= RunCost.onSim(OcurrentSim).
<%= RunCost.onSim(OcurrentSim).countBetween(140000,160000,
%>,
RunCost.onSim(OcurrentSim).countBetween(160000,180000,
3)
%>,
3)
%>,<=
<%= RunCost.onSim(OcurrentSim).countBetween
(180000,200000,
3) %>, <%= RunCost.onSim(currentSim).countBetween(200000,220000,
3) %>, <%= RunCost.onSim(
OcurrentSim).countBetween(220000,240000, 3) Y.>, <%= RunCost.onSim(OcurrentSim).countBetween(240000,260000,
3)
%>,
<%= RunCost.onSim(OcurrentSim).countBetween(260000,280000,
countBetween(280000,300000,
3)
%>,
<%=
RunCost.onSim(CcurrentSim).countBetween(320000,340000,
(340000,360000,
3)
%>,
<%=
%>,
<%=
RunCost.onSim(OcurrentSim).
3)
%>,
<%=
3)
3)
<%=
%>,
RunCost.onSim(OcurrentSim).countBetween
RunCost .onSim(OcurrentSim).countBetween(360000,380000,
OcurrentSim).countBetween(380000,400000,
//color:
3)
RunCost.onSim(OcurrentSim).countBetween(300000,320000,
3)
%>,
<%= RunCost .onSim(
%> ]
'rgba(204,204,255,.85)'
{
name:'Fixedl+3mo Curve',
type:'splinel,
visible:false,
data:
[<%=
RunCost.onSim(OcurrentSim).countBetween(0,20000,
4) %>, <%= RunCost.onSim(OcurrentSim).
%>,<%= RunCost.onSim(OcurrentSim).countBetween(40000,60000,
4) %>,<%= RunCost.
onSim (OcurrentSim) .countBetween (60000 80000, 4) %>, <%= RunCost .onSim (OcurrentSim) .countBetween
(80000 ,100000,
countBetween(20000,40000,
4)
%>,
4)
<%= RunCost.onSim(OcurrentSim).countBetween(100000,120000,
countBetween(120000,140000,
4)
%>,
<.=
RunCost .onSim(OcurrentSim) .countBetween(160000,180000,
(180000,200000,
4)
%>,
<%=
%>,
%>,<V= RunCost.onSim(OcurrentSim).
4)
%>,
<V= RunCost.onSim(CcurrentSim)
RunCost.onSim(OcurrentSim).countBetween(200000,220000,
OcurrentSim).countBetween(220000,240000,
4)
4)
RunCost.onSim(OcurrentSim).countBetween(140000,160000,
4)
%>,
<%=
4)
%>,<=
.countBetween
RunCost.onSim(
<%= RunCost.onSim(OcurrentSim).countBetween(240000,260000,
<%= RunCost.onSim(OcurrentSim).countBetween(260000,280000,
4) %>,
<%= RunCost.onSim(OcurrentSim).
countBetween(280000,300000,
4)
%>,
<%=
4)
%>,
RunCost.onSim(OcurrentSim).countBetween(300000,320000,
RunCost.onSim(OcurrentSim).countBetween(320000,340000,
(340000,360000,
4)
%>,
<V=
4)
%>,
<%=
RunCost.onSim(OcurrentSim).countBetween(360000,380000,
OcurrentSim) .countBetween(380000
400000,
4) %>
]
103
4)
%>,
<%=
RunCost.onSim(OcurrentSim).countBetween
4)
%>,
<%= RunCost.onSim(
//color:
'rgba(204,204,255,.85)'
},
{
name:'Fixed2+3mo Curve',
,
type:'spline
visible:false,
data:
[<%= RunCost.onSim(CcurrentSim) .countBetween(0,20000,
5) %>,<%= RunCost .onSim(OcurrentSim)
countBetween(20000,40000,
5)
%>,
5)
<%= RunCost.onSim(O currentSim).countBetween(100000,120000,
5)
countBetween(120000,140000,
%>,
5)
OcurrentSim)
%>,
%>,<%= RunCost.onSim(OcurrentSim).
%>,<%=
5)
<%= RunCost.onSim(OcurrentSim) .countBetween
.countBetween(220000,240000,
5)
<%= RunCost.onSim(OcurrentSim).countBetween(260000,280000,
%>,
RunCost
%>,<%=
5) 7>, <%= RunCost.onSim(
.>, <%= RunCost.onSim(OcurrentSim).countBetween(200000,220000,
5) 7>, <%= RunCost.onSim(DcurrentSim) .countBetween(240000,260000,
5)
(180000,200000,
5)
.countBetween(80000,100000,
RunCost.onSim(OcurrentSim).countBetween(140000,160000,
<%=
RunCost.onSim(6currentSim). countBetween(160000,180000,
5)
.countBetween(40000,60000,
%>,<%= RunCost.onSim(CcurrentSim)
5)
onSim(CcurrentSim). countBetween(60000,80000,
%>,<%= RunCost.onSim(OcurrentSim)
5)
5)
countBetween(280000,300000,
%>,
<%=
5)
.>, <%=
5)
<%= RunCost.onSim(OcurrentSim) .countBetween
%>, <%= RunCost.onSim(OcurrentSim).countBetween(360000,380000,
OcurrentSim).countBetween(380000,400000,
//color:
%>,
5)
RunCost .onSim(OcurrentSim).countBetween(320000,340000,
(340000,360000,
%>, <%= RunCost.onSim(OcurrentSim).
RunCost.onSim(OcurrentSim).countBetween(300000,320000,
5)
%>,
<%= RunCost.onSim(
5) %> 1
'rgba(204,204,255,.85)'
{
name:'Fixed3+3mo Curve',
type:'spline
,
visible:false,
data:
[<%=
RunCost.onSim(OcurrentSim).countBetween(0,20000,
6)
onSim(OcurrentSim) .countBetween(60000,80000,
6)
6)
6)
<%=
%>,
%>,
6)
6)
6)
RunCost.onSim(OcurrentSim).countBetween(320000,340000,
6)
(340000,360000,
%>,
6)
//color:
%>,
6)
7>, <%= RunCost.onSim(
<%= RunCost.onSim(OcurrentSim).
%>,
6)
%>,
<%=
<%= RunCost.onSim(OcurrentSim).countBetween
<%= RunCost.onSim(OcurrentSim).countBetween(360000,380000,
OcurrentSim).countBetween(380000,400000, 6)
%>,<%=
<%= RunCost.onSim(OcurrentSim) .countBetween(240000,260000,
<%= RunCost.onSim(tcurrentSim).countBetween(300000,320000,
%>,
6)
<%= RunCost.onSim(CcurrentSim).countBetween
RunCost.onSim(CcurrentSim).countBetween(260000,280000,
countBetween(280000,300000,
%>,<%= RunCost.
%>,<%= RunCost.onSim(OcurrentSim).
7>, <%= RunCost.onSim(OcurrentSim).countBetween(200000,220000,
6)
CcurrentSim) .countBetween(220000,240000,
%>,
6)
<%= RunCost.onSim(CcurrentSim).countBetween(140000,160000,
%>,
RunCost.onSim(6currentSim).countBetween(160000,180000,
(180000,200000,
6)
%>,<%= RunCost.onSim(CcurrentSim) .countBetween(80000,100000,
.>, <%= RunCost.onSim(CcurrentSim).countBetween(100000,120000,
countBetween(120000,140000,
6)
%>,<%= RunCost.onSim(OcurrentSim).
6)
%>,<%= RunCost.onSim(OcurrentSim) .countBetween(40000,60000,
6)
countBetween(20000,40000,
6)
%>,
<%= RunCost.onSim(
%> 1
'rgba(204,204,255,.85)'
{
name:"Optionslu+u3uMouCosts",
type:'spline
,
visible:false,
data:
[<%=
(40000,60000,
7)
%>,<%=
%>,<%=
RunCost.onSim(
7)
7>,
7)
7)
%>,<%=
7)
7>,
<%=
7>,
<%=
7)
7)
7>,
7)
7>,
</=
7)
%>,
7)
%>,
7)
7>,
<%=
7)
%>,
<%=
RunCost.onSim(
RunCost.onSim(CcurrentSim).countBetween(260000,280000,
7)
7>,
<%= RunCost.onSim(CcurrentSim).
<%= RunCost.onSim(OcurrentSim).countBetween(320000,340000,
RunCost.onSim(DcurrentSim).countBetween(340000,360000,
7)
%>,
<%=
{
name:"Options2u+u3uMouCosts",
104
7)
7>,
<%=
RunCost.onSim(OcurrentSim).countBetween
<%= RunCost.onSim(OcurrentSim).countBetween(380000,400000,
type: spline ',
7)
<%= RunCost.onSim(OcurrentSim).
<%= RunCost.onSim(OcurrentSim).countBetween
RunCost.onSim(OcurrentSim).countBetween(280000,300000,
countBetween(300000,320000,
(360000,380000,
7>,
RunCost.onSim(OcurrentSim).countBetween(220000,240000,
OcurrentSim).countBetween(240000,260000,
7)
%>,<%= RunCost.onSim(
RunCost.onSim(OcurrentSim).countBetween(160000,180000,
RunCost.onSim(OcurrentSim).countBetween(180000,200000,
(200000,220000,
7)
<%= RunCost.onSim(OcurrentSim).countBetween(100000,120000,
currentSim).countBetween(120000,140000,
countBetween(140000,160000,
%>,<Y=
%>,<%= RunCost.onSim(OcurrentSim).countBetween
RunCost.onSim(icurrentSim).countBetween(60000,80000,
OcurrentSim).countBetween(80000,100000,
7)
RunCost.onSim(OcurrentSim).countBetween(0,20000,
RunCost.onSim(OcurrentSim).countBetween(20000,40000,
7)
7> 1
visible:false,
[<%=
data:
RunCost.onSim(CcurrentSim).countBetween(0,20000,
RunCost.onSim(OcurrentSim).countBetween(20000,40000,
(40000,60000,
%>, <%=
8)
8)
%>,
<%=
RunCost.onSim(OcurrentSim).countBetween(120000,140000,
countBetween(140000,160000,
8)
%>,<V=
(200000,220000,
8)
V>,
</=
%>,
<%=
8)
8)
%>,
<%=
8)
%>,
<%=
8)
%>,
<%=
<%=
%>,<%=
RunCost.onSim(
<%=
8)
%>,
8)
<%=
%>,
RunCost.onSim(OcurrentSim).countBetween
8)
<%=
8)
RunCost.onSim(CcurrentSim).
%>,
<%=
8)
%>,
<%=
RunCost.onSim(
.countBetween(260000,280000,
RunCost.onSim(OcurrentSim).
RunCost.onSim(OcurrentSim).countBetween(320000,340000,
RunCost.onSim(OcurrentSim).countBetween(340000,360000,
%>,
7.>,
RunCost .onSim(CcurrentSim)
RunCost.onSim(OcurrentSim).countBetween(280000,300000,
8)
%>,<V=
RunCost.onSim(CcurrentSim).countBetween(220000,240000,
countBetween(300000,320000,
(360000,380000,
8)
RunCost.onSim(OcurrentSim).countBetween(160000,180000,
OcurrentSim) .countBetween(240000,260000,
8)
RunCost.onSim(CcurrentSim).countBetween
RunCost.onSim(CcurrentSim).countBetween(100000,120000,
RunCost.onSim(OcurrentSim).countBetween(180000,200000,
8)
%>,<V=
RunCost.onSim(OcurrentSim).countBetween(60000,80000,
OcurrentSim).countBetween(80000,100000,
%>,<%=
8)
8)
<%=
%>,
RunCost.onSim(OcurrentSim).countBetween
RunCost.onSim(CcurrentSim).countBetween(380000,400000,
8)
%>
{
name:"Options3,+,3,MoCosts,
type:'spline
,
visible:false,
[<%=
data:
RunCost .onSim(8currentSim)
(40000,60000,
OcurrentSim)
%>,<V=
9)
%>,<%=
RunCost.onSim(ocurrentSim).countBetween(0,20000,
.countBetween(20000,40000,
9)
9)
%>,
<%=
RunCost .onSim (0currentSim).
RunCost.onSim(CcurrentSim).countBetween(120000,140000,
countBetween(140000,160000,
(200000,220000,
OcurrentSim)
%>,
<%=
9)
%>,
9)
%>,<%=
<%=
9)
%>,
<%=
9)
%>,
<%=
9)
%>,
9)
<%=
%>,
<%=
-8">
{
new
Highcharts.Chart({
chart :
{
renderTo: 'satLevel-histogram
defaultSeriesType:lcolumn',
borderWidth:0,
backgroundColor:'#eee',
borderWidth:1,
borderColor:'#cccl,
plotBackgroundColor:'#fff',
plotBorderWidth:1,
plotBorderColor:'#ccc'
credits:{enabled:false},
exporting:{enabled:false),
title:{text:'SatLevel
9)
%>,
Histogram
},
legend:{
//enabled:false
105
9)
RunCost.onSim(OcurrentSim).
9)
%>,
<%=
RunCost.onSim(CcurrentSim).countBetween
9)
%>,
<%=
9)
%>,
<%=
RunCost.onSim(
.countBetween(260000,280000,
RunCost.onSim(CcurrentSim).
9)
%>,
<%=
<%= RunCost.onSim(OcurrentSim).countBetween
RunCost.onSim(OcurrentSim).countBetween(380000,400000,
charset="utf
%>,<%= RunCost.onSim(
RunCost.onSim(OcurrentSim).countBetween(320000,340000,
</script>
type="text/javascript"
<%=
RunCost .onSim(OcurrentSim)
RunCost.onSim(currentSim).countBetween(280000,300000,
(360000,380000,
%>,
%>,<V=
countBetween (100000 ,120000,
RunCost.onSim(OcurrentSim).countBetween(220000,240000,
RunCost.onSim(QcurrentSim).countBetween(340000,360000,
$(function()
9)
9)
9)
.countBetween
RunCost.onSim(CcurrentSim).countBetween(160000,180000,
.countBetween(240000,260000,
countBetween(300000,320000,
<script
RunCost .onSim(CcurrentSim)
RunCost.onSim(OcurrentSim).countBetween(60000,80000,
countBetween (80000,100000,
RunCost.onSim(OcurrentSim).countBetween(180000,200000,
9)
%>,<%=
9)
%> I
tooltip :{
borderWidth:1,
formatter:function() {
return
'<b>Range:</b><br/>
'<b>Count:</b>
'+
this.x +'<br/>'+
'+
this.y;
}
plotOptions:{
column:{
shadow:false,
borderWidth:.5,
borderColor:'#666',
pointPadding:0,
groupPadding:0,
'rgba(204,204,204,.85)'
color:
spline:{
shadow:false,
marker:{
radius:1
}
},
areaspline:{
color:'rgb(69, 114,
167)',
fillColor:'rgba(69,
114,
167,.25)',
shadow:false,
marker:{
radius:1
}
},
xAxis:{
16 <
16','>=
'>=
18','>=
< 34',
32
0
['>=
categories:
'>=
<
2','>=
2=
18 < 20','>=
34 <
36',
'>=
4 <
4','>=
20 <
36
6','>= 6 < 8','>= 8 < 10','>=
22','>= 22 <
< 38',
'>=
38
24','>=
24
10
< 26','>= 26
<
<
12','>=
28','>= 28
12
<
14','>=
< 30','>=
30
14
<
<
32',
< 40'],
labels:{
rotation:-90,
y:20,
style:
{
fontSize:'8pxl,
fontWeight:'normal',
color:'#333'
},
lineWidth:0,
lineColor:'#999',
tickLength:70,
tickColor:'#ccc',
},
yAxis: {
title:
{
text:
"Frequency"
},
series:
<% Qsats.each do
]sat[ %>
{
%>,
<%=
name:"
sat,,<%=,sat
data:
[<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(0,2,sat.id,1)
,id,%>,_12,mo",
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(2,4,sat.id,1)
106
%>,
<%= TimeStep.stepsOnSim(
OcurrentSim).countAtSatLevel(4,6,sat.id,1)
id,1)
%>,
%>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(6,8,sat.
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(8,10,sat.id,1)
%>,<%= TimeStep.stepsOnSim(
OcurrentSim).countAtSatLevel(10,12,sat.id,1) %>, <%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(12,14,
sat.id,1) %>, <%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(14,16,sat.id,1)
%>, <7= TimeStep.
stepsOnSim(CcurrentSim).countAtSatLevel(16,18,sat.id,1)
countAtSatLevel(18,20,sat.id,1)
7>,
%>,
<%= TimeStep.stepsOnSim(CcurrentSim).
TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(20,22,sat.id,1)
<%=
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(22,24,sat.id,1)
QcurrentSimm).countAtSatLevel(24,26,sat.id,1)
%>,
%>,
%>,
<%= TimeStep.stepsOnSim(
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(26,28,
%>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(28,30,sat.id,1)
.>, <%= TimeStep.
stepsOnSiim(CcurrentSim).countAtSatLevel(30,32,sat.id,1) %>, <%= TimeStep.stepsOnSim(QcurrentSim).
sat.id,1)
countAtSatLevel(32,34,sat.id,1)
'/>, <%= TimeStep.stepsOnSim (currentSim).countAtSatLevel(34,36,sat.id,1)
<%= TimeStep.stepsOnSim(DcurrentSim).countAtSatLevel(36,38,sat.id,1)
QcurrentSim).countAtSatLevel(38,40,sat.id,1)
%>,
%>,
<%= TimeStep.stepsOnSim(
%>]
},
{
%>,
name
sat' <7=sat . idi/>U6umo"
data:
[<%=
TimeStep.stepsOnSim(
currentSim).countAtSatLevel(0,2,sat.id,2)
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(2,4,sat.id,2)
OcurrentSim).countAtSatLevel(4,6,sat.id,2)
%>,
id,2) %>, <%= TimeStep.stepslnSim(OcurrentSim).countAtSatLevel(8,10,sat.id,2)
%>,
QcurrentSim).countAtSatLevel(10,12,sat.id,2)
sat.id,2) %>, <%=
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(14,16,sat.id,2)
countAtSatLevel(18,20,sat.id,2)
%>,
TimeStep.
stepsOnSim (currentSim).countAtSatLevel(30,32,sat.id,2)
<%=
%>,
7,>,
<%= TimeStep.stepsOnSim(
%>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(26,28,
stepsOnSim (CcurrentSim) . countAtSatLevel
countAtSatLevel(32,34,sat.id,2)
<%= TimeStep.
%>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(20,22,sat.id,2)
QcurrentSim).countAtSatLevel(24,26,sat.id,2)
<%=
%>,
<%= TimeStep.stepsOnSim(OcurrentSim).
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(22,24,sat.id,2)
%>,
%>,<7= TimeStep.stepsOnSim(
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(12,14,
stepsOnSim(OcurrentSim).countAtSatLevel(16,18,sat.id,2)
sat. id ,2)
<%= TimeStep.stepsOnSim(
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(6,8,sat.
%>,
(28 ,30,sat . id ,2) %>, <%= TimeStep.
%>, <%= TimeStep.stepsOnSim(OcurrentSim).
%>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(34,36,sat.id,2)
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(36,38,sat.id,2)
QcurrentSim).countAtSatLevel(38,40,sat.id,2)
%>,
7>, <%= TimeStep.stepsOnSim(
7>]
{
id,7,>3,mo",
name:
sat
data:
[<Y.= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(0,2,sat.id,3)
<%=,sat .
7>, <%= TimeStep.stepsOnSim(currentSim).countAtSatLevel(2,4,sat.id,3)
QcurrentSim).countAtSatLevel(4,6,sat.id,3)
%>, <%= TimeStep.stepsOnSim(
%>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(6,8,sat.
id,3) %>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(8,10,sat.id,3) %>,<7= TimeStep.stepsOnSim(
OcurrentSim).countAtSatLevel(10,12,sat.id,3) %>,<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(12,14,
sat.id,3) %>, <%= TimeStep.stepsOnSim (currentSim).countAtSatLevel(14,16,sat.id,3)
%>, <%= TimeStep.
stepsOnSim(CcurrentSim).countAtSatLevel(16,18,sat.id,1)
countAtSatLevel(18,20,sat.id,3)
%>, <%= TimeStep.stepsOnSim(OcurrentSim).
%>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(20,22,sat.id,3)
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(22,24,sat.id,3)
OcurrentSim).countAtSatLevel(24,26,sat.id,3)
sat.id,3) %>, <%= TimeStep.stepsOnSim(
7,>,
<%= TimeStep.stepsOnSim(
%>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(26,28,
currentSimi).countAtSatLevel(28,30,sat.id,3)
7>, <%= TimeStep.
%>, <%= TimeStep.stepsOnSim( OcurrentSim).
stepsOnSim(OcurrentSim).countAtSatLevel(30,32,sat.id,3)
countAtSatLevel(32,34,sat.id,3)
%>,
TimeStep.stepsOnSirm(OcurrentSim).countAtSatLevel(34,36,sat.id,3)
%>, <%=
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(36,38,sat.id,3)
OcurrentSim).countAtSatLevel(38,40,sat.id,3)
7,>,
7>, <%= TimeStep.stepsOnSim(
%>]
{
name:'sat
<%= sat.id
type:'spline
7> 12
mo
Curve',
,
visible:false,
data:
[<%= TimeStep.stepsOnSim( QcurrentSim).countAtSatLevel(0,2,sat.id,1)
TimeStep.stepsOnSimC(currentSim).countAtSatLevel(2,4,sat.id,1)
%>, <%=
countAtSatLevel(4,6,sat.id,1)
TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(6,8,sat.id,1)
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(8,10,sat.id,1)
countAtSatLevel(10,12,sat.id,1)
<%= TimeStep.stepsOnSim(
%>,
%>,<%=
%>,
%>,
<%=
TimeStep.stepsOnSim( OcurrentSim).
'/>, <7= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(12,14,sat.id,1)
currentSim).countAtSatLevel(14,16,sat.id,1)
QcurrentSim).countAtSatLevel(16,18,sat.id,1)
<%=
%>, <%= TimeStep.stepsOnSim (currentSim).
7,>,
7>, <%= TimeStep.stepsOnSim(
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(18,20,
107
sat.id,1)
%>,
<%=
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(20,22,sat.id,1)
stepsOnSim(CcurrentSim).countAtSatLevel(22,24,sat.id,1)
%>,
countAtSatLevel(24,26,sat.id,1)
%>,
<%=
<%=
TimeStep.
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(26,28,sat.idl)
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(28,30,sat.id,1)
OcurrentSim).countAtSatLevel(30,32,sat.id,1)
sat.id,1) %>,
%>,
TimeStep.stepsOnSim(OcurrentSim).
%>,
%>,
<%= TimeStep.stepsOnSim(
%>,
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(32,34,
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(34,36,sat.id,1)
stepsanSim(OcurrentSim).countAtSatLevel(36,38,sat.id,1)
%>,
<%=
%>,
<%=
TimeStep.
TimeStep.stepsOnSim(OcurrentSim).
countAtSatLevel(38,40,sat.id,1) %>]
{
name:"satu<%/=usat.idu />uemoCurve",
type:
'spline',
visible:false,
[<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(0,2,sat.id,2)
data:
%>,
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(2,4,sat.id,2)
CcurrentSim).countAtSatLevel(4,6,sat.id,2)
id,2) %>,
%>,
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(8,10,sat.id,2)
%>,
CcurrentSim).countAtSatLevel(10,12,sat.id,2)
sat.id,2) %>,
<%=
<%= TimeStep.
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(20,22,sat.id,2)
%>,
<%=
%>,
<%= TimeStep.steps
stepsOnSim(OcurrentSim).countAtSatLevel(30,32,sat.id,2)
%>,
%>,
OnSim(
TimeStep.stepsOnSim (OcurrentSim).countAtSatLevel (26 ,28,
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(28,30,sat.id,2)
countAtSatLevel(32,34,sat.id,2)
%>,
<%= TimeStep.stepsOnSim(OcurrentSim).
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(22,24,sat.id,2)
OcurrentSim).countAtSatLevel(24,26,sat.id,2) %>,
<%=
%>,<%= TimeStep.stepsOnSim(
<%= TimeStep.stepsOnSim(C currentSim).countAtSatLevel(14,16,sat.id,2)
countAtSatLevel(18,20,sat.id,2)
sat.id,2) %>,
TimeStep.stepsOnSim(
TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(12,14,
stepsanSim(CcurrentSim).countAtSatLevel(16,18,sat.id ,2) %>,
<%=
<%=
%>,
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(6,8,sat.
%>,
%>,
<%=
TimeStep.
<%= TimeStep.stepsOnSim(CcurrentSim).
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(34,36,sat.id,2)
TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(36,38,sat.id,2)
V>,
<%= TimeStep.stepsOnSim(
%>,
OcurrentSim).countAtSatLevel(38,40,sat.id,2) %>]
{
name :"satu
type:
visible:
data:
%>,
<%=Lsat .id,,%>,3,moCurve"
'spline',
false,
[<%=
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(0,2,sat.id,3)
<%= TimeStep.stepsOnSims(OcurrentSim).countAtSatLevel(2,4,sat.id,3)
OcurrentSim).countAtSatLevel(4,6,sat.id
%>,
<%= TimeStep.stepsOnSim(
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(6,8,sat.
,3) %>,
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(8,10,sat.id,3)
%>,<V.= TimeStep.stepsOnSim(
OcurrentSim).countAtSatLevel(10,12,sat.id,3) %>, <%= TimeStep.stepsOnSims(OcurrentSim).countAtSatLevel(12,14,
sat.id,3) %>, <%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(14,16,sat.id ,3)
%>, <%= TimeStep.
id,3) %>,
stepsOnSim(OcurrentSim).countAtSatLevel(16,18,sat.id,1)
countAtSatLevel(18,20,sat.id,3)
<%=
%>,
%>,
<V=
TimeStep.stepsOnSim(OcurrentSim).
<%= TimeStep.stepsOnSim(6currentSim).countAtSatLevel(20,22,sat.id,3)
TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(22,24,sat.id,3)
OcurrentSim).countAtSatLevel(24,26,sat.id,3)
sat.id,3)
%>,
%>,
<%=
countAtSatLevel(32,34,sat.id,3)
%>,
<Y.= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(26,28,
%>,
<%= TimeStep.
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(34,36,sat.id,3)
OcurrentSim).countAtSatLevel(38,40,sat.id ,3) V>]
},
end %>
</script>
id="cost-histogram"
%>,
<%= TimeStep.stepsOnSim(CcurrentSim).
<%= TimeStep.stepsOnSim(CcurrentSim).countAtSatLevel(36,38,sat.id,3)
<%
V.>,
TimeStep.stepsOnSim(
<%= TimeStep.stepsOnSim(OcurrentSim).countAtSatLevel(28,30,sat.id,3)
stepsOnSim(CcurrentSim).countAtSatLevel(30,32,sat.id,3)
<div
%>,
style="height:o500px"></div>
108
%>,
<V=
TimeStep.stepsOnSim(
%>,
<div
style="height: 500px"></div>
id="satLevel-histogram"
<% end %>
<h2>TimingRuns</h2>
<table>
<tr>
<td>number
regions</td>
<td>number
nodes</td>
<td>number
steps</td>
<% for row in OtimingRuns %>
<tr>
<td><%= row.numReg %></td>
row.numNodes
%></td>
<td><%= row.numSteps
%></td>
<td><%=
</tr>
<%
end %>
<h2>Utilization</h2>
<table>
<tr>
<td>12
<td>6
<td>3
mo Average Utilization</td>
mo Average Utilization</td>
mo Average Utilization</td>
<td>Fixedl
+
3mo
Avg
Util</td>
<td>Fixed2
+
3mo
Avg
Util</td>
<td>Fixed3
+
3mo Avg
Util</td>
</tr>
<tr>
<td><%m CdemandLevels.where ("contractDurationID=,?",3).sum(:quantity)
17",
/
OdemandLevels.where("contractDurationlD,
3).sum(:actual-bw) %></td>
<td><%=
CdemandLevels.where("contractDurationID,=
2).sum(:actual-bw) %></td>
,?",2).sum(:quantity) /
CdemandLevels.where("
contractDurationDu,=-?",
<td><%=
OdemandLevels.where("contractDurationID=
1).sum(:actual-bw)
contractDurationlD,=,?",
<td><%.=
OdemandLevels.where("contractDurationIDu=
contractDurationID,=,?",
<td><%=
4).sum(:actual-bw)
<td><%=
5).sum(:actual_bw)
/
OdemandLevels.where("
?",4).sum(:quantity)
/
OdemandLevels.where("
a?",5).sum(:quantity)
/
OdemandLevels.where("
,?",6).sum(:quantity) /
OdemandLevels.where("
%></td>
OdemandLevels.where("contractDurationID,=
contractDurationID,=,?",
,?",1).sum(:quantity)
%></td>
%></td>
OdemandLevels.where("contractDurationlD-=
contractDurationIDl=?", 6).sum(:actual-bw) %></td>
</tr>
</table>
<h2>
Relative
Utilization
Comparisons
</h2>
<table>
<tr>
<td> </td>
<td>12 mo
Average
Utilization</td>
<td>6
mo
Average
Utilization</td>
<td>3
mo
Average
Utilization</td>
<td>Fixedl
+
<td>Fixed2
+ 3mo
Avg Util</td>
<td>Fixed3
+ 3mo
Avg Util</td>
3mo Avg Util</td>
109
<tr>
<td>12
mo
<td><%=
Average U</td>
(OdemandLevels.where("contractDurationID,=u?",3).sum(:quantity)
,=,?",
3).sum(:actual-bw))
/
.where ("contractDurationIDu=,?",
<td><%=
3).sum(:actual-bw)
(OdemandLevels.where
,=,?",
/
(OdemandLevels.where
,=,?",
/
(OdemandLevels.where
,=u?",
/
<td><%=
3) .sum(:actual
bw))
/
/
/
3) .sum(:actualbw))
,1).sum(:quantity)
/
OdemandLevels
OdemandLevels.where("contractDurationID
/
,4).sum(:quantity)
/
OdemandLeveIs
OdemandLevels.where("contractDurationID
,5).sum(:quantity)
/
OdemandLevels
5).sum(:actualbw))%></td>
/
OdemandLevels.where("contractDurationID
(OdemandLevels.where("contractDurationIDu=,?"
.where("contractDurationIDu=u?",
ademandLevels
4).sum(:actualbw))%></td>
(OdemandLevels.where("contractDurationID,=,?",3).sum(:quantity)
u=,?",
/
OdemandLevelsw.here("contractDurationID
(OdemandLevels.where("contractDurationIDu=u?"
.where("contractDurationID,=2?",
,2).sum(:quantity)
1).sum(:actualbw))%></td>
(OdemandLevels.where("contractDurationIDU=,?",3).sum(:quantity)
u=,?",
<td><%=
/
(OdemandLevels.where("contractDurationIDu=,?"
.where("contractDurationIDu=,?",
OdemandLevels
2).sum(:actualbw))X></td>
("contractDurationIDu=u?",3).sum(:quantity)
3) .sum(:actualbw))
/
OdemandLevels.where("contractDurationID
(OdemandLevels.where("contractDurationID=L?"
.where("contractDurationIDu=u?",
<td><7.=
/
("contractDurationIDU=u?",3).sum(:quantity)
3) .sum(:actualbw))
,3).sum(:quantity)
(CdemandLevels.where("contractDurationIDu=,?"
.where("contractDurationIDu=,?",
<td><7.=
OdemandLevels.where("contractDurationID
)%></td>
("contractDurationID,=,?",3).sum(:quantity)
3).sum(:actual _bw))
/
(OdemandLeveIs.where ("contractDurationID,=,?"
,6).sum(:quantity)
/
OdemandLeveIs
6).sum(:actual-bw))%></td>
</tr>
<tr>
<td>6 mo Average
U</td>
<td></td>
<td><%=
(CdemandLevels.where("contractDurationID,=,?",2).sum(:quantity)
=u?" ,
2) .sum(:actualbw))
/
.where("contractDurationID,=u?",
<td><%=
/
2).sum(:actualbw))
(OdemandLevels.where
u=,?",
/
<td><%=
2).sum(:actual
_bw))
/
/
OdemandLevels
OdemandLevels.where("contractDurationID
,1).sum(:quantity)
/
OdemandLevels
,2).sum(:quantity)
/
OdemandLevels.where("contractDurationID
,4).sum(:quantity)
/
OdemandLevels
4).sum(:actualbw) )%></td>
(OdemandLevels.where("cantractDurationIDu=u?"
,=,?",
/
(OdemandLevels.where("contractDuration1Du=?"
.where("contractDurationIDu=u?",
,2).sum(:quantity)
1).sum(:actualbw) )%></td>
("contractDurationID,=,?"
2) .sum(:actualbw))
,2).sum(:quantity)
(OdemandLevels.where("contractDurationID=u?"
.where("contractDurationIDu=,?",
<td><%=
OdemandLevels.where("contractDurationID
2).sum(:actualbw) )%></td>
(OdemandLevels.where("contractDurationIDu=u?"
u=j?",
/
(OdemandLevels.where("contractDurationID=,?"
,2).sum(:quantity)
/
MdemandLevels.where("contractDurationID
(OdemandLevelI.where("contractDurationIDJ=U?"
,5).sum(:quantity)
/
OdemandLevels
.where("contractDurationIDu=u?", 5).sum(:actual-bw) )%></td>
<td><%=
(OdemandLevels.where("contractDurationID=,?"
,=,?",
2) .sum(:actual
bw))
/
,2).sum(:quantity)
/
OdemandLevels.where("contractDurationID
(OdemandLevels.where("contractDurationIDu?"
,6).sum(:quantity)
/
OdemandLevels
.where("contractDurationIDu=u?", 6).sum(:actual-bw) )%></td>
</tr>
<tr>
<td>3 mo
Average
U</td>
<td></td>
<td></td>
<td><%=
(OdemandLevels.where("contractDurationID=u?"
/
1).sum(:actual-bw))
u=u?",
.where("contractDurationIDu=u?",
<td><%=
1).sum(:actualbw))
/
1).sum(:actualbw))
/
(OdemandLevels.where
,=u?",
/
5).sum(:actual-bw)
Average
/
/
6).sum(:actual-bw) )%></td>
<tr>
mo
OdemandLevels
,4).sum(:quantity)
/
OdemandLeveIs
OdemandLevels.where("contractDurationID
,5).sum(:quantity)
/
OdemandLevels
)%></td>
</tr>
<td>Fixedl
/
CdemandLevels.where("contractDurationID
OdemandLevels.where("contractDurationID
(OdemandLevels.where("contractDurationIDu=u?"
.where("contractDurationIDu=,?",
,1).sum(:quantity)
4).sum(:actual-bw) )%></td>
("contractDurationID,=u?",1).sum(:quantity)
1) .sum(:actual.bw))
/
(OdemandLeveIs.where("contractDurationIDu=,?"
.where("contractDurationIDu=u?",
<td><%=
,1).sum(:quantity)
(OdemandLevels.where("contractDurationIDu=,?",1).sum(:quantity)
,=u?",
CdemandLevels.where("contractDurationID
(OdemandLevels.where("contractDurationIDu=u?"
.where("contractDurationID,=,?",
<td><%=
/
1).sum(:actual_bw) )%></td>
(OdemandLevels.where("contractDurationID,=,?"
,=,?",
,1).sum(:quantity)
(OdemandLevels.where("contractDurationIDu=?"
U</td>
<td></td>
<td></td>
110
,6).sum(:quantity)
/
OdemandLevels
<td></td>
<td><%=
(OdemandLevels.where("contractDurationID,=?"
,=,?",
4).sum(:actual
/
bw))
.where("contractDurationlD,,,?",
<td><%=
4).sum(:actual-bw)
(OdemandLevels.where("contractDurationID,=,,?"
4).sum(:actual -bw))
/
.where("contractDurationID,=
<td><%=
,4).sum(:quantity)
/
,4).sum(:quantity)
/
5).sum(:actual-bw)
/
,,=,?",5).sum(:quantity)
/
6) .sum(:actual-bw)
/
OdemandLevels
)%></td>
OdemandLevels.where("contractDurationlD
(OdemandLevels.where("contractDurationID=?"
.where("contractDurationIDu=j?",
CdemandLevels
OdemandLevels.where("contractDurationID
(OdemandLevels.where("contractDurationID
?",
4). sum(:actual-bw))
/
)%></td>
(OdemandLevels.where("contractDurationID,=,?",4).sum(:quantity)
,=,?",
DdemandLevels.where("contractDurationlD
(OdemandLevels.where("contractDurationID=,,?",4).sum(:quantity)
,6).sum(:quantity)
/
OdemandLevels
)/></td>
</tr>
<tr>
<td>Fixed2 mo
Average
U</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><%=
(OdemandLevels.where
"
("contractDurationID
5).sum(:actual-bw))
',?",
/
.where("contractDurationlD=U?",
<td><%=
=?",5).sum(:quantity)
/
5).sum(:actual-bw)
5).sum(:actualbw))
/
/
6).sum(:actual-bw)
OdemandLevels
CdemandLevels.where("contractDurationID
('OdemandLevels.where("contractDurationID=,?
.where("contractDurationlD,-=?",
/
)%></td>
(OdemandLevels.where("contractDurationID,,=,?" ,5).sum(:quantity)
=L? ",
OdemandLevels.where("contractDurationID
(OdemandLevels.where("contractDurationIDj=x?",5).sum(:quantity)
" ,6).sum(:quantity)
/
OdemandLevels
)%></td>
</tr>
<tr>
<td>Fixed3 mo
Average
U</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><%=
(OdemandLevels.where
_=U?",
("contractDuration1D
/
6).sum(:actualbw))
=,?",6).sum(:quantity)
/
OdemandLevels.where(" contractDurationID
(OdemandLevels.where("contractDurationID,=,?"6).sum(:quantity)
.where("contractDurationID,=?",
6).sum(:actual-bw)
/
OdemandLevels
)%></td>
</tr>
</table>
<h2>BW
above
Fixed,
Total
BW
and % of
Total</h2>
<table>
<tr>
<td>Fixedl</td>
<td>Fixed2</td>
<td>Fixed3</td>
</tr>
<tr>
<td><%=
OdemandLevels .where("contractDurationID
OdemandLevels.where("contractDurationID,=,?,ANDquantity
<td><%=
=>7
,4)
.sum(:
quantity)
OdemandLevels.where ("contractDurationID,=_?,ANDquantity,>,8",5).sum(:quantity)
CdemandLevels.where("contractDurationID,=,?,ANDuquantity>.8"
<td><%=
AND quantity,>5"
,5).count*8)
OdemandLevels.where("contractDurationID,=J?
AND quantity
sum(:quantity)
,>1I "6)
%></td>
</tr>
<tr>
<td><%=
OdemandLevels.where ("contractDurationID,=,?",4).sum(:quantity)
<td><%=
OdemandLevels.where ("contractDurationID-=
<td><%=
OdemandLevels.where("contractDurationID
<tr>
111
(
-
(
%></td>
OdemandLevels.where("contractDuration1D,=,?,ANDquantity,>,11,6).count*11)
</tr>
-
>,5",4).count*5) %></td>
?,5)
%></td>
.sum(:quantity)
,,7?",6).sum(:quantity)
%></td>
%></td>
-
<td><%=
(CdemandLevels.where
("contractDurationIDu=u?uANDuquantityu>u5"
OdemandLevels.where("contractDurationIDu=,?,ANDquantityu>5'",4).count*5))
contractDurationID,=,?",4).sum(:quantity))
OdemandLevels.where
("contractDurationIDu=,?,ANDuquantityu>u8"
("contractDurationID,=u?uANDuquantityu>u8",5).count*8))
contractDurationIDu=u?u",5).sum(:quantity))
<td><X=
,4).sum(:quantity)
-
(
-
(
(OdemandLevels.where("
%></td>
where
(OdemandLevels
<td><X=
/
/
,5).sum(:quantity)
(CdemandLevels.where("
></td>
(OdemandLevels.where("contractDurationID,=u?uANDuquantityu>,11",6).sum(:quantity)
OdemandLevels where
("contract
DurationIDu=u?uANDuquantityu>uI1",6).count*11)
contractDurationIDu=u?",6).sum(:quantity))
-
(
(CdemandLevels.where("
%></td>
</tr>
</table>
<h2>Unit
Price</h2>
<table>
<tr>
<td>12 mo</td>
<td>6
mo</td>
<td>3
mo</td>
<td>Fixedl</td>
<td>Fixed2</td>
<td>Fixed3</td>
</tr>
<tr>
-
<td><%=243.2
14.7*12
<td><%=243.2
-
14.7*6
%></td>
<td><%=243.2
-
14.7*3
%></td>
<td><%=
quantity)
(243.2
-
%></td>
14.7*12)*(1-((CdemandLevels.where("contractDurationID,=,?uANDuquantityu>u5",4).sum(:
(OdemandLevels.where("contractDurationIDu=?u
-
,4) .sum(:quantity))))
where("contractDurationIDu=u?"
contractDurationID=u?uANDquantityu>u5"
ANDquantityu>u5" ,4).count*5))
<td><%=
quantity)
(243.2
-
,5).sum(:quantity))))
quantity)
+
/
+
/
</tr>
</table>
Comparisons</h2>
<table>
<tr>
<td>
</td>
Average
Unit
Price</td>
<td>6 mo
Average
Unit
<td>3 mo
Price</td>
Average
Utilization</td>
<td>Fixedl
+
Unit
Price</td>
<td>Fixed2
+ 3mo
Avg Unit
Price</td>
<td>Fixed3
+ 3mo
Avg
Price</td>
3mo Avg
Unit
</tr>
<tr>
mo
14.7*3)*((OdemandLevels.where("
Average
-
-
5) .sum(:quantity)))
%></td>
,6).count*11)) /
UP</td>
<td><%=
(243.2
-
14.7*12)
/
(243.2 -
14.7*12)
<td><%=
(243.2
-
14.7*12)
/
(243.2 -
14.7*6)X></td>
<td><%=
(243.2
-
14.7*12)
/
(243.2 -
14.7*3)%></td>
%></td>
112
(OdemandLevels .
14.7*3)*((OdemandLevels.where("
(OdemandLevels.where("contractDurationID,=,?u
(OdemandLevels.where("contractDurationID,=u?"
td>
mo
(243.2
quantity)
contractDurationIDue?,ANDuquantityu>11",6).Sum(:
<td>12
-
(OdemandLevels.where("contractDurationIDu=?u",
,6).sum(:quantity))))
ANDuquantityu>A1",6).count*11))
<h2>Relative Price
=u?,
%></td>
(OdemandLevels.where("contractDurationIDu=u?
-
(OdemandLeveIs.where ("contractDurationIDu=,?uANDuguantityu>11"
-
4). sum(:quantity)))
14.7*12)*(1-((OdemandLevels.where("contractDurationID,=uuANDuquantityu>A11",6).sum(:
where("contractDurationIDu=?u"
<td>12
(243.2
,5).sum(:quantity)
ANDquantity,>,8",5).count*8))
-
(OdemandLevels.where("contractDurationID
-
(OdemandLevels.where("contractDurationID,=u?"
contractDurationID,=,?,ANDquantity>,8"
(243.2
(OdemandLeveIs.
(demandLevels
where("contractDurationIDu=u~uANDuquantity,>,8",5).sum(:
where(",ontractDurationID,=uuANDuquantity,>,8",5).count*8)) / ((demandLevels.
where("contractDurationID=u?u"
<td><%=
,4).sum(:quantity)
/
14.7*3)*((OdemandLevels.where("
-
14.7*12) *(-(
(OdemandLevels
-
/
ANDuquantityu>.5",4).count*5))
(243.2
+
,6).sum(:quantity)))
%></
<td><%=
(243.2
-
14.7*12)
,4).sum(:quantity)
/
((243.2
14.7*12)*(1-((OdemandLevels.where("contractDurationID
-
/
OdemandLevels.where ("contractDurationID,=-7",4).sum(:quantity))))
contractDurationIDu-
?,,ANDquantity,>,5",4).sum(:quantity)
ANDuquantity,>,5",4).count*5))
<td><%=
(243.2
-
14.7*12)
,5).sum(:quantity)
/
((243.2
(OdemandLevels.where("contractDurationID,=,?,
-
(OdemandLevels.where("contractDurationID=,?",4).sum(:quantity))))%></td>
-
14.7*12)*(1-((QdemandLevels.where ("contractDurationID,=,?,ANDuquantity
/
(OdemandLevels.where("contractDurationID,=,?.ANDquantity,>,8",5).count*8))
-
ANDquantity>,8",5).count*8))
-
14.7*12)
/
((243.2
(
14.7*3)*((CdemandLevels.where("
-
/
+
"contractDurationID,=-?,ANDuquantity,>,8",5).sum(:quantity)
(243.2
(243.2
+
OdemandLevels.where ("contractDurationID=UU",5).sum(:quantity))))
<td><%=
.=u?,ANDOquantityJ>,5"
(OdemandLevels.where("contractDurationID,=?,ANDuquantityu>5,4).count*5))
-
(243.2
-
14.7*3)*((CdemandLevels.where(
demandLevels.where("contractDurationIDu=u?
(
-
>e8"
(
/
(OdemandLevels.where("contractDurationID=a?",5).sum(:quantity))))></td>
-
14.7*12)*(1-((QdemandLevels.where ("contractDurationID,=u?,ANDuquantity,>,11
",6).sum(:quantity)
(demandLevels
where("contractDurat ionID/=(?uANDquantity,>,11",6).count*11))
/
(
+
(243.2 - 14.7*3)*((QdemandLevels.where(
OdemandLevels.where('contractDurationID,=,?, 6) .sum(:quantity))))
1",6).sum(:
"contractDurationID,=,?,ANDquantity,>,
ANDuquantity,>211",6).count*11))
/
quantity)
-
(OdemandLevels.where("contractDurationID,=u?,
(OdemandLevels.where("contractDurationIDj=?e",6).sum(:quantity))))%></td
</tr>
<tr>
<td>6
mo
Average
UP</td>
<td><%=
%></td>
<td><%=
(243.2
-
14.7*6)
/
(243.2
-
<td><%=
(243.2
-
14.7*6)
/
(243.2
-
<td><%=
(243.2
-
14.7*6)
/
((243.2
,4).sum(:quantity)
OdemandLevels
14.7*6)%></td>
14.7*3)%></td>
14.7*12)*(1-((QdemandLevels.where ("contractDuration1D,=,?,ANDjquantity,>,5"
-
(OdemandLevels.where("contractDurationID=?,_AND.quantityJ>u5",4).count*5))
-
where("contractDurationIDI=L?",4).sum(:quantity)
contractDurationID,=,?UANDuquantity,>,5",4)sum(:quantity)
ANDuquantity>b5" ,4).count*5))
<td><%=
(243.2
-
14.7*6)
/
((243.2
(OdemandLevels.where("contractDurationID-,
-
OdemandLevels.where
("contractDurationID=,?-,5).sum(:quantity))))
ANDuquantityj>u8",5).count*8))
<td><%=
(243.2
-
14.7*6)
,6).sum(:quantity)
+
/
/
((243.2
(243.2
-
14.7*3)*((QdemandLevels.where(
(OdemandLevels.where("contractDurationIDu=u?u",5)sum(:quantity)))
)></td>
?,ANDuquantity,>,11"
/
(OdemandLevels.where("contractDurationID,=-?.ANDwquantity,>,11",6).count*11))
-
+
"contractDuration1DI=L?,ANDquantity>u11",6).sum(:quantity)
11",6).count*l1))
/
-
(OdemandLevels.where
8"
(
(OdemandLevels.where("contractDurationID=,?,
-
14.7*12)*(1-((OdemandLevels.where("contractDurationIDO=
-
7
AND.,quantity,>
/
OdemandLevels.where ("contractDurationID,=u?.",6) .sum(:quantity))))
ANDquantity,>,
7
(OdemandLevels.where("contractDurationID=?,ANDquantity§>'8",5).count*8))
"contractDurationID,=,?,ANDuquantityu>u8",5).sum(:quantity)
(
?",4).sum(:quantity))))%></td>
14.7*12)*(1-((OdemandLevels.where("contractDurationID,=r,
-
,5).sum(:quantity)
/
14.7*3)*((demandLevels.where("
-
(OdemandLevels.where("contractDurationID,=?
-
/
(243.2
+
(243.2
-
(
14.7*3)*((QdemandLevels.where(
(OdemandLevels.where("contractDurationIDu=u?,
("contractDurationID,=-?u",6).sum(:quantity))))%></td
</tr>
<tr>
<td>3
mo
Average
UP</td>
<td><%=
%></td>
<td><%=
%></td>
<td><%=
(243.2
-
14.7*3)
/
(243.2
<td><%=
(243.2
-
14.7*3)
/
((243.2
,4).sum(:quantity)
-
14.7*3)X></td>
14.7*12)*(1-((demandLevels.where("contractDurationID=u?,ANDuquantity>,5"
-
(OdemandLevels.where("contractDurationID,=u?,ANDuquantity,>,5",4).count*5))
-
OdemandLevels.where("contractDurationIDu=?",
4). sum(:quantity))))
contractDurationIDule?,ANDquantityu>,5",4).sum(:quantity)
ANDuquantityU>a5",4).count*5))
<td><X=
(243.2
-
14.7*3)
,5).sum(:quantity)
/
((243.2
OdemandLevels.where("contractDurationID=,?",5).sum(:quantity))))
"contractDurationIDu=,?,ANDuquantity,>,8",5).sum(:quantity)
ANDuquantityu>u8",5).count*6))
<td><%=
(243.2
-
,6).sum(:quantity)
14.7*3)
/
-
((243.2
/
.ANDuquantity,>,8"
-
+
(243.2
-
(OdemandLevels.where
-
(
("contractDurationID,=u?u
14.7*12)*(1-((OdemandLevelswhere("contractDurationID,=,?,ANDLquantity,>A11"
(OdemandLevels.where("contractDurationIDu=,?,ANDuquantityu>,11",6).count*11))
sum(:quantity))))
=,?,AND.quantity
ANDquantjty>uJ11",6).count*11))
/
14.7*3)*((@demandLevels.where(
(CdemandLevels.where("contractDurationID=?",5).sum(:quantity))))%></td>
OdemandLevels.where("contractDurationID,-=?j,6).
"contractDurationID
7
(OdemandLevels.where("contractDurationIDU=uUANDquantityu>u8",5).count*8))
-
(
(OdemandLevels.where("contractDurationID,=?",4).sum(:quantity))))%></td>
14.7*12)*(1-((OdemandLevels.where("contractDurationID=,
-
/
14.7*3)*((CdemandLevels.where("
-
(CdemandLevels.where("contractDurationID=.,?,
-
/
(243.2
+
/
>, 11",6).sum(:quantity)
+
-
(243.2
-
/
(
14.7*3)*((QdemandLevels.where(
(4demandLevels.where("contractDurationID,,=?,
(OdemandLevels.where("contractDurationIDu=?,,6).sum(:quantity))))%></td
113
<tr>
<td>Fixedl
mo
Average
<td><%=
/></td>
<td><%=
%></td>
<td><%=
(></td>
<td><X=
((243.2
UP</td>
14.7*12)
-
where
*(1 -( (OdemandLevelIs
(OdemandLevels.where("contractDurationIDu=u?
/
(243.2
+
u>uS",4).sum(:
Dur at ionIDu=u?u AND, quantity
/
ANDuquantityL'>S5",4).count*5))
contractDurationID,=,?",4).sum(:quantity))))
?uANDuquantityu>u5",4).sum(:quantity)
count*5))
("contract
14.7*3)*((QdemandLevels.where("contractDurationID,=,
-
/
,4).sum(:quantity))))
(OdemandLevels.where("contractDurationID=u,?"
(243.2
+
quantity)
-
((243.2
(OdemandLevels.where("contractDurationID
-
((243.2
=j? ANDquantity,>,5" ,4).count*5))
contractDurationIDu=?"
ationIDu=uuANDquantityu>u5",4).count*5))
,4).sum(:quantity))))
?uANDuquantityu>u5",4).sum(:quantity)
(243.2
+
contractDurat
ion
D,=,?,ANDquantityu>uV",5).count*8))
sum(:quantity))))
-
+
(243.2
-
/
/
5).sum(:quantity)
contractDurationIDu=,?",4).sum(:quantity))))
+
-
(243.2
(243.2
+
-
(OdemandLevels.
4).sum(:quantity)
/
-
(OdemandLevels.where("
14.7*3)*((CdemandLevels.where("contractDurationIDu=,
-
/
,4).sum(:quantity))))
/
contractDurationIDu=,?,ANDuquantity,>u11",6).count*11))
.where("
/
?uANDquantityu>u8",5).count*8))
OdemandLevels.where("contractDurationID,=u?uANDuquantity,>,11"
sum(:quantity))))
,5)
)%></td>
(OdemandLevels.where("contractDurationID,=-?"
(:quantity)
(OdemandLevels.where("
-
(OdemandLevels.where("contractDurationID,=
-
,4).
14.7*12)*(1-((
-
(OdemandLevels.where("contractDurationID=uu"
(OdemandLevels.where("contractDurationlDu=
?,ANDquantity>,5" ,4).sum(:quantity)
/
((243.2
14.7*12) *(1-((demandLevels4where("contractDurationI.D=umANDquantityu>,5"
-
-
(OdemandLevels.where("
("contractDurationIDu=,?uANDuquantityu>u5"
(OdemandLevels.where("contractDurationID,=,?,ANDquantity,>,5",4).count*5))
count*5))
(cdemandLevels.
where("contractDurationID,=,?,ANDquantityu>u8",5).sum
14.7*3)*( (demandLevels
where("contractDurationIDu=u?u" ,5).sum(:quantity)))
((243.2
/
,4).sum(:quantity))))
OdemandLeveIs.where("contractDurationIDU=?uANDuquantityu>8",
<td><%=
/
14.7*3)*((OdemandLevels.where ("contractDurationIDu=,
-
(OdemandLevels.where
-
(OdemandLevels.where ("contractDurationIDu?"
(:quantity)
4). sum
4).sum(:quantity))))%></td>
where("contractDur
/
(OdemandLevels.where("
-
(edemandLevels.where("contractDurationID,=u?"
14.7*12)*(1-((OdemandLevels.where("contractDurationIDu=u?uANDquantityU>15",4).sum(:quantity)
-
(/demandLevels
count*5))
,4).
14.7*12)*(1-((
-
14.7*3)*((OdemandLevels.where("contractDurationID,=,?,ANDquantity,>,5",4).sum(:
where("contractDurationIDu=u?"
<td><%=
/
DurationID=u?ANDuquantityu>u5",4).count*5))
(:quantity))))
-
(OdemandLevels.where("contractDurationID,=u?uANDuquantityu>u5"
-
OdemandLevels.where("contractDurationIDu=eu7ANDuquantityu>,5",4).sum(:quantity)
contract
quantity)
(CdemandLevels.where("
?,ANDquantityu>,5"
((243.2
,6).sum(:quantity)
-
,4).
14.7*12)*(1-((
-
(OdemandLevels.where("
(OdemandLevels.where('contractDurationIDu=u?u"
6).
14.7*3)*((OdemandLevels.where("contractDurationIDu=,?,ANDuquantityu>u
I11",6).sum
/
(CdemandLevels.where("contractDurationIDu=u?,ANDuquantityu>,11",6).count*ll))
contract Duration lDw=u?u",t6).sum(:
quant it
(OdemandLevels
y)) ) )></td>
</tr>
<tr>
<td>Fixed2
mo
Average
<td><%=
X></td>
<td><%=
%></td>
<td><%=
%></td>
<td><%=
%></td>
<td><%=
((243.2
UP</td>
where("contractDurationID,=,?,ANDuquantity,>u8",5).sum(:quantity)
14.7*12)-*(1-((demandLevels
-
(/demandLevels
where("contract
DurationIDu=u?uANDquantity(>C8",5).count*8))
contractDurationID,=u?,",5).sum(:quantity))))
+
(243.2
/
14.7*3)*((OdemandLevels.where("contractDurationIDDu=
-
u?,ANDquantity,>,8",5).sum(:quantity) - (OdemandLevels.where("contractDurationID,=,?,ANDquantityI>8",5).
count*8)) / (OdemandLevels.where("contractDurationIDI=,? " ,5).sum(:quantity))))
where("contractDurationID,=,?
OdemandLevels
ANDuquantity,>,8",5).sum(:quantity)
/
contractDurationID,=u?uANDLquantityu>u8",5).count*8))
sum(:quantity))))
(:quantity)
where
<td><%=
-
("contract
((243.2
+
(243.2
-
14.7*3) *((demandLevels
contractDurationIDu=u?,",5).sum(:quantity))))
+
,luANDquantity,>,8",5).sum(:quantity)
-
(243.2
contractDurationIDu=u?uANDuquantity,>,11",6).count*11))
+
-
(243.2
(OdemandLevels
-
14.7*12)*(1-((
,5)
,5).count*8))
/
(OdemandLevels.
,5).count*8))
/
,5).sum(:quantity)
-
(OdemandLevels.where("
14.7*3)*((OdemandLevels.where("contractDurationID,=
-
(OdemandLevels.where("contractDurationIDL=u?uANDuquantityU>L8",5).
(OdemandLevels.where ("contractDurationlDu=u?u"
sum(:quantity))))
-
I DL?uANDuquantityL>U8",5).sum
/
,5).sum(:quantity))))
where("contractDurationIDu~u?uANDuquantityu>ull",6).sum(:quantity)
,demandLevels
(:quantity)
(odemandLevels.where("
14.7*12)*(1-((OdemandLevels.where("contractDurationIDu=u?uANDuquantityu>u8"
-
/
((243.2
-
)%></td>
(OdemandLevels.where("contractDurationIDu=,?ANDquantity,>,8'
count*8))
/
(OdemandLevels.where("contractDurationIDu=u?u"
where("contractDuration
(CdemandLevels.where("contractDurationIDu=u?uANDuquantityu>u8"
Dur at ion IDu=,?," ,5).sum(: quantity)))
-
(OdemandLevels.where("
/
((243.2
-
-
14.7*12)*(1-((
(OdemandLevels.where("
(OdemandLevels.where("contractDurationIDu=?,",6).
14.7*3)*((CdemandLevels.where("contractDurationIDu=,?uANDquantity,>,11",6).sum
where("contractDurat
ionID=uuANDuquantityu>u11"
114
,6).count*11)) /
(OdemandLevels
?,",6).sum(:quantity))))%></td>
.where("contractDurationID,=
</tr>
<tr>
<td>Fixed3 mo
Average
<td><%=
%></td>
<td><%=
%></td>
<td><.=
%></td>
<td><%=
%></td>
UP</td>
<td><%= %></td>
<td><X=
%></td>
1.0
</tr>
</table>
<h2>Relative
Price
Times
Relative
Utilization</h2>
<table>
<tr>
<td>
</td>
<td>12 mo</td>
<td>6
mo</td>
<td>3 mo</td>
<td>Fixedl</td>
<td>Fixed2</td>
<td>Fixed3</td>
</tr>
<td>12
<td><%=
mo
Average
UP</td>
(OdemandLevels.where("contractDurationIDJ=7?"
,=l?",
/
3).sum(:actual-bw))
/
,3).sum(:quantity)
OdemandLevels.where("contractDurationID
(OdemandLevels.where("contractDurationID_=
/
?",3).sum(:quantity)
OdemandLevels
%></td>
/ OdemandLevels.where("contractDurationlID
<td><= (OdemandLevels.where("contractDurationlD,=,?",3).sum(:quantity)
/ OdemandLevels
/ (OdemandLevels.where("contractDurationID=,?" ,2).sum(:quantity)
3). sum(:actual-bw))
,=,?",
)/((243.2
.where ("contractDurationlD,=,?",
3).sum(:actualbw)
.where ("contractDurationID,=,,?',
2).sum(:actual-bw))/((243.2
<td><%=
(OdemandLevels.where("contractDurationID=u?"
=?,
/
3).sum(:actualbw))
-
14.7*12)
/
,3).sum(:quantity)
-
1).sum(:actual-bw))/((243.2
/
3).sum(:actual-bw))
/
(243.2
(243.2
(:quantity))))
/
4).sum(:actual-bw))/((243.2
-
quantity)
-
-
/
3).sum(:actual-bw))
OdemandLevels.where ("contractDurationID
14.7*12)
/
contractDurat
where("
<td><Y.=
+
-
(
/
?",3).sum(:quantity)
-
-
/
QdemandLevels.where
+
-
/
((243.2
=?",
-
(OdemandLevels.where("
ID
ID.
(OdemandLevels.where("contractDuration
.sum(:
quantity))))
?,5).
>,8",5).count*8))
/
(OdemandLevels.
)%></td>
/
OdemandLevels.where("contractDuratioIlD
6). sum(:actual-bw))/((243.2
-
,ANDuquantity,>
/
14.7*12)
/
/
((243.2
11",6).sum(:quantity)
-
(ademandLevels.where("
(OdemandLevels.where("contractDurationID,=,?
14.7*3)*((OdemandLevels.where("
contractDurationID,,
%></td>
=,?",j6). sum(:quantity)))))
</tr>
</table>
115
OdemandLevels
14.7*12)*(1-((
?,AND
quantity
(OdemandLevels.where("contractDurationID=,?aAND,,quantity,>.11",6).count*11))
.where(" contractDuration
OdemandLevels
14.7*12)*(1-((
(OdemandLevels.where("contractDurationID,=?",6).sum(:quantity)
("contractDurationID,='
(243.2
-
/
contractDurationlD,,u=?ANDuquantity,>u11",6).count*11))
sum(:quantity))))
(CdemandLevels.
14.7*3)*((QdemandLevels.where("contractDurationID,.=u7ANDuquantityu>.8",5).sum
?,5)
.where("contractDurationID
(:quantity)
4) .sum(:
/
/
demandLevels.where("contractDurationlD,=U?,ANDuquantity
contractDurationID,=
3).sum(:actual-bw))
=&?",4).sum
OdemandLevels.where("contractDuration ID
14.7*12)
(OdemandLevels.where("contractDurationIDu=,?",3).sum(:quantity)
,=,?",
(OdemandLevels.where("
("contractDurationID
("contractDurationID,=,?,ANDquantity,>,8",5).sum(:quantity)
(243.2
OdemandLevels
14.7*12)*(1-((
(OdemandLevels.where("contractDurationID,=,?",5).sum(:quantity)
ionIDu=,?uANDquantity,>,8",5).count*8))
sum(:quantity))))
(:quantity)
-
-
(OdemandLevels.where
5).sum(:actual-bw))/((243.2
where
/
4) .sum(:quantity)
((243.2
)%></td>
4). sum(: quantity))))
.where("contractDurationID,=,?",
OdemandLevels
OdemandLevels
%></td>
14.7*3))
(OdemandLevels.where("contractDurationID,=,?,ANDuquantityu>,5",4).count*5))
(OdemandLevels.where("contractDurationID,=
,=,?",
-
14.7*3)*((CdemandLevels.where ("contractDurationID,=,?ANDLquantityL>5"
where("contractDurationIDu=1 ?"
<td><%=
/
,ANDquantity,>5",4).count*5))
(243.2
+
14.7*6))%></td>
-
(243.2
OdemandLevels.where("contractDuration ID,=,?AND.quantityu>u5",4).sum(:quantity)
7
14.7*12))
/
/
(OdemandLevels.where("contractDurationID,=?",
.where ("contractDurationIDU-,?",
contractDurationID=,?
-
OdemandLevels.where("contractDurationID
14.7*12)
("contractDurationIDu=,?",3).sum(:quantity)
(OdemandLevels.where
/
(OdemandLevels.where("contractDurationID=?",1).sum(:quantity)
.where ("contractDurationID,=u?",
<td><%=
14.7*12)
-
",6).
,1P",6).sum
/
(OdemandLevels
<h2>Avg Price
/
Utilization</h2>
<table>
<tr>
<td>12 mo</td>
<td>6
mo</td>
<td>3
mo</td>
<td>Fixedl</td>
<td>Fixed2</td>
<td>Fixed3</td>
</tr>
<tr>
<td><%=
(243.2
OdemandLevels.where
<td><%=
14.7*12)/(OdemandLevels.where("contractDurationID,=,?"
-
("contractDurationID,=,?",
(243.2
3).sum(:actual
<td><%=
(243.2
2).sum(:actual-bw))
<td><%=
((243.2
,2).sum(:quantity)
/
,).sum(:quantity)
/
%></td>
14.7*3)/(CdemandLevels.where("contractDurationIDu=u?"
-
1).sum(:actual-bw))
("contractDurationIDu=?",
/
3).sum(:quantity)
%></td>
14.7*6)/(OdemandLevels.where("contractDurationID,=,?"
-
OdemandLevels.where("contractDurationIDu=u?",
OdemandLevels.where
bw))
%></td>
14.7*12) *(4-((demandLevels)where("contractDurationIDu=)?uANDuquantity.>u5",4)
-
(OdemandLevels where("contractDuration IDU=UANDuquantity,>,5",4).count*5)) / (
OdemandLevels.where ("contractDurationID=u?"
,4).sum(:quantity)))) + (243.2 - 14.7*3)*((OdemandLevels.where("
sum(:quantity)
-
contractDurationIDu=u?
ANDquantity la5",4).sum(:quantity)
ANDuquantityu>,5",4).count*5))
/
(OdemandLevelswhere("contractDurationIDu=,?,
-
(OdemandLevels.where("contractDurationID
OdemandLevels.where("contractDurationIDu=,?",4).sum(:quantity)
4).sum(:actual-bw))
<td><%=
sum(:quantity)
-
14.7*12) *(5-((demandLevels)where("contractDurationIDu=)?uANDuquantityu>u8"
OdemandLevels.where("contractDurationIDu=?j
"contractDuration
I D=?,ANDuquantityu>u8",5).sum(:quantity)
ANDuquantityI>,8" ,5).count*8))
/
<td><%=
"contract
-
-
14.7*12)*(1-(
/
(OdemandLevels.where
,6).sum(:quantity)
%></td>
</table>
Levels</h2>
<table>
<tr>
<th>id</th>
<th>timeStepID</th>
<th>satelliteID</th>
<th>bandwidth</th>
<th>cost</th>
<th>contractDuration</th>
</tr>
in
,5)
.sum(:quantity))))/(
OdemandLevels.where("contractDurationIDu=u?
OsatLevels
where("contractDurationIDu=u?uANDuquantity
,6).sum(:quantity))))
DurationIDu=?uANDuquantityu>u I"l,6).sum(:quantity)
satLev
14.7*3)*((OdemandLevels.where(
DurationID=?uANDquantityu>uI1",6).count*11))
</tr>
<% for
/
,5).sum(:quantity)
(demandLevels
OdemandLevels.where("contractDurationIDI=U?"
<h2>Satellite
-
(OdemandLeveIs.where("contractDurationIDu=u?"
(OdemandLevels
6).sum(:actual-bw))
(243.2
5).
(
%></td>
((243.2
ANDuquantity,>u11",6).count*l1))
",
+
/
(OdemandLevels.where("contractDurationID,=,?,
-
where(" contract
OdemandLevels.where("contractDurationIDu=?u"
.sum(:quantity)
?uANDuquantityu>u8" ,5).count*8))
',5).sum(:quantity))))
OdemandLevels.where("contractDurationID=U?"
5).sum(:actualbbw))
=u?",4).sum(:quantity))))/(
OdemandLevels.where("contractDurationIDu=u?
X></td>
((243.2
(OdemandLevels.where("contractDurationIDu=
-
/
%>
<tr>
<td><%= satLev.id %></td>
<td><%=
satLev.timeStepID X></td>
<td><%=
satLev.satelliteID %></td>
<td><%=
satLev.bandwidth %></td>
<td><%=
satLev.cost
%></td>
116
+
-
(243.2
/
-
>uI1",6)
(
14.7*3)*((OdemandLevels.where(
(OdemandLevels.where("contractDurationID,=,?,
("contractDurationID=?u"
/
6) .sum(:quantity))))/(
OdemandLevels.where("contractDurationIDu=,?
<td><%= satLev.contractDurationID X></td>
</tr>
<%
end
%>
</table>
<%=
will-paginate(OsatLevels)
<h2>Demand
by Region
%>
and TimeStep</h2>
<table>
<tr>
<th>id</th>
<th>timeStepID</th>
<th>regionID</tb>
<th>quantity</th>
</tr>
<%
for
demand
in
OdemandLevels
V.>
<tr>
<td><%= demand.id
%></td>
<td><%= demand.timeStepID
%></td>
<td><%= demand.regionID %></td>
<td><%= demand.quantity
%></td>
</tr>
<%
end %>
</table>
<%=
will-paginate(OdemandLevels)
B.2
class
def
%>
Controller
SatLevelsController
<
ApplicationController
index
QlastSim
=
Simulation.last
11= QlastSim
params [:simulation]
OcurrentSim
=
Simulation.find-by-id(params[:simulation])
Qsats=QlastSim.satellites
OtimingRuns=
OsatLevels
per-page
=>
=
30,
OdemandLevels
per-page
if
=>
30,
QlastSim.timing-run
SatLevel.joins(:time-step).where
:page =>
=Demand.joins(:time-step).where("time-steps.simulationID,=I?",
:page =>
(ecurrentSim
Osats
=
("time-steps.simulationID,=?",
=
ClastSim.id
).paginate(:
OlastSim.id
).paginate(:
params[:page])
params[:page])
Simulation.find-by-id(params[:simulation]))
QcurrentSim.satellites
OtimingRuns=
OcurrentSim.timing-run
QsatLevels
paginate (:per-page
=>
=
SatLevel.joins(:time-step).where(t ime
30,
CdemandLevels
paginate (:per-page
=>
30,
:page
=>
steps
=Demand.joins (:timeestep).where ("time_steps
:page
=>
simulationID,=,?",
OcurrentSim.id
).
simulation1D,=_?",
OcurrentSim.id
)
params[:page])
params[:pagel)
end
end
117
end
B.3
class
Models
ContractDuration
has-many
<
ActiveRecord::Base
:sat-level
end
class
Demand
ActiveRecord::Base
<
belongs-to
:region
belongs-to
:time-step, foreign-key:
def
self.atTimeStepRegConActual(ts,
'timeStepID'
reg,
contract)
ts
where("timeStepIDu=,?,ANDuregionIDU=U?uANDcontractDurationID=?",
,
reg,
contract).sum(:
actual-bw)
end
def
reg,
self.atTimeStepRegConQuantity(ts,
contract)
ts,
where("timeStepID,=,?,ANDregionIDu=u?,ANDcontractDurationID,=,?
reg, contract).sum(:
quantity)
end
end
class
OptionsCost
<
ActiveRecord::Base
belongs-to
:contact-duration,
belongs-to
:time-step,
foreign-key:
'timeStepID'
belongs-to
:satellite,
foreign_key:
'satelliteID'
def
self.cumCost(ts,
where
foreign-key:
contract,
'contractDurationID'
satID)
(" timeStepIDu=coANDncontractDurationID,=,7,ANDusatelliteIDu=?
ts
contract,
satID).sum(:
cumTotalC)
end
end
class
Region <
ActiveRecord::Base
has-many
:demand
has-many
:satellite-region
end
class
RunCost
<
ActiveRecord::Base
belongs-to
def
:simulation
self.onSim(sim)
where("simulationID;
?",sim)
end
def
self.countBetween(lower,
where("cumCost
upper,
contract)
>u,?,ANDcumCostU<,7,ANDcontractDurationIDL=L?",
end
end
118
lower ,
upper,
contract).count
class
SatLevel
ActiveRecord::Base
<
'contractDuration
foreign.key:
belongs-to
:contact-duration,
belongs-to
:time-step,
foreign-key:
'timeStepID'
belongs-to
:satellite,
foreign-key:
'sateliteID'
def
ID'
self.atTimeStep(ts)
where("timeStepIDu=,?"
ts).sum(:bandwidth)
,
end
def
self.atTimeStepSat(ts,
satID,
contract)
where("timeStepID=?,ANDsatelliteID,=,?,ANDcontractDurat
ionJD,_?", ts,
satID,
contract).sum(:
bandwidth)
end
def
self.atTimeStepCumCost(ts,
contract)
contractDurationID,='?",ts,
where("timeStepID,<=,,?AND
contract).sum(:cost)
end
def
self.CountAtCosts(lower,
upper)
>=,?,ANDecost,<?",
where("cost
lower ,
upper).count
end
def
.cumCost (ts
self
contract
,
where("tireStepID,,
,
satID)
,AND
contractDurationiD-,?,AND
cumCost)
end
end
class
SatelliteRegion
<
ActiveRecord::Base
belongs-to
:Satellite
belongs-to
:region
end
class
Satellite <
has-many
ActiveRecord::Base
:satjlevel,
'satLevelID'
foreign-key:
end
class
Simulation
<
ActiveRecord::Base
foreign-key:
has-many
:time-step,
has-many
:satellites,
has-many
:run-cost
has-many
:timingrun,
,
timeSteplD'
foreign-key:
'simulationID'
'simulationID'
foreign-key:
foreign-key:
'simulationID'
end
class
TimeStep
<
ActiveRecord::Base
belongs-to
:simulation
has-many
:demand
has-many
:sat-level,
def
foreign-key:
'timeStepID'
self.stepsOnLastSim
where("simulat ionID,
,?e,Simulation.last)
end
def
self.stepsOnSim
(sim)
where("simulationIDe.
,?_,
sim)
119
satelliteID=?"
,
ts,
contract
,
satID).sum(:
end
def
self.CountAtSatCosts(lower,
joins(: satllevel)
upper,
where("
contract)
cost,>=prANDcostu<?aANDcontractDurationID,=,?
lower,
contract).count
end
def
self.countAtSatLevel(lower,
joins(:
sat-level).
contractDurationID,=u?",
upper,
satID,
contract)
where ("bandwidth,>=?
lower,
upper,
satID,
uANDubandwidthu<u?
contract).count
end
end
class TimingRun < ActiveRecord::Base
end
B.4
Database Migrations
class CreateSimulations < ActiveRecord::Migration
def
change
create-table
t.string
:simulations
do Iti
:name
t .timestamps
end
end
end
class
def
CreateSatLevels < ActiveRecord::Migration
change
create-table
:sat-levels do
t.integer
:timeStepID
t.integer
:satelliteID
t.float
:bandwidth
t.float
:cost
t.integer
Iti
:contractDurationID
t .timestamps
end
end
end
class
def
CreateTimeSteps
< ActiveRecord::Migration
change
create-table
:time-steps do Iti
t.integer
:run
t.integer
:period
t.integer
:simulationID
t.timestamps
120
ANDsate11iteI D=,?uAND,
upper
end
end
end
class
def
CreateDemands
<
ActiveRecord::Migration
change
create-table
:demands
do
t.integer
:timeStepID
t.integer
:regionID
t.float
Iti
:quantity
t.timestamps
end
end
end
class
def
CreateRegions
<
ActiveRecord::Migration
change
create-table
t.string
:regions
do
Iti
:name
t.timestamps
end
end
end
class
<
CreateContractDurations
def
ActiveRecord::Migration
change
create-table
:contract
t.integer
durations
do
Iti
:months
t.timestamps
end
end
end
class
CreateSatellites
def
<
ActiveRecord::Migration
change
create-table
t.string
:satellites
do
Iti
:name
t.integer
:capacity
t.timestamps
end
end
end
class
CreateSatelliteRegions
def
<
ActiveRecord::Migration
change
create-table
:satellite-regions
t.integer
:satelliteID
t.integer
:regionID
do
Iti
t.timestamps
end
end
end
121
class AddActualBwToDemand < ActiveRecord::Migration
def
change
add-column
:demands,
float
:actual-bw,
end
end
class AddSimulationIdToSatellite < ActiveRecord::Migration
def
change
add-column
:satellites,
simulationID,
integer
end
end
class AddContractDurationIdToDemands
def
<
ActiveRecord::Migration
change
add-column :demands,
:contractDurationID,
:integer
end
end
class
def
CreateRunCosts
< ActiveRecord::Migration
change
create-table
t.float
:run-costs do
ti
:cumCost
t.integer :simulationID
t.integer
:run
t.timestamps
end
end
end
class AddContractDurationIdToRunCosts < ActiveRecord::Migration
def change
add-column
:run-costs,
:contractDurationID,
integer
end
end
class AddCumCostToSatLevels
def
<
ActiveRecord::Migration
change
add-column
:sat-levels,
:cumCost ,
:float
end
end
class CreatefptionsCosts < ActiveRecord::Migration
def
change
create-table
t.integer
:options-costs do Iti
:timeStepID
t.integer
:optionsExecuted
t.integer
:optionsPurchased
t.float
:reservationPrice
t.float
:executionPrice
t.float
:optionsCost
t.float
:cumOptC
t.float
:excessCost
t.float
:cumTotalC
t.integer
:contractDurationID
t.timestamps
end
end
end
122
class
def
AddSatelliteIdToOptionsCosts
<
ActiveRecord::Migration
change
add-column
:options-costs,
satellitelD,
integer
end
end
class
def
CreateTimingRuns
<
ActiveRecord::Migration
change
create-table
:timing-runs
t.integer
:simulationID
t.integer
:run
t.integer
:numPeriods
t.integer
:numSats
t.integer
:numSatLevels
t.integer
:numReg
t.integer
:numNodes
t.integer
:numSteps
do
Iti
t.timestamps
end
end
end
123
124
Bibliography
[1]
General Services Administration. Indefinite Delivery, Indefinite Quantity Contracts. 2012. URL: http://www.gsa.gov/portal/content/103926
(visited on
04/10/2012).
[2]
Defense Information Systems Agency. Modifications to the Defense Information
Systems Network (DISN) Satellite Transmission Services. 2010. URL: https:
//www. fbo
.
gov/ index?s=opportunity&mode=form&tab=core&id=
dc931c9adb0017bfc22f4de97e7ee2ea.
[3]
European Space Agency. Satellite Frequency Bands. 2013. URL: http: //www.
esa. int/OurActivities/TelecommunicationsIntegratedApplications/
Satellite_frequencybands (visited on 04/10/2014).
[4]
Tim Bonds et al. Employing Commercial Satellite Communications: Wideband
Investment Options for the Department of Defense. Tech. rep. RAND, 2000.
[5]
Neil F. Albert. Taking Advantage of Opportunities for Commercial Satellite
Communications Services: Report to the Secretary of Defense. Tech. rep. Defense Business Board, 2013.
[6]
Amazon. Amazon Prime Air. 2013. URL: http: //www. amazon. com/b?node=
8037720011 (visited on 04/15/2014).
[7]
Elisabeth Bumiller. Obama Puts His Stamp on Strategy for a Leaner Military.
NY Times. Jan. 5, 2012. URL: http: //www.nytimes. com/2012/01/06/us/
obama- at-pentagon-to- outline- cuts-and-strategic- shif ts.html?_r=0
(visited on 05/10/2014).
125
[8]
CCJ. TransCore:Satellite network achieved 99.992% uptime in 2007. 2008. URL:
http: //www.
ccjdigital. com/transcore- satellite -network- achieved-
99992-uptime-in-2007-2/ (visited on 04/13/2014).
[91
DISA. FY 2010 COMSATCOM Annual Usage Report Released to DoD Stakeholders. 2012. URL: http://www.disa.mil/Services/SATCOM/ComsatcomServices/Scoop-Newsletter/2012-10/FY2010-COMSATCOM-Annual-UsageReport (visited on 04/12/2014).
[10]
DoD. "17.2. Options". In: Federal Acquisition Regulation. Ed. by DoD. 2014.
URL:
http: //www. acquisition .gov/far/html/Subpart%2017
_
2. html
(visited on 05/12/2014).
[111
Defense FAR. "Part 252 - Solicitation Provisions and Contract Clauses". In:
Defense FederalAcquisition Regulation Supplement. Ed. by Defense FAR. 2012.
URL: www . acq . osd . mil / dpap / dars / df ars / doc / 252239 . doc (visited on
04/10/2014).
[12
Frost and Sullivan. Commercial Geostationary Satellite Transponder Markets
for Latin America. 2003. URL: http : / / www . frost . com / prod / serviet /
report -brochure .pag?id=A397-01-00-00-00 (visited on 04/14/2014).
[13
Futron. 2010 Futron Forecast of Global Satellite Services Demand Overview.
2010. URL: http://www.futron.com/upload/wysiwyg/Resources/Reports/
2010_FutronForecastOverview.pdf (visited on 04/10/2014).
[14]
Jacbo Gullish. The North American Satellite Market New Methodology Required... Futron. 2011. URL: http: / /www .satmagazine . com / story . php ?
number=1585073081 (visited on 04/10/2014).
[15]
Xin Huang. "Capacity Planning in a General Supply Chain with Multiple Contract Types Single Period Model". PhD Thesis. Massachusetts Institute of Technology, 2008.
126
[16]
Dustin Kaiser. Military Communications A Key Target For Satellite Services.
Futron. 2011. URL: http: //www.
milsatmagazine. com/story .php?number=
1620673149 (visited on 04/12/2014).
[17]
Owen Kurtin. FSS and MSS: Blurring the Lines. 2012. URL: http: //www .
satellitetoday. com/telecom/2012/05/01/f ss - and-mss -blurring-the -
lines/ (visited on 04/12/2014).
[18]
Patrick Rayerman. "Exploiting Commercial SATCOM: A Better Way". In: Parameters. Winter 03-04 (2003). URL: http: //strategicstudiesinstitute.
army.mil/pubs/parameters/articles/03winter/rayerman.
htm (visited on
04/10/2014).
[19]
Shaun Waterman. Drones over U.S. get OK by Congress. Washington Times.
2012. URL: http://www.washingtontimes.com/news/2012/feb/7/comingto-a-sky-near-you/?page=all (visited on 04/11/2014).
127
Download