Title: Maui Travel Time
Author: Tara Graeve
Date: Winter Quarter 2021
A traveler to Maui, Hawaii has compiled a list of destinations to visit. The traveler would like to mimimize their total travel time to each destination. The traveler has selected 7 possible destinations: Haleakala, Kaanapali Beach, Napili Beach, Wailea Beach, Black Rock Beach, Nakalele Blowhole, and Kapalua Bay. The traveler has provided certain requirements to adhere to, though sensitivity analysis will also be performed and presented to them. The initial requirements are: the traveler doesn't want to go to more than 5 of the places but must go to at least 3, they absolutely must visit Kaanapali Beach, and they only want to spend a maximum of 3.5 hours traveling between destinations. In order to optimize the travel times, an assignment linear programming model will be performed. We don't want to double up destinations, so there will also be a limit of at most 1 total selections of each destination.
Data was collected via the Apple Maps application at a specific moment in time to find travel times to each destination from each other destination. This data was compiled into a matrix that will serve as coefficients in the objective functions. Because we don't want to travel from a destination to itself, the coefficients will purposely be large to prevent the solver from choosing those pairs. The decision variables are binary, so ultimately the objective function will be a sum of each time coefficient multiplied by the binary (0/1) variable. Because travel times can vary, it will be helpful to perform a sensitivity analysis slightly varying times to account for traffic/time of day.
Data obtained via Apple Maps queries between destinations. Constraint data is fictitious based on a theoretical traveler.
# perform all necessary imports for the rest of this project
import pandas as pd
import pyomo.environ as pe
import matplotlib.pyplot as plt
%matplotlib inline
#coefficient data -- travel times
coef = pd.read_excel('INFO 3440 Project Data.xlsx', sheet_name='Coef', index_col=0)
coef
Haleakala | Kaanapali Beach | Napili Beach | Wailea Beach | Black Rock Beach | Nakalele Blowhole | Kapalua Bay | |
---|---|---|---|---|---|---|---|
Haleakala | 10000 | 95 | 98 | 68 | 89 | 118 | 99 |
Kaanapali Beach | 92 | 10000 | 13 | 51 | 4 | 33 | 13 |
Napili Beach | 108 | 21 | 10000 | 67 | 20 | 32 | 5 |
Wailea Beach | 71 | 59 | 63 | 10000 | 54 | 83 | 64 |
Black Rock Beach | 106 | 21 | 18 | 57 | 10000 | 38 | 18 |
Nakalele Blowhole | 119 | 35 | 27 | 83 | 33 | 10000 | 26 |
Kapalua Bay | 83 | 18 | 5 | 67 | 17 | 30 | 10000 |
rhs = pd.read_excel('INFO 3440 Project Data.xlsx', sheet_name='Constraints')
rhs
Unnamed: 0 | Max | |
---|---|---|
0 | Max Time | 210 |
1 | Min Places | 3 |
2 | Max Places | 5 |
model = pe.ConcreteModel()
# define DVs
DV_indexes=['Haleakala','Kaanapali Beach','Napili Beach','Wailea Beach','Black Rock Beach', 'Nakalele Blowhole','Kapalua Bay']
model.Haleakala = pe.Var(DV_indexes, domain=pe.Binary)
model.Kaanapali = pe.Var(DV_indexes, domain=pe.Binary)
model.Napili = pe.Var(DV_indexes, domain=pe.Binary)
model.Wailea = pe.Var(DV_indexes, domain=pe.Binary)
model.BlackRock = pe.Var(DV_indexes, domain=pe.Binary)
model.Nakalele = pe.Var(DV_indexes, domain=pe.Binary)
model.Kapalua = pe.Var(DV_indexes, domain=pe.Binary)
# define objective
model.obj = pe.Objective(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes),
sense=pe.minimize)
model.obj.pprint()
obj : Size=1, Index=None, Active=True Key : Active : Sense : Expression None : True : minimize : 10000*Haleakala[Haleakala] + 95*Haleakala[Kaanapali Beach] + 98*Haleakala[Napili Beach] + 68*Haleakala[Wailea Beach] + 89*Haleakala[Black Rock Beach] + 118*Haleakala[Nakalele Blowhole] + 99*Haleakala[Kapalua Bay] + 92*Kaanapali[Haleakala] + 10000*Kaanapali[Kaanapali Beach] + 13*Kaanapali[Napili Beach] + 51*Kaanapali[Wailea Beach] + 4*Kaanapali[Black Rock Beach] + 33*Kaanapali[Nakalele Blowhole] + 13*Kaanapali[Kapalua Bay] + 108*Napili[Haleakala] + 21*Napili[Kaanapali Beach] + 10000*Napili[Napili Beach] + 67*Napili[Wailea Beach] + 20*Napili[Black Rock Beach] + 32*Napili[Nakalele Blowhole] + 5*Napili[Kapalua Bay] + 71*Wailea[Haleakala] + 59*Wailea[Kaanapali Beach] + 63*Wailea[Napili Beach] + 10000*Wailea[Wailea Beach] + 54*Wailea[Black Rock Beach] + 83*Wailea[Nakalele Blowhole] + 64*Wailea[Kapalua Bay] + 106*BlackRock[Haleakala] + 21*BlackRock[Kaanapali Beach] + 18*BlackRock[Napili Beach] + 57*BlackRock[Wailea Beach] + 10000*BlackRock[Black Rock Beach] + 38*BlackRock[Nakalele Blowhole] + 18*BlackRock[Kapalua Bay] + 119*Nakalele[Haleakala] + 35*Nakalele[Kaanapali Beach] + 27*Nakalele[Napili Beach] + 83*Nakalele[Wailea Beach] + 33*Nakalele[Black Rock Beach] + 10000*Nakalele[Nakalele Blowhole] + 26*Nakalele[Kapalua Bay] + 83*Kapalua[Haleakala] + 18*Kapalua[Kaanapali Beach] + 5*Kapalua[Napili Beach] + 67*Kapalua[Wailea Beach] + 17*Kapalua[Black Rock Beach] + 30*Kapalua[Nakalele Blowhole] + 10000*Kapalua[Kapalua Bay]
# total travel time <= 210
model.con_time = pe.Constraint(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes)
<= rhs.loc[0,'Max'])
# total destinations <= 5
model.con_maxDest = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) +
sum(model.Kaanapali[c] for c in DV_indexes) +
sum(model.Napili[c] for c in DV_indexes) +
sum(model.Wailea[c] for c in DV_indexes) +
sum(model.BlackRock[c] for c in DV_indexes) +
sum(model.Nakalele[c] for c in DV_indexes) +
sum(model.Kapalua[c] for c in DV_indexes)
<= rhs.loc[2,'Max'])
# total destinations >= 3
model.con_minDest = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) +
sum(model.Kaanapali[c] for c in DV_indexes) +
sum(model.Napili[c] for c in DV_indexes) +
sum(model.Wailea[c] for c in DV_indexes) +
sum(model.BlackRock[c] for c in DV_indexes) +
sum(model.Nakalele[c] for c in DV_indexes) +
sum(model.Kapalua[c] for c in DV_indexes)
>= rhs.loc[1,'Max'])
# must visit Kaanapali
model.con_visit = pe.Constraint(expr=model.Haleakala['Kaanapali Beach'] +
model.Kaanapali['Kaanapali Beach'] +
model.Napili['Kaanapali Beach'] +
model.Wailea['Kaanapali Beach'] +
model.BlackRock['Kaanapali Beach'] +
model.Nakalele['Kaanapali Beach'] +
model.Kapalua['Kaanapali Beach'] == 1)
# max 1 per row
model.con_HaleakalaRow = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) <= 1)
model.con_KaanapaliRow = pe.Constraint(expr=sum(model.Kaanapali[c] for c in DV_indexes) <= 1)
model.con_NapiliRow = pe.Constraint(expr=sum(model.Napili[c] for c in DV_indexes) <= 1)
model.con_WaileaRow = pe.Constraint(expr=sum(model.Wailea[c] for c in DV_indexes) <= 1)
model.con_BlackRockRow = pe.Constraint(expr=sum(model.BlackRock[c] for c in DV_indexes) <= 1)
model.con_NakaleleRow = pe.Constraint(expr=sum(model.Nakalele[c] for c in DV_indexes) <= 1)
model.con_KapaluaRow =pe.Constraint(expr=sum(model.Kapalua[c] for c in DV_indexes) <= 1)
# max 1 per column, Kaanapali already accounted for above
model.con_HaleakalaCol = pe.Constraint(expr=model.Haleakala['Haleakala'] +
model.Kaanapali['Haleakala'] +
model.Napili['Haleakala'] +
model.Wailea['Haleakala'] +
model.BlackRock['Haleakala'] +
model.Nakalele['Haleakala'] +
model.Kapalua['Haleakala'] <= 1)
model.con_NapiliCol = pe.Constraint(expr=model.Haleakala['Napili Beach'] +
model.Kaanapali['Napili Beach'] +
model.Napili['Napili Beach'] +
model.Wailea['Napili Beach'] +
model.BlackRock['Napili Beach'] +
model.Nakalele['Napili Beach'] +
model.Kapalua['Napili Beach'] <= 1)
model.con_WaileaCol = pe.Constraint(expr=model.Haleakala['Wailea Beach'] +
model.Kaanapali['Wailea Beach'] +
model.Napili['Wailea Beach'] +
model.Wailea['Wailea Beach'] +
model.BlackRock['Wailea Beach'] +
model.Nakalele['Wailea Beach'] +
model.Kapalua['Wailea Beach'] <= 1)
model.con_BlackRockCol = pe.Constraint(expr=model.Haleakala['Black Rock Beach'] +
model.Kaanapali['Black Rock Beach'] +
model.Napili['Black Rock Beach'] +
model.Wailea['Black Rock Beach'] +
model.BlackRock['Black Rock Beach'] +
model.Nakalele['Black Rock Beach'] +
model.Kapalua['Black Rock Beach'] <= 1)
model.con_NakaleleCol = pe.Constraint(expr=model.Haleakala['Nakalele Blowhole'] +
model.Kaanapali['Nakalele Blowhole'] +
model.Napili['Nakalele Blowhole'] +
model.Wailea['Nakalele Blowhole'] +
model.BlackRock['Nakalele Blowhole'] +
model.Nakalele['Nakalele Blowhole'] +
model.Kapalua['Nakalele Blowhole'] <= 1)
model.con_KapaluaCol = pe.Constraint(expr=model.Haleakala['Kapalua Bay'] +
model.Kaanapali['Kapalua Bay'] +
model.Napili['Kapalua Bay'] +
model.Wailea['Kapalua Bay'] +
model.BlackRock['Kapalua Bay'] +
model.Nakalele['Kapalua Bay'] +
model.Kapalua['Kapalua Bay'] <= 1)
model.pprint()
7 Set Declarations BlackRock_index : Size=1, Index=None, Ordered=Insertion Key : Dimen : Domain : Size : Members None : 1 : Any : 7 : {'Haleakala', 'Kaanapali Beach', 'Napili Beach', 'Wailea Beach', 'Black Rock Beach', 'Nakalele Blowhole', 'Kapalua Bay'} Haleakala_index : Size=1, Index=None, Ordered=Insertion Key : Dimen : Domain : Size : Members None : 1 : Any : 7 : {'Haleakala', 'Kaanapali Beach', 'Napili Beach', 'Wailea Beach', 'Black Rock Beach', 'Nakalele Blowhole', 'Kapalua Bay'} Kaanapali_index : Size=1, Index=None, Ordered=Insertion Key : Dimen : Domain : Size : Members None : 1 : Any : 7 : {'Haleakala', 'Kaanapali Beach', 'Napili Beach', 'Wailea Beach', 'Black Rock Beach', 'Nakalele Blowhole', 'Kapalua Bay'} Kapalua_index : Size=1, Index=None, Ordered=Insertion Key : Dimen : Domain : Size : Members None : 1 : Any : 7 : {'Haleakala', 'Kaanapali Beach', 'Napili Beach', 'Wailea Beach', 'Black Rock Beach', 'Nakalele Blowhole', 'Kapalua Bay'} Nakalele_index : Size=1, Index=None, Ordered=Insertion Key : Dimen : Domain : Size : Members None : 1 : Any : 7 : {'Haleakala', 'Kaanapali Beach', 'Napili Beach', 'Wailea Beach', 'Black Rock Beach', 'Nakalele Blowhole', 'Kapalua Bay'} Napili_index : Size=1, Index=None, Ordered=Insertion Key : Dimen : Domain : Size : Members None : 1 : Any : 7 : {'Haleakala', 'Kaanapali Beach', 'Napili Beach', 'Wailea Beach', 'Black Rock Beach', 'Nakalele Blowhole', 'Kapalua Bay'} Wailea_index : Size=1, Index=None, Ordered=Insertion Key : Dimen : Domain : Size : Members None : 1 : Any : 7 : {'Haleakala', 'Kaanapali Beach', 'Napili Beach', 'Wailea Beach', 'Black Rock Beach', 'Nakalele Blowhole', 'Kapalua Bay'} 7 Var Declarations BlackRock : Size=7, Index=BlackRock_index Key : Lower : Value : Upper : Fixed : Stale : Domain Black Rock Beach : 0 : None : 1 : False : True : Binary Haleakala : 0 : None : 1 : False : True : Binary Kaanapali Beach : 0 : None : 1 : False : True : Binary Kapalua Bay : 0 : None : 1 : False : True : Binary Nakalele Blowhole : 0 : None : 1 : False : True : Binary Napili Beach : 0 : None : 1 : False : True : Binary Wailea Beach : 0 : None : 1 : False : True : Binary Haleakala : Size=7, Index=Haleakala_index Key : Lower : Value : Upper : Fixed : Stale : Domain Black Rock Beach : 0 : None : 1 : False : True : Binary Haleakala : 0 : None : 1 : False : True : Binary Kaanapali Beach : 0 : None : 1 : False : True : Binary Kapalua Bay : 0 : None : 1 : False : True : Binary Nakalele Blowhole : 0 : None : 1 : False : True : Binary Napili Beach : 0 : None : 1 : False : True : Binary Wailea Beach : 0 : None : 1 : False : True : Binary Kaanapali : Size=7, Index=Kaanapali_index Key : Lower : Value : Upper : Fixed : Stale : Domain Black Rock Beach : 0 : None : 1 : False : True : Binary Haleakala : 0 : None : 1 : False : True : Binary Kaanapali Beach : 0 : None : 1 : False : True : Binary Kapalua Bay : 0 : None : 1 : False : True : Binary Nakalele Blowhole : 0 : None : 1 : False : True : Binary Napili Beach : 0 : None : 1 : False : True : Binary Wailea Beach : 0 : None : 1 : False : True : Binary Kapalua : Size=7, Index=Kapalua_index Key : Lower : Value : Upper : Fixed : Stale : Domain Black Rock Beach : 0 : None : 1 : False : True : Binary Haleakala : 0 : None : 1 : False : True : Binary Kaanapali Beach : 0 : None : 1 : False : True : Binary Kapalua Bay : 0 : None : 1 : False : True : Binary Nakalele Blowhole : 0 : None : 1 : False : True : Binary Napili Beach : 0 : None : 1 : False : True : Binary Wailea Beach : 0 : None : 1 : False : True : Binary Nakalele : Size=7, Index=Nakalele_index Key : Lower : Value : Upper : Fixed : Stale : Domain Black Rock Beach : 0 : None : 1 : False : True : Binary Haleakala : 0 : None : 1 : False : True : Binary Kaanapali Beach : 0 : None : 1 : False : True : Binary Kapalua Bay : 0 : None : 1 : False : True : Binary Nakalele Blowhole : 0 : None : 1 : False : True : Binary Napili Beach : 0 : None : 1 : False : True : Binary Wailea Beach : 0 : None : 1 : False : True : Binary Napili : Size=7, Index=Napili_index Key : Lower : Value : Upper : Fixed : Stale : Domain Black Rock Beach : 0 : None : 1 : False : True : Binary Haleakala : 0 : None : 1 : False : True : Binary Kaanapali Beach : 0 : None : 1 : False : True : Binary Kapalua Bay : 0 : None : 1 : False : True : Binary Nakalele Blowhole : 0 : None : 1 : False : True : Binary Napili Beach : 0 : None : 1 : False : True : Binary Wailea Beach : 0 : None : 1 : False : True : Binary Wailea : Size=7, Index=Wailea_index Key : Lower : Value : Upper : Fixed : Stale : Domain Black Rock Beach : 0 : None : 1 : False : True : Binary Haleakala : 0 : None : 1 : False : True : Binary Kaanapali Beach : 0 : None : 1 : False : True : Binary Kapalua Bay : 0 : None : 1 : False : True : Binary Nakalele Blowhole : 0 : None : 1 : False : True : Binary Napili Beach : 0 : None : 1 : False : True : Binary Wailea Beach : 0 : None : 1 : False : True : Binary 1 Objective Declarations obj : Size=1, Index=None, Active=True Key : Active : Sense : Expression None : True : minimize : 10000*Haleakala[Haleakala] + 95*Haleakala[Kaanapali Beach] + 98*Haleakala[Napili Beach] + 68*Haleakala[Wailea Beach] + 89*Haleakala[Black Rock Beach] + 118*Haleakala[Nakalele Blowhole] + 99*Haleakala[Kapalua Bay] + 92*Kaanapali[Haleakala] + 10000*Kaanapali[Kaanapali Beach] + 13*Kaanapali[Napili Beach] + 51*Kaanapali[Wailea Beach] + 4*Kaanapali[Black Rock Beach] + 33*Kaanapali[Nakalele Blowhole] + 13*Kaanapali[Kapalua Bay] + 108*Napili[Haleakala] + 21*Napili[Kaanapali Beach] + 10000*Napili[Napili Beach] + 67*Napili[Wailea Beach] + 20*Napili[Black Rock Beach] + 32*Napili[Nakalele Blowhole] + 5*Napili[Kapalua Bay] + 71*Wailea[Haleakala] + 59*Wailea[Kaanapali Beach] + 63*Wailea[Napili Beach] + 10000*Wailea[Wailea Beach] + 54*Wailea[Black Rock Beach] + 83*Wailea[Nakalele Blowhole] + 64*Wailea[Kapalua Bay] + 106*BlackRock[Haleakala] + 21*BlackRock[Kaanapali Beach] + 18*BlackRock[Napili Beach] + 57*BlackRock[Wailea Beach] + 10000*BlackRock[Black Rock Beach] + 38*BlackRock[Nakalele Blowhole] + 18*BlackRock[Kapalua Bay] + 119*Nakalele[Haleakala] + 35*Nakalele[Kaanapali Beach] + 27*Nakalele[Napili Beach] + 83*Nakalele[Wailea Beach] + 33*Nakalele[Black Rock Beach] + 10000*Nakalele[Nakalele Blowhole] + 26*Nakalele[Kapalua Bay] + 83*Kapalua[Haleakala] + 18*Kapalua[Kaanapali Beach] + 5*Kapalua[Napili Beach] + 67*Kapalua[Wailea Beach] + 17*Kapalua[Black Rock Beach] + 30*Kapalua[Nakalele Blowhole] + 10000*Kapalua[Kapalua Bay] 17 Constraint Declarations con_BlackRockCol : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Haleakala[Black Rock Beach] + Kaanapali[Black Rock Beach] + Napili[Black Rock Beach] + Wailea[Black Rock Beach] + BlackRock[Black Rock Beach] + Nakalele[Black Rock Beach] + Kapalua[Black Rock Beach] : 1.0 : True con_BlackRockRow : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : BlackRock[Haleakala] + BlackRock[Kaanapali Beach] + BlackRock[Napili Beach] + BlackRock[Wailea Beach] + BlackRock[Black Rock Beach] + BlackRock[Nakalele Blowhole] + BlackRock[Kapalua Bay] : 1.0 : True con_HaleakalaCol : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Haleakala[Haleakala] + Kaanapali[Haleakala] + Napili[Haleakala] + Wailea[Haleakala] + BlackRock[Haleakala] + Nakalele[Haleakala] + Kapalua[Haleakala] : 1.0 : True con_HaleakalaRow : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Haleakala[Haleakala] + Haleakala[Kaanapali Beach] + Haleakala[Napili Beach] + Haleakala[Wailea Beach] + Haleakala[Black Rock Beach] + Haleakala[Nakalele Blowhole] + Haleakala[Kapalua Bay] : 1.0 : True con_KaanapaliRow : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Kaanapali[Haleakala] + Kaanapali[Kaanapali Beach] + Kaanapali[Napili Beach] + Kaanapali[Wailea Beach] + Kaanapali[Black Rock Beach] + Kaanapali[Nakalele Blowhole] + Kaanapali[Kapalua Bay] : 1.0 : True con_KapaluaCol : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Haleakala[Kapalua Bay] + Kaanapali[Kapalua Bay] + Napili[Kapalua Bay] + Wailea[Kapalua Bay] + BlackRock[Kapalua Bay] + Nakalele[Kapalua Bay] + Kapalua[Kapalua Bay] : 1.0 : True con_KapaluaRow : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Kapalua[Haleakala] + Kapalua[Kaanapali Beach] + Kapalua[Napili Beach] + Kapalua[Wailea Beach] + Kapalua[Black Rock Beach] + Kapalua[Nakalele Blowhole] + Kapalua[Kapalua Bay] : 1.0 : True con_NakaleleCol : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Haleakala[Nakalele Blowhole] + Kaanapali[Nakalele Blowhole] + Napili[Nakalele Blowhole] + Wailea[Nakalele Blowhole] + BlackRock[Nakalele Blowhole] + Nakalele[Nakalele Blowhole] + Kapalua[Nakalele Blowhole] : 1.0 : True con_NakaleleRow : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Nakalele[Haleakala] + Nakalele[Kaanapali Beach] + Nakalele[Napili Beach] + Nakalele[Wailea Beach] + Nakalele[Black Rock Beach] + Nakalele[Nakalele Blowhole] + Nakalele[Kapalua Bay] : 1.0 : True con_NapiliCol : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Haleakala[Napili Beach] + Kaanapali[Napili Beach] + Napili[Napili Beach] + Wailea[Napili Beach] + BlackRock[Napili Beach] + Nakalele[Napili Beach] + Kapalua[Napili Beach] : 1.0 : True con_NapiliRow : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Napili[Haleakala] + Napili[Kaanapali Beach] + Napili[Napili Beach] + Napili[Wailea Beach] + Napili[Black Rock Beach] + Napili[Nakalele Blowhole] + Napili[Kapalua Bay] : 1.0 : True con_WaileaCol : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Haleakala[Wailea Beach] + Kaanapali[Wailea Beach] + Napili[Wailea Beach] + Wailea[Wailea Beach] + BlackRock[Wailea Beach] + Nakalele[Wailea Beach] + Kapalua[Wailea Beach] : 1.0 : True con_WaileaRow : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Wailea[Haleakala] + Wailea[Kaanapali Beach] + Wailea[Napili Beach] + Wailea[Wailea Beach] + Wailea[Black Rock Beach] + Wailea[Nakalele Blowhole] + Wailea[Kapalua Bay] : 1.0 : True con_maxDest : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : Haleakala[Haleakala] + Haleakala[Kaanapali Beach] + Haleakala[Napili Beach] + Haleakala[Wailea Beach] + Haleakala[Black Rock Beach] + Haleakala[Nakalele Blowhole] + Haleakala[Kapalua Bay] + Kaanapali[Haleakala] + Kaanapali[Kaanapali Beach] + Kaanapali[Napili Beach] + Kaanapali[Wailea Beach] + Kaanapali[Black Rock Beach] + Kaanapali[Nakalele Blowhole] + Kaanapali[Kapalua Bay] + Napili[Haleakala] + Napili[Kaanapali Beach] + Napili[Napili Beach] + Napili[Wailea Beach] + Napili[Black Rock Beach] + Napili[Nakalele Blowhole] + Napili[Kapalua Bay] + Wailea[Haleakala] + Wailea[Kaanapali Beach] + Wailea[Napili Beach] + Wailea[Wailea Beach] + Wailea[Black Rock Beach] + Wailea[Nakalele Blowhole] + Wailea[Kapalua Bay] + BlackRock[Haleakala] + BlackRock[Kaanapali Beach] + BlackRock[Napili Beach] + BlackRock[Wailea Beach] + BlackRock[Black Rock Beach] + BlackRock[Nakalele Blowhole] + BlackRock[Kapalua Bay] + Nakalele[Haleakala] + Nakalele[Kaanapali Beach] + Nakalele[Napili Beach] + Nakalele[Wailea Beach] + Nakalele[Black Rock Beach] + Nakalele[Nakalele Blowhole] + Nakalele[Kapalua Bay] + Kapalua[Haleakala] + Kapalua[Kaanapali Beach] + Kapalua[Napili Beach] + Kapalua[Wailea Beach] + Kapalua[Black Rock Beach] + Kapalua[Nakalele Blowhole] + Kapalua[Kapalua Bay] : 5.0 : True con_minDest : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : 3.0 : Haleakala[Haleakala] + Haleakala[Kaanapali Beach] + Haleakala[Napili Beach] + Haleakala[Wailea Beach] + Haleakala[Black Rock Beach] + Haleakala[Nakalele Blowhole] + Haleakala[Kapalua Bay] + Kaanapali[Haleakala] + Kaanapali[Kaanapali Beach] + Kaanapali[Napili Beach] + Kaanapali[Wailea Beach] + Kaanapali[Black Rock Beach] + Kaanapali[Nakalele Blowhole] + Kaanapali[Kapalua Bay] + Napili[Haleakala] + Napili[Kaanapali Beach] + Napili[Napili Beach] + Napili[Wailea Beach] + Napili[Black Rock Beach] + Napili[Nakalele Blowhole] + Napili[Kapalua Bay] + Wailea[Haleakala] + Wailea[Kaanapali Beach] + Wailea[Napili Beach] + Wailea[Wailea Beach] + Wailea[Black Rock Beach] + Wailea[Nakalele Blowhole] + Wailea[Kapalua Bay] + BlackRock[Haleakala] + BlackRock[Kaanapali Beach] + BlackRock[Napili Beach] + BlackRock[Wailea Beach] + BlackRock[Black Rock Beach] + BlackRock[Nakalele Blowhole] + BlackRock[Kapalua Bay] + Nakalele[Haleakala] + Nakalele[Kaanapali Beach] + Nakalele[Napili Beach] + Nakalele[Wailea Beach] + Nakalele[Black Rock Beach] + Nakalele[Nakalele Blowhole] + Nakalele[Kapalua Bay] + Kapalua[Haleakala] + Kapalua[Kaanapali Beach] + Kapalua[Napili Beach] + Kapalua[Wailea Beach] + Kapalua[Black Rock Beach] + Kapalua[Nakalele Blowhole] + Kapalua[Kapalua Bay] : +Inf : True con_time : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : -Inf : 10000*Haleakala[Haleakala] + 95*Haleakala[Kaanapali Beach] + 98*Haleakala[Napili Beach] + 68*Haleakala[Wailea Beach] + 89*Haleakala[Black Rock Beach] + 118*Haleakala[Nakalele Blowhole] + 99*Haleakala[Kapalua Bay] + 92*Kaanapali[Haleakala] + 10000*Kaanapali[Kaanapali Beach] + 13*Kaanapali[Napili Beach] + 51*Kaanapali[Wailea Beach] + 4*Kaanapali[Black Rock Beach] + 33*Kaanapali[Nakalele Blowhole] + 13*Kaanapali[Kapalua Bay] + 108*Napili[Haleakala] + 21*Napili[Kaanapali Beach] + 10000*Napili[Napili Beach] + 67*Napili[Wailea Beach] + 20*Napili[Black Rock Beach] + 32*Napili[Nakalele Blowhole] + 5*Napili[Kapalua Bay] + 71*Wailea[Haleakala] + 59*Wailea[Kaanapali Beach] + 63*Wailea[Napili Beach] + 10000*Wailea[Wailea Beach] + 54*Wailea[Black Rock Beach] + 83*Wailea[Nakalele Blowhole] + 64*Wailea[Kapalua Bay] + 106*BlackRock[Haleakala] + 21*BlackRock[Kaanapali Beach] + 18*BlackRock[Napili Beach] + 57*BlackRock[Wailea Beach] + 10000*BlackRock[Black Rock Beach] + 38*BlackRock[Nakalele Blowhole] + 18*BlackRock[Kapalua Bay] + 119*Nakalele[Haleakala] + 35*Nakalele[Kaanapali Beach] + 27*Nakalele[Napili Beach] + 83*Nakalele[Wailea Beach] + 33*Nakalele[Black Rock Beach] + 10000*Nakalele[Nakalele Blowhole] + 26*Nakalele[Kapalua Bay] + 83*Kapalua[Haleakala] + 18*Kapalua[Kaanapali Beach] + 5*Kapalua[Napili Beach] + 67*Kapalua[Wailea Beach] + 17*Kapalua[Black Rock Beach] + 30*Kapalua[Nakalele Blowhole] + 10000*Kapalua[Kapalua Bay] : 210.0 : True con_visit : Size=1, Index=None, Active=True Key : Lower : Body : Upper : Active None : 1.0 : Haleakala[Kaanapali Beach] + Kaanapali[Kaanapali Beach] + Napili[Kaanapali Beach] + Wailea[Kaanapali Beach] + BlackRock[Kaanapali Beach] + Nakalele[Kaanapali Beach] + Kapalua[Kaanapali Beach] : 1.0 : True 32 Declarations: Haleakala_index Haleakala Kaanapali_index Kaanapali Napili_index Napili Wailea_index Wailea BlackRock_index BlackRock Nakalele_index Nakalele Kapalua_index Kapalua obj con_time con_maxDest con_minDest con_visit con_HaleakalaRow con_KaanapaliRow con_NapiliRow con_WaileaRow con_BlackRockRow con_NakaleleRow con_KapaluaRow con_HaleakalaCol con_NapiliCol con_WaileaCol con_BlackRockCol con_NakaleleCol con_KapaluaCol
opt = pe.SolverFactory('glpk')
success=opt.solve(model)
print(success.solver.status,success.solver.termination_condition)
ok optimal
# get objective value and set up lists to append to in sensitivity analysis
obj_val = model.obj.expr()
print(f'optimal objective value minimum travel time = {obj_val:.2f}')
obj_num_dest = []
obj_num_dest.append(obj_val)
obj_visit_req = []
obj_visit_req.append(obj_val)
obj_list = []
obj_list.append(obj_val)
optimal objective value minimum travel time = 27.00
# print out dv results
DV_solution = pd.DataFrame()
for DV in model.component_objects(pe.Var):
for c in DV:
DV_solution.loc[DV.name,c] = DV[c].value
DV_solution
Haleakala | Kaanapali Beach | Napili Beach | Wailea Beach | Black Rock Beach | Nakalele Blowhole | Kapalua Bay | |
---|---|---|---|---|---|---|---|
Haleakala | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kaanapali | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 |
Napili | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Wailea | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
BlackRock | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Nakalele | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kapalua | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
# run model function to assist in sensitivity analysis
def run_model():
model = pe.ConcreteModel()
# define DVs
DV_indexes=['Haleakala','Kaanapali Beach','Napili Beach','Wailea Beach','Black Rock Beach', 'Nakalele Blowhole','Kapalua Bay']
model.Haleakala = pe.Var(DV_indexes, domain=pe.Binary)
model.Kaanapali = pe.Var(DV_indexes, domain=pe.Binary)
model.Napili = pe.Var(DV_indexes, domain=pe.Binary)
model.Wailea = pe.Var(DV_indexes, domain=pe.Binary)
model.BlackRock = pe.Var(DV_indexes, domain=pe.Binary)
model.Nakalele = pe.Var(DV_indexes, domain=pe.Binary)
model.Kapalua = pe.Var(DV_indexes, domain=pe.Binary)
# define objective
model.obj = pe.Objective(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes),
sense=pe.minimize)
# total travel time <= 210
model.con_time = pe.Constraint(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes)
<= rhs.loc[0,'Max'])
# total destinations <= 5
model.con_maxDest = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) +
sum(model.Kaanapali[c] for c in DV_indexes) +
sum(model.Napili[c] for c in DV_indexes) +
sum(model.Wailea[c] for c in DV_indexes) +
sum(model.BlackRock[c] for c in DV_indexes) +
sum(model.Nakalele[c] for c in DV_indexes) +
sum(model.Kapalua[c] for c in DV_indexes)
<= rhs.loc[2,'Max'])
# total destinations >= 3
model.con_minDest = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) +
sum(model.Kaanapali[c] for c in DV_indexes) +
sum(model.Napili[c] for c in DV_indexes) +
sum(model.Wailea[c] for c in DV_indexes) +
sum(model.BlackRock[c] for c in DV_indexes) +
sum(model.Nakalele[c] for c in DV_indexes) +
sum(model.Kapalua[c] for c in DV_indexes)
>= rhs.loc[1,'Max'])
# must visit Kaanapali
model.con_visit = pe.Constraint(expr=model.Haleakala['Kaanapali Beach'] +
model.Kaanapali['Kaanapali Beach'] +
model.Napili['Kaanapali Beach'] +
model.Wailea['Kaanapali Beach'] +
model.BlackRock['Kaanapali Beach'] +
model.Nakalele['Kaanapali Beach'] +
model.Kapalua['Kaanapali Beach'] == 1)
# max 1 per row
model.con_HaleakalaRow = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) <= 1)
model.con_KaanapaliRow = pe.Constraint(expr=sum(model.Kaanapali[c] for c in DV_indexes) <= 1)
model.con_NapiliRow = pe.Constraint(expr=sum(model.Napili[c] for c in DV_indexes) <= 1)
model.con_WaileaRow = pe.Constraint(expr=sum(model.Wailea[c] for c in DV_indexes) <= 1)
model.con_BlackRockRow = pe.Constraint(expr=sum(model.BlackRock[c] for c in DV_indexes) <= 1)
model.con_NakaleleRow = pe.Constraint(expr=sum(model.Nakalele[c] for c in DV_indexes) <= 1)
model.con_KapaluaRow =pe.Constraint(expr=sum(model.Kapalua[c] for c in DV_indexes) <= 1)
# max 1 per column, Kaanapali already accounted for above
model.con_HaleakalaCol = pe.Constraint(expr=model.Haleakala['Haleakala'] +
model.Kaanapali['Haleakala'] +
model.Napili['Haleakala'] +
model.Wailea['Haleakala'] +
model.BlackRock['Haleakala'] +
model.Nakalele['Haleakala'] +
model.Kapalua['Haleakala'] <= 1)
model.con_NapiliCol = pe.Constraint(expr=model.Haleakala['Napili Beach'] +
model.Kaanapali['Napili Beach'] +
model.Napili['Napili Beach'] +
model.Wailea['Napili Beach'] +
model.BlackRock['Napili Beach'] +
model.Nakalele['Napili Beach'] +
model.Kapalua['Napili Beach'] <= 1)
model.con_WaileaCol = pe.Constraint(expr=model.Haleakala['Wailea Beach'] +
model.Kaanapali['Wailea Beach'] +
model.Napili['Wailea Beach'] +
model.Wailea['Wailea Beach'] +
model.BlackRock['Wailea Beach'] +
model.Nakalele['Wailea Beach'] +
model.Kapalua['Wailea Beach'] <= 1)
model.con_BlackRockCol = pe.Constraint(expr=model.Haleakala['Black Rock Beach'] +
model.Kaanapali['Black Rock Beach'] +
model.Napili['Black Rock Beach'] +
model.Wailea['Black Rock Beach'] +
model.BlackRock['Black Rock Beach'] +
model.Nakalele['Black Rock Beach'] +
model.Kapalua['Black Rock Beach'] <= 1)
model.con_NakaleleCol = pe.Constraint(expr=model.Haleakala['Nakalele Blowhole'] +
model.Kaanapali['Nakalele Blowhole'] +
model.Napili['Nakalele Blowhole'] +
model.Wailea['Nakalele Blowhole'] +
model.BlackRock['Nakalele Blowhole'] +
model.Nakalele['Nakalele Blowhole'] +
model.Kapalua['Nakalele Blowhole'] <= 1)
model.con_KapaluaCol = pe.Constraint(expr=model.Haleakala['Kapalua Bay'] +
model.Kaanapali['Kapalua Bay'] +
model.Napili['Kapalua Bay'] +
model.Wailea['Kapalua Bay'] +
model.BlackRock['Kapalua Bay'] +
model.Nakalele['Kapalua Bay'] +
model.Kapalua['Kapalua Bay'] <= 1)
opt = pe.SolverFactory('glpk')
success=opt.solve(model,tee=False)
obj_val = model.obj.expr()
print(f'optimal objective value minimum travel time = {obj_val:.2f}')
DV_solution = pd.DataFrame()
for DV in model.component_objects(pe.Var):
for c in DV:
DV_solution.loc[DV.name,c] = DV[c].value
return model
# must visit 4 places
model = pe.ConcreteModel()
# define DVs
DV_indexes=['Haleakala','Kaanapali Beach','Napili Beach','Wailea Beach','Black Rock Beach', 'Nakalele Blowhole','Kapalua Bay']
model.Haleakala = pe.Var(DV_indexes, domain=pe.Binary)
model.Kaanapali = pe.Var(DV_indexes, domain=pe.Binary)
model.Napili = pe.Var(DV_indexes, domain=pe.Binary)
model.Wailea = pe.Var(DV_indexes, domain=pe.Binary)
model.BlackRock = pe.Var(DV_indexes, domain=pe.Binary)
model.Nakalele = pe.Var(DV_indexes, domain=pe.Binary)
model.Kapalua = pe.Var(DV_indexes, domain=pe.Binary)
# define objective
model.obj = pe.Objective(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes),
sense=pe.minimize)
# total travel time <= 210
model.con_time = pe.Constraint(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes)
<= rhs.loc[0,'Max'])
# total destinations >= 4
model.con_minDest = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) +
sum(model.Kaanapali[c] for c in DV_indexes) +
sum(model.Napili[c] for c in DV_indexes) +
sum(model.Wailea[c] for c in DV_indexes) +
sum(model.BlackRock[c] for c in DV_indexes) +
sum(model.Nakalele[c] for c in DV_indexes) +
sum(model.Kapalua[c] for c in DV_indexes)
>= rhs.loc[2,'Max'] - 1)
# must visit Kaanapali
model.con_visit = pe.Constraint(expr=model.Haleakala['Kaanapali Beach'] +
model.Kaanapali['Kaanapali Beach'] +
model.Napili['Kaanapali Beach'] +
model.Wailea['Kaanapali Beach'] +
model.BlackRock['Kaanapali Beach'] +
model.Nakalele['Kaanapali Beach'] +
model.Kapalua['Kaanapali Beach'] == 1)
# max 1 per row
model.con_HaleakalaRow = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) <= 1)
model.con_KaanapaliRow = pe.Constraint(expr=sum(model.Kaanapali[c] for c in DV_indexes) <= 1)
model.con_NapiliRow = pe.Constraint(expr=sum(model.Napili[c] for c in DV_indexes) <= 1)
model.con_WaileaRow = pe.Constraint(expr=sum(model.Wailea[c] for c in DV_indexes) <= 1)
model.con_BlackRockRow = pe.Constraint(expr=sum(model.BlackRock[c] for c in DV_indexes) <= 1)
model.con_NakaleleRow = pe.Constraint(expr=sum(model.Nakalele[c] for c in DV_indexes) <= 1)
model.con_KapaluaRow =pe.Constraint(expr=sum(model.Kapalua[c] for c in DV_indexes) <= 1)
# max 1 per column, Kaanapali already accounted for above
model.con_HaleakalaCol = pe.Constraint(expr=model.Haleakala['Haleakala'] +
model.Kaanapali['Haleakala'] +
model.Napili['Haleakala'] +
model.Wailea['Haleakala'] +
model.BlackRock['Haleakala'] +
model.Nakalele['Haleakala'] +
model.Kapalua['Haleakala'] <= 1)
model.con_NapiliCol = pe.Constraint(expr=model.Haleakala['Napili Beach'] +
model.Kaanapali['Napili Beach'] +
model.Napili['Napili Beach'] +
model.Wailea['Napili Beach'] +
model.BlackRock['Napili Beach'] +
model.Nakalele['Napili Beach'] +
model.Kapalua['Napili Beach'] <= 1)
model.con_WaileaCol = pe.Constraint(expr=model.Haleakala['Wailea Beach'] +
model.Kaanapali['Wailea Beach'] +
model.Napili['Wailea Beach'] +
model.Wailea['Wailea Beach'] +
model.BlackRock['Wailea Beach'] +
model.Nakalele['Wailea Beach'] +
model.Kapalua['Wailea Beach'] <= 1)
model.con_BlackRockCol = pe.Constraint(expr=model.Haleakala['Black Rock Beach'] +
model.Kaanapali['Black Rock Beach'] +
model.Napili['Black Rock Beach'] +
model.Wailea['Black Rock Beach'] +
model.BlackRock['Black Rock Beach'] +
model.Nakalele['Black Rock Beach'] +
model.Kapalua['Black Rock Beach'] <= 1)
model.con_NakaleleCol = pe.Constraint(expr=model.Haleakala['Nakalele Blowhole'] +
model.Kaanapali['Nakalele Blowhole'] +
model.Napili['Nakalele Blowhole'] +
model.Wailea['Nakalele Blowhole'] +
model.BlackRock['Nakalele Blowhole'] +
model.Nakalele['Nakalele Blowhole'] +
model.Kapalua['Nakalele Blowhole'] <= 1)
model.con_KapaluaCol = pe.Constraint(expr=model.Haleakala['Kapalua Bay'] +
model.Kaanapali['Kapalua Bay'] +
model.Napili['Kapalua Bay'] +
model.Wailea['Kapalua Bay'] +
model.BlackRock['Kapalua Bay'] +
model.Nakalele['Kapalua Bay'] +
model.Kapalua['Kapalua Bay'] <= 1)
#solve and output
opt = pe.SolverFactory('glpk')
success=opt.solve(model,tee=False)
obj_val = model.obj.expr()
print(f'optimal objective value minimum travel time = {obj_val:.2f}')
DV_solution_4 = pd.DataFrame()
for DV in model.component_objects(pe.Var):
for c in DV:
DV_solution_4.loc[DV.name,c] = DV[c].value
DV_solution_4
obj_num_dest.append(obj_val)
optimal objective value minimum travel time = 35.00
# must visit 5 places
model = pe.ConcreteModel()
# define DVs
DV_indexes=['Haleakala','Kaanapali Beach','Napili Beach','Wailea Beach','Black Rock Beach', 'Nakalele Blowhole','Kapalua Bay']
model.Haleakala = pe.Var(DV_indexes, domain=pe.Binary)
model.Kaanapali = pe.Var(DV_indexes, domain=pe.Binary)
model.Napili = pe.Var(DV_indexes, domain=pe.Binary)
model.Wailea = pe.Var(DV_indexes, domain=pe.Binary)
model.BlackRock = pe.Var(DV_indexes, domain=pe.Binary)
model.Nakalele = pe.Var(DV_indexes, domain=pe.Binary)
model.Kapalua = pe.Var(DV_indexes, domain=pe.Binary)
# define objective
model.obj = pe.Objective(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes),
sense=pe.minimize)
# total travel time <= 210
model.con_time = pe.Constraint(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes)
<= rhs.loc[0,'Max'])
# total destinations >= 4
model.con_minDest = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) +
sum(model.Kaanapali[c] for c in DV_indexes) +
sum(model.Napili[c] for c in DV_indexes) +
sum(model.Wailea[c] for c in DV_indexes) +
sum(model.BlackRock[c] for c in DV_indexes) +
sum(model.Nakalele[c] for c in DV_indexes) +
sum(model.Kapalua[c] for c in DV_indexes)
>= rhs.loc[2,'Max'])
# must visit Kaanapali
model.con_visit = pe.Constraint(expr=model.Haleakala['Kaanapali Beach'] +
model.Kaanapali['Kaanapali Beach'] +
model.Napili['Kaanapali Beach'] +
model.Wailea['Kaanapali Beach'] +
model.BlackRock['Kaanapali Beach'] +
model.Nakalele['Kaanapali Beach'] +
model.Kapalua['Kaanapali Beach'] == 1)
# max 1 per row
model.con_HaleakalaRow = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) <= 1)
model.con_KaanapaliRow = pe.Constraint(expr=sum(model.Kaanapali[c] for c in DV_indexes) <= 1)
model.con_NapiliRow = pe.Constraint(expr=sum(model.Napili[c] for c in DV_indexes) <= 1)
model.con_WaileaRow = pe.Constraint(expr=sum(model.Wailea[c] for c in DV_indexes) <= 1)
model.con_BlackRockRow = pe.Constraint(expr=sum(model.BlackRock[c] for c in DV_indexes) <= 1)
model.con_NakaleleRow = pe.Constraint(expr=sum(model.Nakalele[c] for c in DV_indexes) <= 1)
model.con_KapaluaRow =pe.Constraint(expr=sum(model.Kapalua[c] for c in DV_indexes) <= 1)
# max 1 per column, Kaanapali already accounted for above
model.con_HaleakalaCol = pe.Constraint(expr=model.Haleakala['Haleakala'] +
model.Kaanapali['Haleakala'] +
model.Napili['Haleakala'] +
model.Wailea['Haleakala'] +
model.BlackRock['Haleakala'] +
model.Nakalele['Haleakala'] +
model.Kapalua['Haleakala'] <= 1)
model.con_NapiliCol = pe.Constraint(expr=model.Haleakala['Napili Beach'] +
model.Kaanapali['Napili Beach'] +
model.Napili['Napili Beach'] +
model.Wailea['Napili Beach'] +
model.BlackRock['Napili Beach'] +
model.Nakalele['Napili Beach'] +
model.Kapalua['Napili Beach'] <= 1)
model.con_WaileaCol = pe.Constraint(expr=model.Haleakala['Wailea Beach'] +
model.Kaanapali['Wailea Beach'] +
model.Napili['Wailea Beach'] +
model.Wailea['Wailea Beach'] +
model.BlackRock['Wailea Beach'] +
model.Nakalele['Wailea Beach'] +
model.Kapalua['Wailea Beach'] <= 1)
model.con_BlackRockCol = pe.Constraint(expr=model.Haleakala['Black Rock Beach'] +
model.Kaanapali['Black Rock Beach'] +
model.Napili['Black Rock Beach'] +
model.Wailea['Black Rock Beach'] +
model.BlackRock['Black Rock Beach'] +
model.Nakalele['Black Rock Beach'] +
model.Kapalua['Black Rock Beach'] <= 1)
model.con_NakaleleCol = pe.Constraint(expr=model.Haleakala['Nakalele Blowhole'] +
model.Kaanapali['Nakalele Blowhole'] +
model.Napili['Nakalele Blowhole'] +
model.Wailea['Nakalele Blowhole'] +
model.BlackRock['Nakalele Blowhole'] +
model.Nakalele['Nakalele Blowhole'] +
model.Kapalua['Nakalele Blowhole'] <= 1)
model.con_KapaluaCol = pe.Constraint(expr=model.Haleakala['Kapalua Bay'] +
model.Kaanapali['Kapalua Bay'] +
model.Napili['Kapalua Bay'] +
model.Wailea['Kapalua Bay'] +
model.BlackRock['Kapalua Bay'] +
model.Nakalele['Kapalua Bay'] +
model.Kapalua['Kapalua Bay'] <= 1)
#solve and output
opt = pe.SolverFactory('glpk')
success=opt.solve(model,tee=False)
obj_val = model.obj.expr()
print(f'optimal objective value minimum travel time = {obj_val:.2f}')
DV_solution_5 = pd.DataFrame()
for DV in model.component_objects(pe.Var):
for c in DV:
DV_solution_5.loc[DV.name,c] = DV[c].value
DV_solution_5
obj_num_dest.append(obj_val)
optimal objective value minimum travel time = 87.00
model = pe.ConcreteModel()
# define DVs
DV_indexes=['Haleakala','Kaanapali Beach','Napili Beach','Wailea Beach','Black Rock Beach', 'Nakalele Blowhole','Kapalua Bay']
model.Haleakala = pe.Var(DV_indexes, domain=pe.Binary)
model.Kaanapali = pe.Var(DV_indexes, domain=pe.Binary)
model.Napili = pe.Var(DV_indexes, domain=pe.Binary)
model.Wailea = pe.Var(DV_indexes, domain=pe.Binary)
model.BlackRock = pe.Var(DV_indexes, domain=pe.Binary)
model.Nakalele = pe.Var(DV_indexes, domain=pe.Binary)
model.Kapalua = pe.Var(DV_indexes, domain=pe.Binary)
# define objective
model.obj = pe.Objective(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes),
sense=pe.minimize)
# total travel time <= 210
model.con_time = pe.Constraint(expr=sum(coef.loc['Haleakala',c]*model.Haleakala[c] for c in DV_indexes) +
sum(coef.loc['Kaanapali Beach',c]*model.Kaanapali[c] for c in DV_indexes) +
sum(coef.loc['Napili Beach',c]*model.Napili[c] for c in DV_indexes) +
sum(coef.loc['Wailea Beach',c]*model.Wailea[c] for c in DV_indexes) +
sum(coef.loc['Black Rock Beach',c]*model.BlackRock[c] for c in DV_indexes) +
sum(coef.loc['Nakalele Blowhole',c]*model.Nakalele[c] for c in DV_indexes) +
sum(coef.loc['Kapalua Bay',c]*model.Kapalua[c] for c in DV_indexes)
<= rhs.loc[0,'Max'])
# total destinations >= 4
model.con_minDest = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) +
sum(model.Kaanapali[c] for c in DV_indexes) +
sum(model.Napili[c] for c in DV_indexes) +
sum(model.Wailea[c] for c in DV_indexes) +
sum(model.BlackRock[c] for c in DV_indexes) +
sum(model.Nakalele[c] for c in DV_indexes) +
sum(model.Kapalua[c] for c in DV_indexes)
>= rhs.loc[2,'Max'] - 2)
# must visit Kaanapali -- changed to <=
model.con_visit = pe.Constraint(expr=model.Haleakala['Kaanapali Beach'] +
model.Kaanapali['Kaanapali Beach'] +
model.Napili['Kaanapali Beach'] +
model.Wailea['Kaanapali Beach'] +
model.BlackRock['Kaanapali Beach'] +
model.Nakalele['Kaanapali Beach'] +
model.Kapalua['Kaanapali Beach'] <= 1)
# max 1 per row
model.con_HaleakalaRow = pe.Constraint(expr=sum(model.Haleakala[c] for c in DV_indexes) <= 1)
model.con_KaanapaliRow = pe.Constraint(expr=sum(model.Kaanapali[c] for c in DV_indexes) <= 1)
model.con_NapiliRow = pe.Constraint(expr=sum(model.Napili[c] for c in DV_indexes) <= 1)
model.con_WaileaRow = pe.Constraint(expr=sum(model.Wailea[c] for c in DV_indexes) <= 1)
model.con_BlackRockRow = pe.Constraint(expr=sum(model.BlackRock[c] for c in DV_indexes) <= 1)
model.con_NakaleleRow = pe.Constraint(expr=sum(model.Nakalele[c] for c in DV_indexes) <= 1)
model.con_KapaluaRow =pe.Constraint(expr=sum(model.Kapalua[c] for c in DV_indexes) <= 1)
# max 1 per column, Kaanapali already accounted for above
model.con_HaleakalaCol = pe.Constraint(expr=model.Haleakala['Haleakala'] +
model.Kaanapali['Haleakala'] +
model.Napili['Haleakala'] +
model.Wailea['Haleakala'] +
model.BlackRock['Haleakala'] +
model.Nakalele['Haleakala'] +
model.Kapalua['Haleakala'] <= 1)
model.con_NapiliCol = pe.Constraint(expr=model.Haleakala['Napili Beach'] +
model.Kaanapali['Napili Beach'] +
model.Napili['Napili Beach'] +
model.Wailea['Napili Beach'] +
model.BlackRock['Napili Beach'] +
model.Nakalele['Napili Beach'] +
model.Kapalua['Napili Beach'] <= 1)
model.con_WaileaCol = pe.Constraint(expr=model.Haleakala['Wailea Beach'] +
model.Kaanapali['Wailea Beach'] +
model.Napili['Wailea Beach'] +
model.Wailea['Wailea Beach'] +
model.BlackRock['Wailea Beach'] +
model.Nakalele['Wailea Beach'] +
model.Kapalua['Wailea Beach'] <= 1)
model.con_BlackRockCol = pe.Constraint(expr=model.Haleakala['Black Rock Beach'] +
model.Kaanapali['Black Rock Beach'] +
model.Napili['Black Rock Beach'] +
model.Wailea['Black Rock Beach'] +
model.BlackRock['Black Rock Beach'] +
model.Nakalele['Black Rock Beach'] +
model.Kapalua['Black Rock Beach'] <= 1)
model.con_NakaleleCol = pe.Constraint(expr=model.Haleakala['Nakalele Blowhole'] +
model.Kaanapali['Nakalele Blowhole'] +
model.Napili['Nakalele Blowhole'] +
model.Wailea['Nakalele Blowhole'] +
model.BlackRock['Nakalele Blowhole'] +
model.Nakalele['Nakalele Blowhole'] +
model.Kapalua['Nakalele Blowhole'] <= 1)
model.con_KapaluaCol = pe.Constraint(expr=model.Haleakala['Kapalua Bay'] +
model.Kaanapali['Kapalua Bay'] +
model.Napili['Kapalua Bay'] +
model.Wailea['Kapalua Bay'] +
model.BlackRock['Kapalua Bay'] +
model.Nakalele['Kapalua Bay'] +
model.Kapalua['Kapalua Bay'] <= 1)
#solve and output
opt = pe.SolverFactory('glpk')
success=opt.solve(model,tee=False)
obj_val = model.obj.expr()
print(f'optimal objective value minimum travel time = {obj_val:.2f}')
DV_solution_noVisit = pd.DataFrame()
for DV in model.component_objects(pe.Var):
for c in DV:
DV_solution_noVisit.loc[DV.name,c] = DV[c].value
DV_solution_noVisit
obj_visit_req.append(obj_val)
optimal objective value minimum travel time = 14.00
[27.0, 14.0]
# increase travel time
time_icr = [1,1,1,1,1,1,1,1,1,1]
coef = pd.read_excel('INFO 3440 Project Data.xlsx', sheet_name='Coef', index_col=0)
rhs = pd.read_excel('INFO 3440 Project Data.xlsx', sheet_name='Constraints')
obj_list = []
for n in time_icr:
for i in coef:
for j in coef:
coef.loc[i,j] = coef.loc[i,j] + n
model = run_model()
obj_list.append(model.obj.expr())
time_obj = pd.DataFrame(obj_list,index=range(1,len(obj_list)+1))
time_obj
optimal objective value minimum travel time = 30.00 optimal objective value minimum travel time = 33.00 optimal objective value minimum travel time = 36.00 optimal objective value minimum travel time = 39.00 optimal objective value minimum travel time = 42.00 optimal objective value minimum travel time = 45.00 optimal objective value minimum travel time = 48.00 optimal objective value minimum travel time = 51.00 optimal objective value minimum travel time = 54.00 optimal objective value minimum travel time = 57.00
0 | |
---|---|
1 | 30.0 |
2 | 33.0 |
3 | 36.0 |
4 | 39.0 |
5 | 42.0 |
6 | 45.0 |
7 | 48.0 |
8 | 51.0 |
9 | 54.0 |
10 | 57.0 |
dest_obj = pd.DataFrame(obj_num_dest,index=[3,4,5])
dest_obj
0 | |
---|---|
3 | 27.0 |
4 | 35.0 |
5 | 87.0 |
dest_obj.plot(kind='line',legend=None)
plt.title('Effect of Changing Minimum Destinations on Minimum Travel Time')
plt.show()
col_names = DV_indexes.copy()
i = 3
for j in range(0,len(col_names)):
col_names[j] = col_names[j] + ' ' + str(i)
col_names
['Haleakala 3', 'Kaanapali Beach 3', 'Napili Beach 3', 'Wailea Beach 3', 'Black Rock Beach 3', 'Nakalele Blowhole 3', 'Kapalua Bay 3']
DV_solution
Haleakala | Kaanapali Beach | Napili Beach | Wailea Beach | Black Rock Beach | Nakalele Blowhole | Kapalua Bay | |
---|---|---|---|---|---|---|---|
Haleakala | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kaanapali | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 |
Napili | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Wailea | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
BlackRock | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Nakalele | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kapalua | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
col_names = DV_indexes.copy()
i = 4
for j in range(0,len(col_names)):
col_names[j] = col_names[j] + ' ' + str(i)
col_names
['Haleakala 4', 'Kaanapali Beach 4', 'Napili Beach 4', 'Wailea Beach 4', 'Black Rock Beach 4', 'Nakalele Blowhole 4', 'Kapalua Bay 4']
DV_solution_4['new index'] = col_names
DV_solution_4.set_index('new index',inplace=True)
DV_solution_4
Haleakala | Kaanapali Beach | Napili Beach | Wailea Beach | Black Rock Beach | Nakalele Blowhole | Kapalua Bay | |
---|---|---|---|---|---|---|---|
new index | |||||||
Haleakala 4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kaanapali Beach 4 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 |
Napili Beach 4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Wailea Beach 4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Black Rock Beach 4 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Nakalele Blowhole 4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kapalua Bay 4 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
DV_solution_5
Haleakala | Kaanapali Beach | Napili Beach | Wailea Beach | Black Rock Beach | Nakalele Blowhole | Kapalua Bay | |
---|---|---|---|---|---|---|---|
Haleakala | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kaanapali | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 |
Napili | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Wailea | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
BlackRock | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 |
Nakalele | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kapalua | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
col_names = DV_indexes.copy()
i = 5
for j in range(0,len(col_names)):
col_names[j] = col_names[j] + ' ' + str(i)
col_names
['Haleakala 5', 'Kaanapali Beach 5', 'Napili Beach 5', 'Wailea Beach 5', 'Black Rock Beach 5', 'Nakalele Blowhole 5', 'Kapalua Bay 5']
DV_solution_5['new index'] = col_names
DV_solution_5.set_index('new index',inplace=True)
DV_solution_5
Haleakala | Kaanapali Beach | Napili Beach | Wailea Beach | Black Rock Beach | Nakalele Blowhole | Kapalua Bay | |
---|---|---|---|---|---|---|---|
new index | |||||||
Haleakala 5 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kaanapali Beach 5 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 |
Napili Beach 5 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Wailea Beach 5 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Black Rock Beach 5 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 |
Nakalele Blowhole 5 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Kapalua Bay 5 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 |
plt.figure(figsize=(12,7))
plt.plot(DV_solution)
plt.title('Effect of Increasing Num Destinations on Optimal Solution: Original 3 Locations')
plt.show()
plt.figure(figsize=(12,7))
plt.title('Effect of Increasing Num Destinations on Optimal Solution: 4 Locations')
plt.plot(DV_solution_4)
plt.show()
plt.figure(figsize=(12,7))
plt.title('Effect of Increasing Num Destinations on Optimal Solution: 5 Locations')
plt.plot(DV_solution_5)
plt.show()
noVisit_obj = pd.DataFrame(obj_visit_req,index=['Yes','No'])
noVisit_obj['req']=[True,False]
noVisit_obj
0 | req | |
---|---|---|
Yes | 27.0 | True |
No | 14.0 | False |
#noVisit_obj.plot(kind='line',legend=None)
plt.figure(figsize=(6,4))
plt.plot(noVisit_obj['req'])
plt.title('Effect of Not Visiting Kaanapali on Minimum Travel Time')
plt.show()
time_obj.plot(kind='line',legend=None)
plt.title('Effect of Increasing Travel Time on Minimum Total Time')
plt.show()
With the original constraints, the minimum travel time satisfying the requirements (3-5 locations, must visit Kaanapali, can't visit more than once, and travel less than 210 minutes) is 27 minutes. The traveler will be traveling from Kaanapali Beach to Black Rock Beach, from Napili to Kapalua Bay, and from Kapalua to Kaanapali Beach.
By changing the required amount of locations to 4, the optimal minimum travel time is 35 minutes. The traveler will travel from Kaanapali Beach to Black Rock Beach, Napili Beach to Kapalua Bay, Black Rock Beach to Kaanapali Beach, and Kapalua Bay to Napili Beach.
By changing the required amount of locations to 5, the optimal minimum travel time is 87 minutes. The traveler will travel from Kaanapali Beach to Black Rock Beach, from Napili Beach to Kapalua Bay, from Black Rock Beach to Nakalele Blowhole, from Nakalele Blowhole to Kaanapali Beach, and from Kapalua Bay to Napili Beach.
If the traveler doesn't absolutely have to go to Kaanapali Beach, the optimal minimum travel time is 14 minutes. The traveler will travel from Kaanapali to Black Rock Beach, from Napili to Kapalua Bay, and from Kapalua Bay to Napili Beach.
Each increase in 1 minute travel time for all coefficents led to a 3 minute increase in the objective function, minimum travel time. All other factors equal, the relationship is linear and didn't have a big impact on the optimal mix.
Looking at the original solution, the traveler should start at Napili Beach and travel to Kapalua Bay, then travel from Kapalua Bay to Kaanapali Beach, and finally from Kaanapali Beach to Black Rock Beach. The three pairs chosen sequence together well, so this will absolutely lead to the minimal time. The traveler should have plenty of extra time to spend exploring the destinations since this amount of time is well below the traveler's maximum desired travel time.
With the 4 locations, the traveler should travel from Kaanapali Beach to Black Rock Beach and from Black Rock Beach back to Kaanapali Beach. The traveler should also travel from Napili Beach to Kapalua Bay and from Kapalua Bay back to Napili Beach. Due to the limitations of this model, this solution doesn't make a whole lot of sense for the traveler to use if they want to actually hit 4 locations with no duplications and thus circular routes. The increase in time between this solution and going to 3 destinations is only 8 minutes, so it's not adding a lot of time, though the discontinuity between the pairs means extra time that is not accounted for in the model would be tacked on in order to get to some destinations.
With visiting 5 locations, the traveler should travel from Black Rock to Nakalele Blowhole, then from Nakalele Blowhole to Kaanapali Beach. From Kaanapali Beach the traveler should travel back to Black Rock Beach. The traveler can complete his desire to reach 5 locations by going from Napili Beach to Kapalua Bay and back to Napili Beach from Kapalua Bay. The first three destinations make logical sense to sequence, however the second two provide duplication of pairs and incontinuity, so the minimum travel time given by the model will likely not hold up in this situation should the traveler choose it. This solution also adds a lot to the minimum travel time without the limitations of the model, so the opportunity cost is a lot higher than it is going from 3 locations to 4 locations.
Without visiting Kaanapali, the minimum travel time is cut roughly in half. There is again a discontinuity in the locations provided, as well as the traveler going from Napili to Kapalua Bay and from Kapalua Bay back to Napili. Despite the drastic decrease in time, this solution doesn't seem as feasible, especially considering the time added on to get between Black Rock Beach and Napili/Kapalua. Granted, eliminating the circular routes in each of the scenarios and visiting both without going back to the starting point will lead to a decrease, the time added will lead to a less mathematically optimal model. How much this could be is unclear and would need to be further explored.
The biggest challenge for me was that the original idea I had for this project was way too complex for the scope of this class--that is I wanted to sequence them together, and that was simply beyond the scope of this class and what we have learned in pyomo. Initially I thought I could do this sort of like a transshipment model and use balance equations, but as I thought it through I realized that was not going to work how I originally thought. The limitations of this model are that it is in a sense a simplified version. Given more time and more advanced knowledge, I would ideally perform a model that would sequence the locations, much like a tool like the evolutionary solver would do in Excel. This would eliminate the duplication of pairs that led to circular routes in some of the sensitivity analysis optimal solutions, and it would lead to less manual construction of the routes. When analyzing the model as it is now, I took the pairs and sequenced them myself, whereas it would be good if the model did that for me. With more time and work on this model, it would ideally be retooled to be able to sequence the route and eliminate the circular travel pairs. I also might do an analysis of the constraints and see if I could add a constraint that would at least eliminate the circular pairs, if developing a full sequencing model was not possible.