Working with Data Files

Originally Contributed by: Arpit Bhatia

In many cases we might need to read data available in an external file rather than type it into Julia ourselves.

This tutorial is concerned with reading tabular data into Julia and using it for a JuMP model.

We'll be reading data using the DataFrames.jl package and some other packages specific to file types.

The data are stored in the /docs/src/tutorials/Getting started/data directory of the JuMP source code.

const DATA_DIR = joinpath(@__DIR__, "data");
Note

There are multiple ways to read the same kind of data into Julia. This tutorial focuses on DataFrames.jl because it provides the ecosystem to work with most of the required file types in a straightforward manner.

DataFrames.jl

The DataFrames package provides a set of tools for working with tabular data. It is available through the Julia package system.

using Pkg
Pkg.add("DataFrames")
import DataFrames

What is a DataFrame?

A DataFrame is a data structure like a table or spreadsheet. You can use it for storing and exploring a set of related data values. Think of it as a smarter array for holding tabular data.

Reading Tabular Data into a DataFrame

We will begin by reading data from different file formats into a DataFrame object.

Excel Sheets

Excel files can be read using the XLSX.jl package.

Pkg.add("XLSX")
import XLSX

To read a Excel file into a DataFrame, we use the following julia code. The first argument to the readtable function is the file to be read and the second argument is the name of the sheet.

excel_df = DataFrames.DataFrame(
    XLSX.readtable(joinpath(DATA_DIR, "SalesData.xlsx"), "SalesOrders")...
)

18 rows × 7 columns

OrderDateRegionRepItemUnitsUnit CostTotal
AnyAnyAnyAnyAnyAnyAny
12018-01-06EastJonesPencil951.99189.05
22018-01-23CentralKivellBinder5019.99999.5
32018-02-09CentralJardinePencil364.99179.64
42018-02-26CentralGillPen2719.99539.73
52018-03-15WestSorvinoPencil562.99167.44
62018-06-08EastJonesBinder608.99539.4
72018-06-25CentralMorganPencil904.99449.1
82018-07-12EastHowardBinder291.9957.71
92019-07-21CentralMorganPen Set5512.49686.95
102019-08-07CentralKivellPen Set4223.951005.9
112019-08-24WestSorvinoDesk3275.0825.0
122019-09-10CentralGillPencil71.299.03
132019-09-27WestSorvinoPen761.99151.24
142019-10-14WestThompsonBinder5719.991139.43
152019-10-31CentralAndrewsPencil141.2918.06
162019-11-17CentralJardineBinder114.9954.89
172019-12-04CentralJardineBinder9419.991879.06
182019-12-21CentralAndrewsBinder284.99139.72

CSV files

CSV and other delimited text files can be read by the CSV.jl package.

Pkg.add("CSV")
import CSV

To read a CSV file into a DataFrame, we use the CSV.read function.

csv_df = CSV.read(joinpath(DATA_DIR, "StarWars.csv"), DataFrames.DataFrame)

20 rows × 13 columns

NameGenderHeightWeightEyecolorHaircolorSkincolorHomelandBornDiedJediSpeciesWeapon
StringStringFloat64StringStringStringStringStringStringStringStringStringString
1Anakin Skywalkermale1.8884blueblondfairTatooine41.9BBY4ABYjedihumanlightsaber
2Padme Amidalafemale1.6545brownbrownlightNaboo46BBY19BBYno_jedihumanunarmed
3Luke Skywalkermale1.7277blueblondfairTatooine19BBYunk_diedjedihumanlightsaber
4Leia Skywalkerfemale1.549brownbrownlightAlderaan19BBYunk_diedno_jedihumanblaster
5Qui-Gon Jinnmale1.9388.5bluebrownlightunk_planet92BBY32BBYjedihumanlightsaber
6Obi-Wan Kenobimale1.8277bluegrayauburnfairStewjon57BBY0BBYjedihumanlightsaber
7Han Solomale1.880brownbrownlightCorellia29BBYunk_diedno_jedihumanblaster
8Sheev Palpatinemale1.7375blueredpaleNaboo82BBY10ABYno_jedihumanforce-lightning
9R2-D2male0.9632NANANANaboo33BBYunk_diedno_jedidroidunarmed
10C-3POmale1.6775NANANATatooine112BBY3ABYno_jedidroidunarmed
11Yodamale0.6617brownbrowngreenunk_planet896BBY4ABYjediyodalightsaber
12Darth Maulmale1.7580yellownoneredDathomir54BBYunk_diedno_jedidathomirianlightsaber
13Dookumale1.9386brownbrownlightSerenno102BBY19BBYjedihumanlightsaber
14Chewbaccamale2.28112bluebrownNAKashyyyk200BBY25ABYno_jediwookieebowcaster
15Jabbamale3.9NAyellownonetan-greenTatooineunk_born4ABYno_jedihuttunarmed
16Lando Calrissianmale1.7879brownblankdarkSocorro31BBYunk_diedno_jedihumanblaster
17Boba Fettmale1.8378brownblackbrownKamino31.5BBYunk_diedno_jedihumanblaster
18Jango Fettmale1.8379brownblackbrownConcordDawn66BBY22BBYno_jedihumanblaster
19Grievousmale2.16159goldblackorangeKaleeunk_born19BBYno_jedikaleeshslugthrower
20Chief Chirpamale1.050blackgraybrownEndorunk_born4ABYno_jediewokspear

Other Delimited Files

We can also use the CSV.jl package to read any other delimited text file format.

By default, CSV.File will try to detect a file's delimiter from the first 10 lines of the file.

Candidate delimiters include ',', '\t', ' ', '|', ';', and ':'. If it can't auto-detect the delimiter, it will assume ','.

Let's take the example of space separated data.

ss_df = CSV.read(joinpath(DATA_DIR, "Cereal.txt"), DataFrames.DataFrame)

23 rows × 10 columns

