Skip to content

Commit ae2a649

Browse files
committed
Initial commit
0 parents  commit ae2a649

File tree

15 files changed

+26050
-0
lines changed

15 files changed

+26050
-0
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.jl.cov
2+
*.jl.*.cov
3+
*.jl.mem
4+
deps/deps.jl

.travis.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
language: julia
2+
os:
3+
- linux
4+
julia:
5+
- 0.4
6+
notifications:
7+
email: false
8+
sudo: false

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 wen-chih
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# FrontierEfficiencyAnalysis.jl
2+
3+
#### Copyright © 2017 by Wen-Chih Chen. Released under the MIT License.
4+
5+
[![Build Status](https://travis-ci.org/wen-chih/FrontierEfficiencyAnalysis.jl.svg?branch=master)](https://travis-ci.org/wen-chih/FrontierEfficiencyAnalysis.jl)
6+
7+
8+
FrontierEfficiencyAnalysis.jl is a package for Frontier Efficiency Analysis (aka Data Envelopment Analysis, DEA) computation. It is embedded in the [Julia](https://julialang.org/) programming language, and is an extension to the [JuMP](https://github.com/JuliaOpt/JuMP.jl) modeling language. It is particularly designed to enhance large-scale DEA computation and to solve DEA problems by size-limited solvers.
9+
10+
**Disclaimer** : FrontierEfficiencyAnalysis is *not* developed or maintained by the JuMP developers.
11+
12+
13+
## Installation
14+
In Julia, call `Pkg.clone("git://github.com/wen-chih/FrontierEfficiencyAnalysis.jl.git")` to install FrontierEfficiencyAnalysis.
15+
16+
17+
## Usage
18+
DEA is a linear program (LP)-based method used to determine a firm’s relative efficiency. Users can use JuMP to model and solve the DEA problems (special LP problems). Rather than solve the LPs by calling `JuMP.solve()`, FrontierEfficiencyAnalysis.jl can solve the large-scale problems more efficiently and/or by a solver with size limitation (e.g. 300 variables).
19+
20+
21+
Please refer to [Quick Start Guide of JuMP](https://jump.readthedocs.io/en/latest/quickstart.html) for modeling details. What needed is to call our FrontierEfficiencyAnalysis.jl function:
22+
23+
solveDEA(model)
24+
25+
instead of calling
26+
27+
JuMP.solve(model)
28+
29+
30+
## Example
31+
32+
33+
```julia
34+
# The example determine the efficiencies for all DMUs based on the CRS input-oriented model (CCR model)
35+
using JuMP
36+
using Gurobi # Gurobi is used as the LP solver
37+
using FrontierEfficiencyAnalysis
38+
39+
data = readcsv("example.csv") # input User's (.csv) data path
40+
scale, dimension = size(data) # scale is the number of DMU, dimension is the total number of inputs and outputs
41+
42+
for t = 1 : scale
43+
### Modeling section
44+
# Here is the CRS input-oriented model (CCR model) to evaluate DMU t
45+
model = Model(solver = GurobiSolver()) # Gurobi is used as the LP solver here. Users can choose their favorite solver.
46+
@variable(model, Lambda[1:scale] >= 0)
47+
@variable(model, Theta)
48+
@objective(model, Min, Theta)
49+
@constraint(model, inputCon[i=1:2], sum(Lambda[r]*data[r,i] for r = 1:scale) <= Theta*data[t,i])
50+
@constraint(model, outputCon[j=3:dimension], sum(Lambda[r]*data[r,j] for r = 1:scale) >= data[t,j])
51+
# uncomment to add the convexity constraint for the VRS model
52+
# @constraint(model, sum(Lambda[r] for r = 1:scale) == 1)
53+
54+
### Problem solving
55+
solveDEA(model)
56+
57+
### Display
58+
println("Results for DMU $t")
59+
println("The efficicncy: $(getobjectivevalue(model))")
60+
println("The efficicncy: $(getvalue(Theta))")
61+
println("The lambdas: $(getvalue(Lambda)))")
62+
63+
64+
## Use the following if returning dual values and slacks is needed
65+
66+
### Problem solving
67+
# duals, slacks = solveDEA(model)
68+
### Display
69+
# println("Results for DMU $t")
70+
# println("The efficicncy: $(getobjectivevalue(model))")
71+
# println("The efficicncy: $(getvalue(Theta))")
72+
# println("The lambdas: $(getvalue(Lambda)))")
73+
74+
# #println("The dual values (weights): $duals") # a vector associated with the constraints you define from the top to the bottom
75+
# println("the slack values: $slacks") # a vector associated with the constraints you define from the top to the bottom
76+
end
77+
```
78+
79+
<br>
80+
81+
## Parameters
82+
83+
>
84+
**incrementSize** : the incremental size to expand the sample ( default value: 100 ).
85+
86+
solveDEA(model, incrementSize = 200) # set the incremental size to 200
87+
88+
>
89+
**tol** : the solution tolerance for solving DEA problem (default value: 1e-6). It also resets the dual feasibility tolerance in the solver to the given value.
90+
<br>
91+
92+
solveDEA(model, tol = 10^-4) # set the solution tolerance to 1e-4
93+
94+
>
95+
**lpUB** : the size limit of the LP, i.e. the limitation of number of variables in the LP (default value: Inf).
96+
<br>
97+
98+
solveDEA(model, lpUB = 300) # set the LP size limitation to 300 variables
99+
100+
>
101+
**extremeValueSetFlag** : to enable (=1) or disable (=0) performing initial sampling by selecing extreme value in each input/output dimension (default value: 0).
102+
<br>
103+
104+
105+
solveDEA(model, extremeValueSetFlag = 1) # enable
106+
107+
108+
109+
110+
## Citation
111+
If you find FrontierEfficiencyAnalysis useful in your work, we kindly request that you cite the following papers
112+
113+
@article{ChenLai2017,
114+
author = {Wen-Chih Chen and Sheng-Yung Lai},
115+
title = {Determining radial efficiency with a large data set by solving small-size linear programs},
116+
journal = {Annals of Operations Research},
117+
volume = {250},
118+
number = {1},
119+
pages = {147-166},
120+
year = {2017},
121+
doi = {10.1007/s10479-015-1968-4},
122+
}
123+
and
124+
125+
@misc{chen2017b,
126+
Author = {Wen-Chih Chen},
127+
Title = {Solving size-limited linear programs to determine productive efficiencies with big data},
128+
Year = {2017},
129+
Eprint = {http://dx.doi.org/10.2139/ssrn.2496847},
130+
}
131+
132+
## Acknowledgements
133+
FrontierEfficiencyAnalysis has been developed under the financial support of the Ministry of Science and Technology, Taiwan (Grant No. 104-2410-H-009-026-MY2). The contributors include Yueh-Shan Chung and Hao-Yun Chen.

REQUIRE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
julia 0.5
2+
JuMP
3+
MathProgBase
4+
Gurobi

example/basicDEAmodel.jl

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright Wen-Chih Chen
2+
# the code is for computing basic DEA models based on orientation (input or output)
3+
# and returns-to-scale (crs or vrs)
4+
5+
using JuMP
6+
using Gurobi # Gurobi is used as the LP solver
7+
using FrontierEfficiencyAnalysis # for large scale problems and/or with size-limited solver
8+
9+
function basicDEAmodel()
10+
#----------------------------------------
11+
# data section
12+
data = readcsv("example.csv") # input User's (.csv) data path
13+
# each row is for a DMU; each column is an input or output
14+
# in the example the first two columns are the inputs while the others are the outputs
15+
inputs = data[:, 1:2]
16+
outputs = data[:, 3:end]
17+
18+
# ---------------------------------------
19+
# to determine the efficiencies of all DMUs
20+
results = zeros(size(inputs)[1])
21+
getAllEfficiencies!(results, inputs, outputs) # get all DMU's efficiencies of input-oriented crs model
22+
## or use the following to set the options of orientation, returns-to-scale and method
23+
# getAllEfficiencies!(results, inputs, outputs, orientation = "input", rts = "crs", method = 0)
24+
## orientation = "input" (default) or "output"
25+
## rts = "crs" (default) or "vrs"
26+
## method = 0 (default) or 1 (by FrontierEfficiencyAnalysis for large scale problems and/or with size-limited solver)
27+
## e.g. for output-oriented vsr model and solve by FrontierEfficiencyAnalysis do:
28+
# getAllEfficiencies!(results, inputs, outputs, orientation = "output", rts = "vrs", method = 1)
29+
println(results)
30+
31+
# ---------------------------------------
32+
# to determine the efficiency of DMU k
33+
k = 2
34+
score = getEfficiency(inputs, outputs, k) # get DMU k's efficiency of input-oriented crs model
35+
## or use the following to set the options of orientation, returns-to-scale and method
36+
# score = getEfficiency(inputs, outputs, k, orientation = "input", rts = "crs", method = 0)
37+
## orientation = "input" (default) or "output"
38+
## rts = "crs" (default) or "vrs"
39+
## method = 0 (default) or 1 (by FrontierEfficiencyAnalysis for large scale problems and/or with size-limited solver)
40+
## e.g. for output-oriented vsr model and solve by FrontierEfficiencyAnalysis do:
41+
# score = getEfficiency(inputs, outputs, k, orientation = "output", rts = "vrs", method = 1)
42+
println(score)
43+
44+
end
45+
46+
# compute DEA efficiencies for all DMUs in the data set and store results in scores
47+
function getAllEfficiencies!(scores, inputData, outputData; orientation = "input", rts = "crs", method = 0)
48+
# parameters
49+
# scores: efficiency results
50+
# inputData: input data matrix (DMU size) x (input size)
51+
# outputData: output data matrix (DMU size) x (output size)
52+
# orientation: input- or output- oriented model (value= "input" or "output")
53+
# rts: returns to scale setting (value = "crs" or "vrs")
54+
# # method: how to solve LP (value = 0 (default) or 1 (by FrontierEfficiencyAnalysis.jl))
55+
56+
if !(orientation == "input" || orientation == "output")
57+
error("orientation not supported")
58+
end
59+
60+
if !(rts == "crs" || rts == "vrs")
61+
error("returns to scale not supported")
62+
end
63+
64+
for t = 1:size(inputData)[1]
65+
scores[t] = getEfficiency(inputData, outputData, t, orientation = orientation, rts = rts, method = method)
66+
end
67+
end
68+
69+
# compute DEA efficiency for DMU k
70+
function getEfficiency(inputs, outputs, k; orientation = "input", rts = "crs", method = 0)
71+
# parameters
72+
# inputs: input data matrix (DMU size) x (input size)
73+
# outputs: output data matrix (DMU size) x (output size)
74+
# k: index of DMU to be evaluated
75+
# orientation: input- or output- oriented model (value= "input" or "output")
76+
# rts: returns to scale setting (value = "crs" or "vrs")
77+
# method: how to solve LP (value = 0 (default) or 1 (by FrontierEfficiencyAnalysis.jl))
78+
scale, inputNo = size(inputs)
79+
outputNo = size(outputs)[2]
80+
81+
model = Model(solver = GurobiSolver(OutputFlag=0)) # Gurobi is used as the LP solver here. Users can choose their favorite solver.
82+
@variable(model, Lambda[1:scale] >= 0)
83+
@variable(model, Theta)
84+
85+
if orientation == "input" # input-oriented model
86+
@objective(model, Min, Theta)
87+
@constraint(model, inputCon[i=1:inputNo], sum(Lambda[r]*inputs[r,i] for r = 1:scale) <= Theta*inputs[k,i])
88+
@constraint(model, outputCon[j=1:outputNo], sum(Lambda[r]*outputs[r,j] for r = 1:scale) >= outputs[k,j])
89+
elseif orientation == "output" # output-oriented model
90+
@objective(model, Max, Theta)
91+
@constraint(model, inputCon[i=1:inputNo], sum(Lambda[r]*inputs[r,i] for r = 1:scale) <= inputs[k,i])
92+
@constraint(model, outputCon[j=1:outputNo], sum(Lambda[r]*outputs[r,j] for r = 1:scale) >= Theta*outputs[k,j])
93+
else
94+
error("orientation not support")
95+
end
96+
97+
if rts == "vrs"
98+
@constraint(model, sum(Lambda[r] for r = 1:scale) == 1)
99+
elseif rts == "crs"
100+
else
101+
error("returns to scale not supported")
102+
end
103+
104+
if method == 0 # defalut
105+
solve(model)
106+
else # using FrontierEfficiencyAnalysis for large scale problem or with size limited solver
107+
solveDEA(model)
108+
end
109+
110+
return getvalue(Theta)
111+
end
112+
113+
basicDEAmodel()

0 commit comments

Comments
 (0)