Skip to content

Commit 5665905

Browse files
first commit
1 parent be43f70 commit 5665905

33 files changed

+515
-956
lines changed

.DS_Store

2 KB
Binary file not shown.

README.md

+62-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ This program currently generates optimal default spare placement for the followi
1818
- CFM56-5B3-3
1919
- CFM56-7B26
2020
- CFM56-7B27E-B1F
21-
- JT8D-219
2221
- PW2000-2037
2322
- PW2000-2040
2423
- PW4000-4060
@@ -54,6 +53,56 @@ cd StaticPlacementGenerator
5453

5554
## Usage
5655

56+
### First Run
57+
58+
Some files will need to be created to use for all subsequent runs. These tasks will only need to be completed once per machine this program is used on.
59+
60+
Navigate to the `StaticPlacementGenerator` directory. Run the following command to set the `FIRST_RUN` environment variable to indicate this is the first time running this program on your machine:
61+
```
62+
export FIRST_RUN=true
63+
```
64+
65+
Doing this will create the following for future use:
66+
- All possible states exported to a file
67+
- All possible removal situations for each engine type exported to a file
68+
69+
### Subsequent Runs
70+
71+
The `FIRST_RUN` environment variable can be set to FALSE for all future runs.
72+
```
73+
export FIRST_RUN=false
74+
```
75+
76+
Prior to running this program, a few files may need to be updated.
77+
78+
#### Update Information to Reflect Current State/System
79+
80+
**`data_to_read/removal_info.csv`**
81+
82+
This file contains information on expected number of removals for each engine subtype. For each engine subtype, the following is specified:
83+
- Expected maximum number of removals in a month for all airports
84+
- Expected maximum number of removals in a month for each specific hub
85+
- Expected maximum number of removals in a month for all airports excluding hubs
86+
- Expected AOS cost
87+
- Whether or not these files were updated from the previous run (if any of the data for a subtype has been updated, make sure to set the UPDATED column value for that row to be TRUE)
88+
89+
Our team based these values on past removal data for each type. We set the maximum number of removals that could happen based on data from 2015-2019 by taking the maximum that had ever occurred for each and adding 1 to it. For example, if no more than 3 removals ever occurred in ATL, we assumed the maximum number of removals that could ever happen at ATL would be 4.
90+
91+
*Limitations*:
92+
- The maximum number of removals for all airports cannot be less than 1 or greater than 10
93+
- The maximum number of removals for each specific hub cannot be greater than 10
94+
- The maximum number of removals for all airports excluding hubs cannot be greater than 2
95+
96+
The purpose of this file is to minimize the iterations the program runs so that runtime is reduced and extremely unlikely situations are not considered.
97+
98+
**`data_to_read/engine_info.csv`**
99+
100+
This file contains information on total number of engines for each engine subtype. For each engine subtype, the following is specified:
101+
- Total number of current spare engines
102+
103+
*Limitations*:
104+
- The total number of current spare engines cannot be less than 1 and cannot be greater than 5
105+
57106
### Run the Program
58107

59108
Navigate to the `StaticPlacementGenerator` directory if you aren't there already.
@@ -67,6 +116,18 @@ The program may take several hours to run.
67116

68117
## Files Provided
69118

119+
For each engine subtype (located in `StaticPlacementGenerator/data_to_read/engine_subtype/`):
120+
121+
| File | Description |
122+
| ----------------------------------------------------------| --------------------------------------------------------- |
123+
| `probabilities_of_num_removals_in_each_state_region` | Probabilities of removals based on 2015-2019 data |
124+
| `expected_transport_cost` | Expected transportation costs from hubs to state regions |
125+
| `number_of_broken_engines_and_number_repaired` | Probabilities of engines repaired given on engines broken |
126+
127+
Turnover documents will be provided that will outline how to re-calculate probability values based on new past data.
128+
129+
**The format of these documents (the naming of the file, the header structure and naming, etc.) must remain the same in order for the program to work.**
130+
70131
## Authors
71132

72133
**Industrial and Systems Engineering, Georgia Institute of Technology**, Spring 2020

app.py

+49-180
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,57 @@
1-
from util import reader_util, writer_util, data_util
2-
import data, static_placement_finder
1+
from util import reader_util, writer_util, data_util, config
2+
from services import data_generator, solve
3+
import data
34
import pprint, logging
45