NameCupsCaloriesCarbsFatFiberPotassiumProteinSodiumSugars
StringFloat64Int64Float64Int64Float64Int64Int64Int64Int64
1CapnCrunch0.7512012.020.035122012
2CocoaPuffs1.011012.010.055118013
3Trix1.011013.010.025114012
4AppleJacks1.011011.001.030212514
5CornChex1.011022.000.02522803
6CornFlakes1.010021.001.03522902
7Nut&Honey0.6712015.010.04021909
8Smacks0.751109.011.04027015
9MultiGrain1.010015.012.09022206
10CracklinOat0.511010.034.016031407
11GrapeNuts0.2511017.003.09031793
12HoneyNutCheerios0.7511011.511.590325010
13NutriGrain0.6714021.023.013032207
14Product191.010020.001.04533203
15TotalRaisinBran1.014015.014.0230319014
16WheatChex0.6710017.013.011532303
17Oatmeal0.513013.521.5120317010
18Life0.6710012.022.09541506
19Maypo1.010016.010.095403
20QuakerOats0.510014.012.011041356
21Muesli1.015016.033.0170415011
22Cheerios1.2511017.022.010562901
23SpecialK1.011016.001.05562303

We can also specify the delimiter by passing the delim argument.

delim_df = CSV.read(
    joinpath(DATA_DIR, "Soccer.txt"), DataFrames.DataFrame, delim = "::"
)

20 rows × 7 columns

TeamPlayedWinsDrawsLossesGoals_forGoals_against
StringInt64Int64Int64Int64StringString
1Barcelona383044110 goals21 goals
2Real Madrid383026118 goals38 goals
3Atletico Madrid38239667 goals29 goals
4Valencia382211570 goals32 goals
5Seville38237871 goals45 goals
6Villarreal3816121048 goals37 goals
7Athletic Bilbao3815101342 goals41 goals
8Celta Vigo3813121347 goals44 goals
9Malaga381481642 goals48 goals
10Espanyol3813101547 goals51 goals
11Rayo Vallecano381541946 goals68 goals
12Real Sociedad3811131444 goals51 goals
13Elche381181935 goals62 goals
14Levante389101934 goals67 goals
15Getafe381072133 goals64 goals
16Deportivo La Coruna387141735 goals60 goals
17Granada387141729 goals64 goals
18Eibar38982134 goals55 goals
19Almeria38882235 goals64 goals
20Cordoba383112422 goals68 goals

Note that by default, are read-only. If we wish to make changes to the data read, we pass the copycols = true argument in the function call.

ss_df = CSV.read(
    joinpath(DATA_DIR, "Cereal.txt"), DataFrames.DataFrame, copycols = true
)

23 rows × 10 columns

NameCupsCaloriesCarbsFatFiberPotassiumProteinSodiumSugars
StringFloat64Int64Float64Int64Float64Int64Int64Int64Int64
1CapnCrunch0.7512012.020.035122012
2CocoaPuffs1.011012.010.055118013
3Trix1.011013.010.025114012
4AppleJacks1.011011.001.030212514
5CornChex1.011022.000.02522803
6CornFlakes1.010021.001.03522902
7Nut&Honey0.6712015.010.04021909
8Smacks0.751109.011.04027015
9MultiGrain1.010015.012.09022206
10CracklinOat0.511010.034.016031407
11GrapeNuts0.2511017.003.09031793
12HoneyNutCheerios0.7511011.511.590325010
13NutriGrain0.6714021.023.013032207
14Product191.010020.001.04533203
15TotalRaisinBran1.014015.014.0230319014
16WheatChex0.6710017.013.011532303
17Oatmeal0.513013.521.5120317010
18Life0.6710012.022.09541506
19Maypo1.010016.010.095403
20QuakerOats0.510014.012.011041356
21Muesli1.015016.033.0170415011
22Cheerios1.2511017.022.010562901
23SpecialK1.011016.001.05562303

Working with DataFrames

Now that we have read the required data into a DataFrame, let us look at some basic operations we can perform on it.

Querying Basic Information

The size function gets us the dimensions of the DataFrame.

DataFrames.size(ss_df)
(23, 10)

We can also us the nrow and ncol functions to get the number of rows and columns respectively.

DataFrames.nrow(ss_df), DataFrames.ncol(ss_df)
(23, 10)

The describe function gives basic summary statistics of data in a DataFrame.

DataFrames.describe(ss_df)

10 rows × 7 columns

variablemeanminmedianmaxnmissingeltype
SymbolUnion…AnyUnion…AnyInt64DataType
1NameAppleJacksWheatChex0String
2Cups0.8230430.251.01.250Float64
3Calories113.043100110.01500Int64
4Carbs15.04359.015.022.00Float64
5Fat1.1304301.030Int64
6Fiber1.565220.01.54.00Float64
7Potassium86.30432590.02300Int64
8Protein2.9130413.060Int64
9Sodium189.9570190.03200Int64
10Sugars7.5217417.0150Int64

Names of every column can be obtained by the names function.

DataFrames.names(ss_df)
10-element Array{String,1}:
 "Name"     
 "Cups"     
 "Calories" 
 "Carbs"    
 "Fat"      
 "Fiber"    
 "Potassium"
 "Protein"  
 "Sodium"   
 "Sugars"   

Corresponding data types are obtained using the broadcasted eltype function.

eltype.(ss_df)

23 rows × 10 columns

NameCupsCaloriesCarbsFatFiberPotassiumProteinSodiumSugars
DataTypeDataTypeDataTypeDataTypeDataTypeDataTypeDataTypeDataTypeDataTypeDataType
1CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
2CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
3CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
4CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
5CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
6CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
7CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
8CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
9CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
10CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
11CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
12CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
13CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
14CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
15CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
16CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
17CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
18CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
19CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
20CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
21CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
22CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64
23CharFloat64Int64Float64Int64Float64Int64Int64Int64Int64

Accessing the Data

Similar to regular arrays, we use numerical indexing to access elements of a DataFrame.

csv_df[1, 1]
"Anakin Skywalker"

The following are different ways to access a column.

csv_df[!, 1]
20-element Array{String,1}:
 "Anakin Skywalker"
 "Padme Amidala"   
 "Luke Skywalker"  
 "Leia Skywalker"  
 "Qui-Gon Jinn"    
 "Obi-Wan Kenobi"  
 "Han Solo"        
 "Sheev Palpatine" 
 "R2-D2"           
 "C-3PO"           
 "Yoda"            
 "Darth Maul"      
 "Dooku"           
 "Chewbacca"       
 "Jabba"           
 "Lando Calrissian"
 "Boba Fett"       
 "Jango Fett"      
 "Grievous"        
 "Chief Chirpa"    
csv_df[!, :Name]
20-element Array{String,1}:
 "Anakin Skywalker"
 "Padme Amidala"   
 "Luke Skywalker"  
 "Leia Skywalker"  
 "Qui-Gon Jinn"    
 "Obi-Wan Kenobi"  
 "Han Solo"        
 "Sheev Palpatine" 
 "R2-D2"           
 "C-3PO"           
 "Yoda"            
 "Darth Maul"      
 "Dooku"           
 "Chewbacca"       
 "Jabba"           
 "Lando Calrissian"
 "Boba Fett"       
 "Jango Fett"      
 "Grievous"        
 "Chief Chirpa"    
csv_df.Name
20-element Array{String,1}:
 "Anakin Skywalker"
 "Padme Amidala"   
 "Luke Skywalker"  
 "Leia Skywalker"  
 "Qui-Gon Jinn"    
 "Obi-Wan Kenobi"  
 "Han Solo"        
 "Sheev Palpatine" 
 "R2-D2"           
 "C-3PO"           
 "Yoda"            
 "Darth Maul"      
 "Dooku"           
 "Chewbacca"       
 "Jabba"           
 "Lando Calrissian"
 "Boba Fett"       
 "Jango Fett"      
 "Grievous"        
 "Chief Chirpa"    
csv_df[:, 1] # Note that this creates a copy.
20-element Array{String,1}:
 "Anakin Skywalker"
 "Padme Amidala"   
 "Luke Skywalker"  
 "Leia Skywalker"  
 "Qui-Gon Jinn"    
 "Obi-Wan Kenobi"  
 "Han Solo"        
 "Sheev Palpatine" 
 "R2-D2"           
 "C-3PO"           
 "Yoda"            
 "Darth Maul"      
 "Dooku"           
 "Chewbacca"       
 "Jabba"           
 "Lando Calrissian"
 "Boba Fett"       
 "Jango Fett"      
 "Grievous"        
 "Chief Chirpa"    

The following are different ways to access a row.

csv_df[1:1, :]

1 rows × 13 columns

NameGenderHeightWeightEyecolorHaircolorSkincolorHomelandBornDiedJediSpeciesWeapon
StringStringFloat64StringStringStringStringStringStringStringStringStringString
1Anakin Skywalkermale1.8884blueblondfairTatooine41.9BBY4ABYjedihumanlightsaber
csv_df[1, :] # This produces a DataFrameRow.

DataFrameRow (13 columns)

NameGenderHeightWeightEyecolorHaircolorSkincolorHomelandBornDiedJediSpeciesWeapon
StringStringFloat64StringStringStringStringStringStringStringStringStringString
1Anakin Skywalkermale1.8884blueblondfairTatooine41.9BBY4ABYjedihumanlightsaber

We can change the values just as we normally assign values.

Assign a range to scalar.

excel_df[1:3, 5] .= 1
3-element view(::Array{Any,1}, 1:3) with eltype Any:
 1
 1
 1

Vector to equal length vector.

excel_df[4:6, 5] = [4, 5, 6]
3-element Array{Int64,1}:
 4
 5
 6

Subset of the DataFrame to another data frame of matching size.

excel_df[1:2, 6:7] =  DataFrames.DataFrame(
    [-2 -2; -2 -2], [Symbol("Unit Cost"), :Total]
)

2 rows × 2 columns

Unit CostTotal
Int64Int64
1-2-2
2-2-2
excel_df

18 rows × 7 columns

OrderDateRegionRepItemUnitsUnit CostTotal
AnyAnyAnyAnyAnyAnyAny
12018-01-06EastJonesPencil1-2-2
22018-01-23CentralKivellBinder1-2-2
32018-02-09CentralJardinePencil14.99179.64
42018-02-26CentralGillPen419.99539.73
52018-03-15WestSorvinoPencil52.99167.44
62018-06-08EastJonesBinder68.99539.4
72018-06-25CentralMorganPencil904.99449.1
82018-07-12EastHowardBinder291.9957.71
92019-07-21CentralMorganPen Set5512.49686.95
102019-08-07CentralKivellPen Set4223.951005.9
112019-08-24WestSorvinoDesk3275.0825.0
122019-09-10CentralGillPencil71.299.03
132019-09-27WestSorvinoPen761.99151.24
142019-10-14WestThompsonBinder5719.991139.43
152019-10-31CentralAndrewsPencil141.2918.06
162019-11-17CentralJardineBinder114.9954.89
172019-12-04CentralJardineBinder9419.991879.06
182019-12-21CentralAndrewsBinder284.99139.72
Tip

There are a lot more things which can be done with a DataFrame. Read the docs for more information.

A Complete Modelling Example - Passport Problem

Let's now apply what we have learnt to solve a real modelling problem.

The Passport Index Dataset lists travel visa requirements for 199 countries, in .csv format. Our task is to find out the minimum number of passports required to visit all countries.

In this dataset, the first column represents a passport (=from) and each remaining column represents a foreign country (=to).

The values in each cell are as follows:

  • 3 = visa-free travel
  • 2 = eTA is required
  • 1 = visa can be obtained on arrival
  • 0 = visa is required
  • -1 is for all instances where passport and destination are the same

Our task is to find out the minimum number of passports needed to visit every country without requiring a visa.

Thus, the values we are interested in are -1 and 3. Let us modify the data in the following manner:

passport_data = CSV.read(
    joinpath(DATA_DIR, "passport-index-matrix.csv"),
    DataFrames.DataFrame;
    copycols = true,
)