56
if __name__ == '__main__':
67
data.init()
78

8-
logging.basicConfig(level=logging.INFO)
9-
10-
time_range = '2015-2019'
11-
12-
file_with_all_permutations_exists = True
13-
14-
# ********** V2500-D5 ********** 2015-2018 done, 2015-2019 done
15-
# engine_subtype = 'V2500 - D5'
16-
# engine_subtype_filename = 'V2500-D5'
17-
# num_engines = 4
18-
# max_num_removals_to_iterate = 5
19-
# max_num_removals_to_find_cost = 5
20-
# subtype_aos_cost = 9072
21-
22-
# ********** TRENT8-892-17 ********** 2015-2018 done
23-
engine_subtype = 'TRENT8 - 892-17'
24-
engine_subtype_filename = 'TRENT8-892-17'
25-
num_engines = 1
26-
max_num_removals_to_iterate = 1
27-
max_num_removals_to_find_cost = 1
28-
subtype_aos_cost = 20105
29-
30-
# ********** PW4000-4168 ********** 2015-2018 done
31-
# engine_subtype = 'PW4000 - 4168'
32-
# engine_subtype_filename = 'PW4000-4168'
33-
# num_engines = 1
34-
# max_num_removals_to_iterate = 5
35-
# max_num_removals_to_find_cost = 5
36-
# subtype_aos_cost = 17556
37-
38-
# ********** PW4000-4060 ********** 2015-2018 done
39-
# engine_subtype = 'PW4000 - 4060'
40-
# engine_subtype_filename = 'PW4000-4060'
41-
# num_engines = 2
42-
# max_num_removals_to_iterate = 2
43-
# max_num_removals_to_find_cost = 2
44-
# subtype_aos_cost = 9081
45-
46-
# ********** PW2000-2040 ********** 2015-2018 done
47-
# engine_subtype = 'PW2000 - 2040'
48-
# engine_subtype_filename = 'PW2000-2040'
49-
# num_engines = 1
50-
# max_num_removals_to_iterate = 4
51-
# max_num_removals_to_find_cost = 4
52-
# subtype_aos_cost = 9134.5
53-
54-
# ********** PW2000-2037 ********** 2015-2018 done
55-
# engine_subtype = 'PW2000 - 2037'
56-
# engine_subtype_filename = 'PW2000-2037'
57-
# num_engines = 3
58-
# max_num_removals_to_iterate = 5
59-
# max_num_removals_to_find_cost = 5
60-
# subtype_aos_cost = 9134.5
61-
62-
# ********** JT8D-219 **********
63-
# ********** need to re-generate combinations
64-
# 10 in ATL, 5 CVG DTW MSP, 0 LAX SEA SLC, 2 non-hubs
65-
# engine_subtype = 'JT8D - 219'
66-
# engine_subtype_filename = 'JT8D-219'
67-
# num_engines = 4
68-
# max_num_removals_to_iterate = 17
69-
# max_num_removals_to_find_cost = 17
70-
# subtype_aos_cost = 9177
71-
72-
# ********** CFM56-7B27E-B1F ********** 2015-2018 done
73-
# engine_subtype = 'CFM56 - 7B27E/B1F'
74-
# engine_subtype_filename = 'CFM56-7B27E-B1F'
75-
# num_engines = 1
76-
# max_num_removals_to_iterate = 2
77-
# max_num_removals_to_find_cost = 2
78-
# subtype_aos_cost = 7417
79-
80-
# ********** CFM56-7B26 ********** 2015-2018 done
81-
# engine_subtype = 'CFM56 - 7B26'
82-
# engine_subtype_filename = 'CFM56-7B26'
83-
# num_engines = 3
84-
# max_num_removals_to_iterate = 3
85-
# max_num_removals_to_find_cost = 3
86-
# subtype_aos_cost = 5350.5
87-
88-
# ********** CFM56-5B3-3 ********** 2015-2018 done
89-
# engine_subtype = 'CFM56 - 5B3/3'
90-
# engine_subtype_filename = 'CFM56-5B3-3'
91-
# num_engines = 1
92-
# max_num_removals_to_iterate = 1
93-
# max_num_removals_to_find_cost = 1
94-
# subtype_aos_cost = 8843
95-
96-
# ********** CFM56-5A ********** 2015-2018 done
97-
# engine_subtype = 'CFM56 - 5A'
98-
# engine_subtype_filename = 'CFM56-5A'
99-
# num_engines = 5
100-
# max_num_removals_to_iterate = 7
101-
# max_num_removals_to_find_cost = 7
102-
# subtype_aos_cost = 5053.5
103-
104-
# ********** CF6-80E1A4 ********** 2015-2018 done
105-
# engine_subtype = 'CF6 - 80E1A4'
106-
# engine_subtype_filename = 'CF6-80E1A4'
107-
# num_engines = 2
108-
# max_num_removals_to_iterate = 1
109-
# max_num_removals_to_find_cost = 1
110-
# subtype_aos_cost = 22403
111-
112-
# ********** CF6-80C2B8F ********** 2015-2018 done
113-
# engine_subtype = 'CF6 - 80C2B8F'
114-
# engine_subtype_filename = 'CF6-80C2B8F'
115-
# num_engines = 1
116-
# max_num_removals_to_iterate = 4
117-
# max_num_removals_to_find_cost = 4
118-
# subtype_aos_cost = 8580
119-
120-
# ********** CF6-80C2B6F ********** 2015-2018 done
121-
# engine_subtype = 'CF6 - 80C2B6F'
122-
# engine_subtype_filename = 'CF6-80C2B6F'
123-
# num_engines = 2
124-
# max_num_removals_to_iterate = 5
125-
# max_num_removals_to_find_cost = 5
126-
# subtype_aos_cost = 8200
127-
128-
# ********** CF6-80C2B6 ********** 2015-2018 done
129-
# engine_subtype = 'CF6 - 80C2B6'
130-
# engine_subtype_filename = 'CF6-80C2B6'
131-
# num_engines = 1
132-
# max_num_removals_to_iterate = 2
133-
# max_num_removals_to_find_cost = 2
134-
# subtype_aos_cost = 13121
135-
136-
# ********** BR700-715C1-30 ********** 2015-2018 done
137-
# engine_subtype = 'BR700 - 715C1-30'
138-
# engine_subtype_filename = 'BR700-715C1-30'
139-
# num_engines = 2
140-
# max_num_removals_to_iterate = 5
141-
# max_num_removals_to_find_cost = 5
142-
# subtype_aos_cost = 4525
143-
144-
data.probabilities_of_engine_repair_within_month_by_num_broken = data_util.set_probabilities_of_engine_repair_within_month_by_num_broken(
145-
engine_subtypes_overall=data.all_engine_subtypes_overall,
146-
data_storage=data.probabilities_of_engine_repair_within_month_by_num_broken)
147-
data.expected_cost_to_transport_engine_from_hub_for_each_state_region = data_util.set_expected_cost_to_transport_engine_from_hub_for_each_state_region(
148-
engine_subtypes_overall=data.all_engine_subtypes_overall,
149-
hubs_and_state_regions=data.hubs_and_state_regions,
150-
hubs=data.current_delta_hubs,
151-
data_storage=data.expected_cost_to_transport_engine_from_hub_for_each_state_region)
152-
data.probabilities_of_num_removals_in_each_state_region = data_util.set_probabilities_of_num_removals_in_each_state_region(
153-
engine_subtypes_overall=data.all_engine_subtypes_overall,
154-
hubs_and_state_regions=data.hubs_and_state_regions,
155-
data_storage=data.probabilities_of_num_removals_in_each_state_region)
156-
data.all_possible_removal_situations_by_number_of_removals = data_util.set_all_possible_removal_situations_by_number_of_removals(
157-
max_num_removals=max_num_removals_to_find_cost,
158-
data_storage=data.all_possible_removal_situations_by_number_of_removals)
159-
160-
# ********** READING FROM FILES **********
161-
162-
data.probabilities_of_engine_repair_within_month_by_num_broken = reader_util.read_number_of_broken_engines_and_number_repaired_file(
163-
filename='data_to_read/' + engine_subtype_filename + '/' + engine_subtype_filename + '_number_of_broken_engines_and_number_repaired.csv',
164-
engine_subtype=engine_subtype,
165-
data_storage=data.probabilities_of_engine_repair_within_month_by_num_broken)
166-
data.expected_cost_to_transport_engine_from_hub_for_each_state_region = reader_util.read_expected_transport_cost_file(
167-
filename='data_to_read/' + engine_subtype_filename + '/' + engine_subtype_filename + '_expected_transport_cost.csv',
168-
engine_subtype=engine_subtype,
169-
hubs=data.current_delta_hubs,
170-
data_storage=data.expected_cost_to_transport_engine_from_hub_for_each_state_region)
171-
data.probabilities_of_num_removals_in_each_state_region = reader_util.read_probabilities_of_num_removals_in_each_state_region_file(
172-
filename='data_to_read/' + engine_subtype_filename + '/' + engine_subtype_filename + '_' + time_range + '_probabilities_of_num_removals_in_each_state_region.csv',
173-
engine_subtype=engine_subtype,
174-
data_storage=data.probabilities_of_num_removals_in_each_state_region)
175-
data.all_possible_removal_situations_by_number_of_removals = reader_util.read_num_removals_state_regions_and_hubs_file(
176-
max_num_removals=max_num_removals_to_find_cost,
177-
data_storage=data.all_possible_removal_situations_by_number_of_removals)
178-
179-
# ********** DOING CALCULATIONS **********
180-
181-
print("\n******************** Finding static placement for " + str(num_engines) + " total engines with up to " + str(max_num_removals_to_find_cost) + " removals total happening in the month. ********************\n")
182-
static_placement_finder.find_static_placement(engine_subtype=engine_subtype, engine_subtype_filename=engine_subtype_filename, num_engines=num_engines, max_num_removals_to_iterate=max_num_removals_to_iterate, max_num_removals_to_find_cost=max_num_removals_to_find_cost, subtype_aos_cost=subtype_aos_cost, time_range=time_range, file_with_all_permutations_exists=file_with_all_permutations_exists)
183-
184-
185-
9+
# Import engine information
10+
data.engines_info = reader_util.import_engine_info(
11+
filepath='data_to_read/engine_info.csv',
12+
data_storage=data.engines_info)
13+
14+
# Import removal information
15+
data.removals_info, data.aos_cost = reader_util.import_removal_info(
16+
filepath='data_to_read/removal_info.csv',
17+
removals_data_storage=data.removals_info,
18+
aos_cost_data_storage=data.aos_cost)
19+
20+
data_util.validate_removal_and_engine_info()
21+
22+
if config.first_run:
23+
logging.info("FIRST_RUN is set to TRUE. All files needed for future runs are going to be generated. This may take awhile.")
24+
data_generator.generate_all_possible_states()
25+
data_generator.generate_all_possible_num_broken_num_working()
26+
logging.info("All files needed for future runs have been created. Please set FIRST_RUN to FALSE for any future runs on this machine.")
27+
else:
28+
# Import engine subtype data
29+
reader_util.import_engine_subtype_data()
30+
31+
data_util.validate_engine_subtype_data()
32+
33+
# Generate all possible removal situations if removal info has been updated
34+
for engine_subtype in data.engine_subtypes:
35+
if data.need_to_update_removal_info[engine_subtype]:
36+
data_generator.generate_all_possible_removal_situations(
37+
engine_subtype=engine_subtype)
38+
39+
# Import all possible states
40+
data.all_possible_states = reader_util.import_all_possible_states(
41+
filepath='data_to_read/all_possible_states.csv',
42+
data_storage=data.all_possible_states)
43+
44+
# Import all possible number of engines broken and number of engines working
45+
data.all_possible_num_working_num_broken = reader_util.import_all_possible_num_working_num_broken(
46+
filepath='data_to_read/all_possible_num_working_num_broken.csv',
47+
data_storage=data.all_possible_num_working_num_broken)
48+
49+
# Import all possible removal situations
50+
data.all_possible_removal_situations = reader_util.import_all_possible_removal_situations(
51+
data_storage=data.all_possible_removal_situations)
52+
53+
for engine_subtype in data.engine_subtypes:
54+
solve.static_placement_generator(engine_subtype)
18655

18756

18857

0 commit comments

Comments
 (0)