for i in 1:DataFrames.nrow(passport_data)
    for j in 2:DataFrames.ncol(passport_data)
        if passport_data[i, j] == -1 || passport_data[i, j] == 3
            passport_data[i, j] = 1
        else
            passport_data[i, j] = 0
        end
    end
end

The values in the cells now represent:

  • 1 = no visa required for travel
  • 0 = visa required for travel

Let us associate each passport with a decision variable $pass_{cntr}$ for each country. We want to minimize the sum $\sum pass_{cntr}$ over all countries.

Since we wish to visit all the countries, for every country, we should own at least one passport that lets us travel to that country visa free. For one destination, this can be mathematically represented as $\sum_{cntr \in world} passportdata_{cntr,dest} \cdot pass_{cntr} \geq 1$.

Thus, we can represent this problem using the following model:

\[\begin{aligned} \min && \sum_{cntr \in World} pass_{cntr} \\ \text{s.t.} && \sum_{cntr \in World} passportdata_{cntr,dest} \cdot pass_{cntr} \geq 1 && \forall dest \in World \\ && pass_{cntr} \in \{0,1\} && \forall cntr \in World \end{aligned}\]

We'll now solve the problem using JuMP.

using JuMP
import GLPK

First, create the set of countries:

World = names(passport_data)[2:end]
199-element Array{String,1}:
 "Afghanistan"        
 "Albania"            
 "Algeria"            
 "Andorra"            
 "Angola"             
 "Antigua and Barbuda"
 "Argentina"          
 "Armenia"            
 "Australia"          
 "Austria"            
 ⋮                    
 "Uruguay"            
 "Uzbekistan"         
 "Vanuatu"            
 "Vatican"            
 "Venezuela"          
 "Viet Nam"           
 "Yemen"              
 "Zambia"             
 "Zimbabwe"           

Then, create the model and initialize the decision variables:

model = Model(GLPK.Optimizer)
@variable(model, pass[cntr in World], Bin)
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
    Dimension 1, ["Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Australia", "Austria"  …  "United States", "Uruguay", "Uzbekistan", "Vanuatu", "Vatican", "Venezuela", "Viet Nam", "Yemen", "Zambia", "Zimbabwe"]
And data, a 199-element Array{VariableRef,1}:
 pass[Afghanistan]        
 pass[Albania]            
 pass[Algeria]            
 pass[Andorra]            
 pass[Angola]             
 pass[Antigua and Barbuda]
 pass[Argentina]          
 pass[Armenia]            
 pass[Australia]          
 pass[Austria]            
 ⋮                        
 pass[Uruguay]            
 pass[Uzbekistan]         
 pass[Vanuatu]            
 pass[Vatican]            
 pass[Venezuela]          
 pass[Viet Nam]           
 pass[Yemen]              
 pass[Zambia]             
 pass[Zimbabwe]           

Define the objective function

@objective(model, Min, sum(pass[cntr] for cntr in World))

\[ pass_{Afghanistan} + pass_{Albania} + pass_{Algeria} + pass_{Andorra} + pass_{Angola} + pass_{Antigua and Barbuda} + pass_{Argentina} + pass_{Armenia} + pass_{Australia} + pass_{Austria} + pass_{Azerbaijan} + pass_{Bahamas} + pass_{Bahrain} + pass_{Bangladesh} + pass_{Barbados} + pass_{Belarus} + pass_{Belgium} + pass_{Belize} + pass_{Benin} + pass_{Bhutan} + pass_{Bolivia} + pass_{Bosnia and Herzegovina} + pass_{Botswana} + pass_{Brazil} + pass_{Brunei} + pass_{Bulgaria} + pass_{Burkina Faso} + pass_{Burundi} + pass_{Cambodia} + pass_{Cameroon} + pass_{Canada} + pass_{Cape Verde} + pass_{Central African Republic} + pass_{Chad} + pass_{Chile} + pass_{China} + pass_{Colombia} + pass_{Comoros} + pass_{Congo} + pass_{DR Congo} + pass_{Costa Rica} + pass_{Ivory Coast} + pass_{Croatia} + pass_{Cuba} + pass_{Cyprus} + pass_{Czech Republic} + pass_{Denmark} + pass_{Djibouti} + pass_{Dominica} + pass_{Dominican Republic} + pass_{Ecuador} + pass_{Egypt} + pass_{El Salvador} + pass_{Equatorial Guinea} + pass_{Eritrea} + pass_{Estonia} + pass_{Swaziland} + pass_{Ethiopia} + pass_{Fiji} + pass_{Finland} + pass_{France} + pass_{Gabon} + pass_{Gambia} + pass_{Georgia} + pass_{Germany} + pass_{Ghana} + pass_{Greece} + pass_{Grenada} + pass_{Guatemala} + pass_{Guinea} + pass_{Guinea-Bissau} + pass_{Guyana} + pass_{Haiti} + pass_{Honduras} + pass_{Hong Kong} + pass_{Hungary} + pass_{Iceland} + pass_{India} + pass_{Indonesia} + pass_{Iran} + pass_{Iraq} + pass_{Ireland} + pass_{Israel} + pass_{Italy} + pass_{Jamaica} + pass_{Japan} + pass_{Jordan} + pass_{Kazakhstan} + pass_{Kenya} + pass_{Kiribati} + pass_{Kosovo} + pass_{Kuwait} + pass_{Kyrgyzstan} + pass_{Laos} + pass_{Latvia} + pass_{Lebanon} + pass_{Lesotho} + pass_{Liberia} + pass_{Libya} + pass_{Liechtenstein} + pass_{Lithuania} + pass_{Luxembourg} + pass_{Macao} + pass_{Madagascar} + pass_{Malawi} + pass_{Malaysia} + pass_{Maldives} + pass_{Mali} + pass_{Malta} + pass_{Marshall Islands} + pass_{Mauritania} + pass_{Mauritius} + pass_{Mexico} + pass_{Micronesia} + pass_{Moldova} + pass_{Monaco} + pass_{Mongolia} + pass_{Montenegro} + pass_{Morocco} + pass_{Mozambique} + pass_{Myanmar} + pass_{Namibia} + pass_{Nauru} + pass_{Nepal} + pass_{Netherlands} + pass_{New Zealand} + pass_{Nicaragua} + pass_{Niger} + pass_{Nigeria} + pass_{North Korea} + pass_{North Macedonia} + pass_{Norway} + pass_{Oman} + pass_{Pakistan} + pass_{Palau} + pass_{Palestine} + pass_{Panama} + pass_{Papua New Guinea} + pass_{Paraguay} + pass_{Peru} + pass_{Philippines} + pass_{Poland} + pass_{Portugal} + pass_{Qatar} + pass_{Romania} + pass_{Russian Federation} + pass_{Rwanda} + pass_{Saint Kitts and Nevis} + pass_{Saint Lucia} + pass_{Samoa} + pass_{San Marino} + pass_{Sao Tome and Principe} + pass_{Saudi Arabia} + pass_{Senegal} + pass_{Serbia} + pass_{Seychelles} + pass_{Sierra Leone} + pass_{Singapore} + pass_{Slovakia} + pass_{Slovenia} + pass_{Solomon Islands} + pass_{Somalia} + pass_{South Africa} + pass_{South Korea} + pass_{South Sudan} + pass_{Spain} + pass_{Sri Lanka} + pass_{Saint Vincent and the Grenadines} + pass_{Sudan} + pass_{Suriname} + pass_{Sweden} + pass_{Switzerland} + pass_{Syria} + pass_{Taiwan} + pass_{Tajikistan} + pass_{Tanzania} + pass_{Thailand} + pass_{Timor-Leste} + pass_{Togo} + pass_{Tonga} + pass_{Trinidad and Tobago} + pass_{Tunisia} + pass_{Turkey} + pass_{Turkmenistan} + pass_{Tuvalu} + pass_{Uganda} + pass_{Ukraine} + pass_{United Arab Emirates} + pass_{United Kingdom} + pass_{United States} + pass_{Uruguay} + pass_{Uzbekistan} + pass_{Vanuatu} + pass_{Vatican} + pass_{Venezuela} + pass_{Viet Nam} + pass_{Yemen} + pass_{Zambia} + pass_{Zimbabwe} \]

@constraint(model, [dest in World], passport_data[:, dest]' * pass >= 1)
1-dimensional DenseAxisArray{ConstraintRef{Model,MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.GreaterThan{Float64}},ScalarShape},1,...} with index sets:
    Dimension 1, ["Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Antigua and Barbuda", "Argentina", "Armenia", "Australia", "Austria"  …  "United States", "Uruguay", "Uzbekistan", "Vanuatu", "Vatican", "Venezuela", "Viet Nam", "Yemen", "Zambia", "Zimbabwe"]
And data, a 199-element Array{ConstraintRef{Model,MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.GreaterThan{Float64}},ScalarShape},1}:
 pass[Afghanistan] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
 pass[Albania] + pass[Andorra] + pass[Antigua and Barbuda] + pass[Argentina] + pass[Armenia] + pass[Australia] + pass[Austria] + pass[Azerbaijan] + pass[Bahamas] + pass[Bahrain] + pass[Barbados] + pass[Belarus] + pass[Belgium] + pass[Bosnia and Herzegovina] + pass[Brazil] + pass[Brunei] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[China] + pass[Colombia] + pass[Costa Rica] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[El Salvador] + pass[Estonia] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Guatemala] + pass[Honduras] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Ireland] + pass[Israel] + pass[Italy] + pass[Japan] + pass[Kazakhstan] + pass[Kosovo] + pass[Kuwait] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Macao] + pass[Malaysia] + pass[Malta] + pass[Mauritius] + pass[Mexico] + pass[Moldova] + pass[Monaco] + pass[Montenegro] + pass[Netherlands] + pass[New Zealand] + pass[Nicaragua] + pass[North Macedonia] + pass[Norway] + pass[Panama] + pass[Paraguay] + pass[Peru] + pass[Poland] + pass[Portugal] + pass[Qatar] + pass[Romania] + pass[Russian Federation] + pass[Saint Kitts and Nevis] + pass[San Marino] + pass[Saudi Arabia] + pass[Serbia] + pass[Seychelles] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[South Korea] + pass[Spain] + pass[Sweden] + pass[Switzerland] + pass[Taiwan] + pass[Thailand] + pass[Trinidad and Tobago] + pass[Turkey] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uruguay] + pass[Vatican] + pass[Venezuela] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
 pass[Algeria] + pass[Libya] + pass[Malaysia] + pass[Mali] + pass[Mauritania] + pass[Morocco] + pass[Seychelles] + pass[Tunisia] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
 pass[Albania] + pass[Andorra] + pass[Antigua and Barbuda] + pass[Argentina] + pass[Australia] + pass[Austria] + pass[Bahamas] + pass[Barbados] + pass[Belgium] + pass[Bosnia and Herzegovina] + pass[Brazil] + pass[Brunei] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[Colombia] + pass[Costa Rica] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Dominica] + pass[El Salvador] + pass[Estonia] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Grenada] + pass[Guatemala] + pass[Honduras] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Ireland] + pass[Israel] + pass[Italy] + pass[Japan] + pass[Kiribati] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Macao] + pass[Malaysia] + pass[Malta] + pass[Marshall Islands] + pass[Mauritius] + pass[Mexico] + pass[Micronesia] + pass[Moldova] + pass[Monaco] + pass[Montenegro] + pass[Netherlands] + pass[New Zealand] + pass[Nicaragua] + pass[North Macedonia] + pass[Norway] + pass[Palau] + pass[Panama] + pass[Paraguay] + pass[Peru] + pass[Poland] + pass[Portugal] + pass[Romania] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[Samoa] + pass[San Marino] + pass[Serbia] + pass[Seychelles] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[Solomon Islands] + pass[South Korea] + pass[Spain] + pass[Saint Vincent and the Grenadines] + pass[Sweden] + pass[Switzerland] + pass[Taiwan] + pass[Timor-Leste] + pass[Tonga] + pass[Trinidad and Tobago] + pass[Tuvalu] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uruguay] + pass[Vanuatu] + pass[Vatican] + pass[Venezuela] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                
 pass[Angola] + pass[Botswana] + pass[Mauritius] + pass[Mozambique] + pass[Namibia] + pass[Rwanda] + pass[Seychelles] + pass[Singapore] + pass[South Africa] + pass[Zambia] + pass[Zimbabwe] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
 pass[Albania] + pass[Andorra] + pass[Antigua and Barbuda] + pass[Argentina] + pass[Armenia] + pass[Australia] + pass[Austria] + pass[Azerbaijan] + pass[Bahamas] + pass[Barbados] + pass[Belarus] + pass[Belgium] + pass[Belize] + pass[Botswana] + pass[Brazil] + pass[Brunei] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[China] + pass[Colombia] + pass[Croatia] + pass[Cuba] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Dominica] + pass[Estonia] + pass[Swaziland] + pass[Fiji] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Grenada] + pass[Guyana] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Ireland] + pass[Italy] + pass[Jamaica] + pass[Japan] + pass[Kazakhstan] + pass[Kenya] + pass[Kiribati] + pass[Kyrgyzstan] + pass[Latvia] + pass[Lesotho] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Macao] + pass[Madagascar] + pass[Malawi] + pass[Malaysia] + pass[Maldives] + pass[Malta] + pass[Marshall Islands] + pass[Mauritius] + pass[Mexico] + pass[Moldova] + pass[Monaco] + pass[Namibia] + pass[Nauru] + pass[Netherlands] + pass[New Zealand] + pass[North Macedonia] + pass[Norway] + pass[Panama] + pass[Papua New Guinea] + pass[Peru] + pass[Poland] + pass[Portugal] + pass[Romania] + pass[Russian Federation] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[Samoa] + pass[San Marino] + pass[Seychelles] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[Solomon Islands] + pass[South Africa] + pass[South Korea] + pass[Spain] + pass[Saint Vincent and the Grenadines] + pass[Suriname] + pass[Sweden] + pass[Switzerland] + pass[Taiwan] + pass[Tajikistan] + pass[Tanzania] + pass[Trinidad and Tobago] + pass[Turkey] + pass[Turkmenistan] + pass[Tuvalu] + pass[Uganda] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uzbekistan] + pass[Vanuatu] + pass[Vatican] + pass[Venezuela] + pass[Zambia] ≥ 1.0                                                                                                                                                                            
 pass[Andorra] + pass[Argentina] + pass[Armenia] + pass[Australia] + pass[Austria] + pass[Barbados] + pass[Belarus] + pass[Belgium] + pass[Bolivia] + pass[Brazil] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[Colombia] + pass[Costa Rica] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Ecuador] + pass[El Salvador] + pass[Estonia] + pass[Fiji] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Grenada] + pass[Guatemala] + pass[Guyana] + pass[Honduras] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Ireland] + pass[Israel] + pass[Italy] + pass[Jamaica] + pass[Japan] + pass[Kazakhstan] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Malaysia] + pass[Malta] + pass[Mexico] + pass[Monaco] + pass[Montenegro] + pass[Netherlands] + pass[New Zealand] + pass[Nicaragua] + pass[North Macedonia] + pass[Norway] + pass[Panama] + pass[Paraguay] + pass[Peru] + pass[Poland] + pass[Portugal] + pass[Qatar] + pass[Romania] + pass[Russian Federation] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[San Marino] + pass[Serbia] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[South Africa] + pass[South Korea] + pass[Spain] + pass[Saint Vincent and the Grenadines] + pass[Suriname] + pass[Sweden] + pass[Switzerland] + pass[Thailand] + pass[Trinidad and Tobago] + pass[Turkey] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uruguay] + pass[Vatican] + pass[Venezuela] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
 pass[Albania] + pass[Andorra] + pass[Argentina] + pass[Armenia] + pass[Australia] + pass[Austria] + pass[Belarus] + pass[Belgium] + pass[Brazil] + pass[Bulgaria] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Estonia] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Iran] + pass[Ireland] + pass[Italy] + pass[Japan] + pass[Kazakhstan] + pass[Kyrgyzstan] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Macao] + pass[Malta] + pass[Moldova] + pass[Monaco] + pass[Montenegro] + pass[Netherlands] + pass[New Zealand] + pass[Norway] + pass[Poland] + pass[Portugal] + pass[Qatar] + pass[Romania] + pass[Russian Federation] + pass[San Marino] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[South Korea] + pass[Spain] + pass[Sweden] + pass[Switzerland] + pass[Tajikistan] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uruguay] + pass[Uzbekistan] + pass[Vatican] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
 pass[Australia] + pass[New Zealand] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
 pass[Albania] + pass[Andorra] + pass[Antigua and Barbuda] + pass[Argentina] + pass[Australia] + pass[Austria] + pass[Bahamas] + pass[Barbados] + pass[Belgium] + pass[Bosnia and Herzegovina] + pass[Brazil] + pass[Brunei] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[Colombia] + pass[Costa Rica] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Dominica] + pass[El Salvador] + pass[Estonia] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Grenada] + pass[Guatemala] + pass[Honduras] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Ireland] + pass[Israel] + pass[Italy] + pass[Japan] + pass[Kiribati] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Macao] + pass[Malaysia] + pass[Malta] + pass[Marshall Islands] + pass[Mauritius] + pass[Mexico] + pass[Micronesia] + pass[Moldova] + pass[Monaco] + pass[Montenegro] + pass[Netherlands] + pass[New Zealand] + pass[Nicaragua] + pass[North Macedonia] + pass[Norway] + pass[Palau] + pass[Panama] + pass[Paraguay] + pass[Peru] + pass[Poland] + pass[Portugal] + pass[Romania] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[Samoa] + pass[San Marino] + pass[Serbia] + pass[Seychelles] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[Solomon Islands] + pass[South Korea] + pass[Spain] + pass[Saint Vincent and the Grenadines] + pass[Sweden] + pass[Switzerland] + pass[Taiwan] + pass[Timor-Leste] + pass[Tonga] + pass[Trinidad and Tobago] + pass[Tuvalu] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uruguay] + pass[Vanuatu] + pass[Vatican] + pass[Venezuela] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                
 ⋮                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
 pass[Andorra] + pass[Argentina] + pass[Armenia] + pass[Australia] + pass[Austria] + pass[Bahamas] + pass[Barbados] + pass[Belgium] + pass[Belize] + pass[Bolivia] + pass[Brazil] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[Colombia] + pass[Costa Rica] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Dominica] + pass[Ecuador] + pass[El Salvador] + pass[Estonia] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Grenada] + pass[Guatemala] + pass[Guyana] + pass[Honduras] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Ireland] + pass[Israel] + pass[Italy] + pass[Jamaica] + pass[Japan] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Macao] + pass[Malaysia] + pass[Malta] + pass[Mexico] + pass[Monaco] + pass[Mongolia] + pass[Montenegro] + pass[Netherlands] + pass[New Zealand] + pass[Nicaragua] + pass[Norway] + pass[Panama] + pass[Paraguay] + pass[Peru] + pass[Poland] + pass[Portugal] + pass[Romania] + pass[Russian Federation] + pass[Saint Kitts and Nevis] + pass[San Marino] + pass[Serbia] + pass[Seychelles] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[South Africa] + pass[South Korea] + pass[Spain] + pass[Saint Vincent and the Grenadines] + pass[Sweden] + pass[Switzerland] + pass[Taiwan] + pass[Trinidad and Tobago] + pass[Turkey] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uruguay] + pass[Vatican] + pass[Venezuela] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
 pass[Andorra] + pass[Argentina] + pass[Armenia] + pass[Australia] + pass[Austria] + pass[Azerbaijan] + pass[Belarus] + pass[Belgium] + pass[Bosnia and Herzegovina] + pass[Brazil] + pass[Brunei] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Estonia] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Hungary] + pass[Iceland] + pass[Indonesia] + pass[Ireland] + pass[Israel] + pass[Italy] + pass[Japan] + pass[Kazakhstan] + pass[Kyrgyzstan] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Malaysia] + pass[Malta] + pass[Moldova] + pass[Monaco] + pass[Mongolia] + pass[Montenegro] + pass[Netherlands] + pass[New Zealand] + pass[Norway] + pass[Poland] + pass[Portugal] + pass[Romania] + pass[Russian Federation] + pass[San Marino] + pass[Serbia] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[South Korea] + pass[Spain] + pass[Sweden] + pass[Switzerland] + pass[Tajikistan] + pass[Turkey] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[Uzbekistan] + pass[Vatican] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
 pass[Andorra] + pass[Antigua and Barbuda] + pass[Argentina] + pass[Australia] + pass[Austria] + pass[Azerbaijan] + pass[Bahamas] + pass[Bahrain] + pass[Bangladesh] + pass[Barbados] + pass[Belarus] + pass[Belgium] + pass[Belize] + pass[Botswana] + pass[Brazil] + pass[Brunei] + pass[Bulgaria] + pass[Cameroon] + pass[Canada] + pass[Chile] + pass[China] + pass[Croatia] + pass[Cuba] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Dominica] + pass[Estonia] + pass[Swaziland] + pass[Fiji] + pass[Finland] + pass[France] + pass[Gambia] + pass[Germany] + pass[Ghana] + pass[Greece] + pass[Grenada] + pass[Guyana] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[India] + pass[Ireland] + pass[Israel] + pass[Italy] + pass[Jamaica] + pass[Japan] + pass[Kenya] + pass[Kiribati] + pass[Kuwait] + pass[Latvia] + pass[Lesotho] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Macao] + pass[Malawi] + pass[Malaysia] + pass[Maldives] + pass[Malta] + pass[Marshall Islands] + pass[Mauritius] + pass[Mexico] + pass[Micronesia] + pass[Monaco] + pass[Morocco] + pass[Mozambique] + pass[Namibia] + pass[Nauru] + pass[Netherlands] + pass[New Zealand] + pass[Nigeria] + pass[Norway] + pass[Oman] + pass[Pakistan] + pass[Palau] + pass[Papua New Guinea] + pass[Peru] + pass[Philippines] + pass[Poland] + pass[Portugal] + pass[Qatar] + pass[Romania] + pass[Russian Federation] + pass[Rwanda] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[Samoa] + pass[San Marino] + pass[Saudi Arabia] + pass[Serbia] + pass[Seychelles] + pass[Sierra Leone] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[Solomon Islands] + pass[South Africa] + pass[South Korea] + pass[Spain] + pass[Sri Lanka] + pass[Saint Vincent and the Grenadines] + pass[Sweden] + pass[Switzerland] + pass[Taiwan] + pass[Tanzania] + pass[Thailand] + pass[Tonga] + pass[Trinidad and Tobago] + pass[Tunisia] + pass[Turkey] + pass[Tuvalu] + pass[Uganda] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uruguay] + pass[Vanuatu] + pass[Vatican] + pass[Zambia] + pass[Zimbabwe] ≥ 1.0
 pass[Albania] + pass[Andorra] + pass[Antigua and Barbuda] + pass[Argentina] + pass[Australia] + pass[Austria] + pass[Bahamas] + pass[Barbados] + pass[Belgium] + pass[Bosnia and Herzegovina] + pass[Brazil] + pass[Brunei] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[Colombia] + pass[Costa Rica] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Dominica] + pass[El Salvador] + pass[Estonia] + pass[Finland] + pass[France] + pass[Georgia] + pass[Germany] + pass[Greece] + pass[Grenada] + pass[Guatemala] + pass[Honduras] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Ireland] + pass[Israel] + pass[Italy] + pass[Japan] + pass[Kiribati] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Macao] + pass[Malaysia] + pass[Malta] + pass[Marshall Islands] + pass[Mauritius] + pass[Mexico] + pass[Micronesia] + pass[Moldova] + pass[Monaco] + pass[Montenegro] + pass[Netherlands] + pass[New Zealand] + pass[Nicaragua] + pass[North Macedonia] + pass[Norway] + pass[Palau] + pass[Panama] + pass[Paraguay] + pass[Peru] + pass[Poland] + pass[Portugal] + pass[Romania] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[Samoa] + pass[San Marino] + pass[Serbia] + pass[Seychelles] + pass[Singapore] + pass[Slovakia] + pass[Slovenia] + pass[Solomon Islands] + pass[South Korea] + pass[Spain] + pass[Saint Vincent and the Grenadines] + pass[Sweden] + pass[Switzerland] + pass[Taiwan] + pass[Timor-Leste] + pass[Tonga] + pass[Trinidad and Tobago] + pass[Tuvalu] + pass[Ukraine] + pass[United Arab Emirates] + pass[United Kingdom] + pass[United States] + pass[Uruguay] + pass[Vanuatu] + pass[Vatican] + pass[Venezuela] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                
 pass[Andorra] + pass[Antigua and Barbuda] + pass[Argentina] + pass[Australia] + pass[Austria] + pass[Barbados] + pass[Belarus] + pass[Belgium] + pass[Belize] + pass[Bolivia] + pass[Brazil] + pass[Bulgaria] + pass[Canada] + pass[Chile] + pass[Colombia] + pass[Costa Rica] + pass[Croatia] + pass[Cyprus] + pass[Czech Republic] + pass[Denmark] + pass[Dominica] + pass[Ecuador] + pass[Estonia] + pass[Finland] + pass[France] + pass[Germany] + pass[Greece] + pass[Grenada] + pass[Guatemala] + pass[Hong Kong] + pass[Hungary] + pass[Iceland] + pass[Iran] + pass[Ireland] + pass[Italy] + pass[Jamaica] + pass[Japan] + pass[Latvia] + pass[Liechtenstein] + pass[Lithuania] + pass[Luxembourg] + pass[Malaysia] + pass[Malta] + pass[Mexico] + pass[Monaco] + pass[Netherlands] + pass[New Zealand] + pass[Norway] + pass[Palestine] + pass[Paraguay] + pass[Peru] + pass[Poland] + pass[Portugal] + pass[Romania] + pass[Russian Federation] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[San Marino] + pass[Slovakia] + pass[Slovenia] + pass[South Africa] + pass[South Korea] + pass[Spain] + pass[Saint Vincent and the Grenadines] + pass[Sweden] + pass[Switzerland] + pass[Trinidad and Tobago] + pass[Turkey] + pass[United Kingdom] + pass[Uruguay] + pass[Venezuela] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
 pass[Belarus] + pass[Brunei] + pass[Cambodia] + pass[Chile] + pass[Denmark] + pass[Finland] + pass[France] + pass[Germany] + pass[Indonesia] + pass[Italy] + pass[Japan] + pass[Kyrgyzstan] + pass[Laos] + pass[Malaysia] + pass[Myanmar] + pass[Norway] + pass[Philippines] + pass[Russian Federation] + pass[Singapore] + pass[South Korea] + pass[Spain] + pass[Sweden] + pass[Thailand] + pass[United Kingdom] + pass[Viet Nam] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
 pass[Hong Kong] + pass[Yemen] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
 pass[Angola] + pass[Antigua and Barbuda] + pass[Bahamas] + pass[Barbados] + pass[Belize] + pass[Botswana] + pass[Cyprus] + pass[Dominica] + pass[Swaziland] + pass[Fiji] + pass[Grenada] + pass[Hong Kong] + pass[Ireland] + pass[Jamaica] + pass[Kenya] + pass[Kiribati] + pass[Lesotho] + pass[Malawi] + pass[Malaysia] + pass[Maldives] + pass[Malta] + pass[Marshall Islands] + pass[Mauritius] + pass[Montenegro] + pass[Mozambique] + pass[Namibia] + pass[Romania] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[Samoa] + pass[Serbia] + pass[Seychelles] + pass[Singapore] + pass[Solomon Islands] + pass[South Africa] + pass[Saint Vincent and the Grenadines] + pass[Tanzania] + pass[Tonga] + pass[Trinidad and Tobago] + pass[Tuvalu] + pass[Uganda] + pass[Vanuatu] + pass[Zambia] + pass[Zimbabwe] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
 pass[Angola] + pass[Antigua and Barbuda] + pass[Bahamas] + pass[Barbados] + pass[Belize] + pass[Botswana] + pass[DR Congo] + pass[Cyprus] + pass[Swaziland] + pass[Fiji] + pass[Ghana] + pass[Grenada] + pass[Hong Kong] + pass[Jamaica] + pass[Kenya] + pass[Kiribati] + pass[Lesotho] + pass[Madagascar] + pass[Malawi] + pass[Malaysia] + pass[Maldives] + pass[Malta] + pass[Mauritius] + pass[Mozambique] + pass[Namibia] + pass[Nauru] + pass[Saint Kitts and Nevis] + pass[Saint Lucia] + pass[Samoa] + pass[Seychelles] + pass[Singapore] + pass[Solomon Islands] + pass[South Africa] + pass[Saint Vincent and the Grenadines] + pass[Tanzania] + pass[Tonga] + pass[Trinidad and Tobago] + pass[Tuvalu] + pass[Uganda] + pass[Vanuatu] + pass[Zambia] + pass[Zimbabwe] ≥ 1.0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                

Now optimize!

optimize!(model)
println("Minimum number of passports needed: ", objective_value(model))
Minimum number of passports needed: 23.0
optimal_passports = [cntr for cntr in World if value(pass[cntr]) > 0.5]
println("Countries:")
for p in optimal_passports
    println(" ", p)
end
Countries:
 Afghanistan
 Angola
 Australia
 Austria
 Comoros
 Congo
 Eritrea
 Gambia
 Georgia
 Hong Kong
 India
 Iraq
 Kenya
 Madagascar
 Maldives
 North Korea
 Papua New Guinea
 Singapore
 Somalia
 Sri Lanka
 Tunisia
 United Arab Emirates
 United States
Note

We use value(pass[i]) > 0.5 rather than value(pass[i]) == 1 to avoid excluding solutions like pass[i] = 0.99999 that are "1" to some tolerance.

View this file on Github.


This page was generated using Literate.jl.