Skip to content

Commit c366031

Browse files
Merge pull request #16 from MatthewStuber/InitCommit
Init commit
2 parents d3d2eac + 2573ce1 commit c366031

File tree

4 files changed

+120
-32
lines changed

4 files changed

+120
-32
lines changed

README.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,50 @@
1-
# EAGODomainReduction
2-
A Package Containing Multiple Domain Reduction Procedures Used in Global Optimization
1+
# EAGODomainReduction.jl
2+
Domain Reduction Procedures in Global Optimization
3+
4+
## Installation
5+
6+
```julia
7+
julia> Pkg.add("EAGODomainReduction.jl")
8+
```
9+
10+
## Capabilities
11+
12+
**EAGODomainReduction.jl** provides a series of subroutines for tightening the domains of subproblems
13+
solved in global optimization (potentially to in-feasibility). Currently, it supports routines for
14+
nonconvex nonlinear programs:
15+
- **Interval Contractor Propagation:** A forward-backward interval contractor using **IntervalArthimetic.jl**
16+
and **IntervalContractors.jl** for the operator library.
17+
- **Duality-Based Bound Tightening:** Provides algorithms for tightening domains based on duality of solutions
18+
found for subproblems.
19+
- **Standard Range Reduction:** Contracts subproblem domain via linear-relaxations generated using McCormick
20+
relaxations.
21+
- **Implicit Subroutine support:** Supports domain reduction of reduced space lower-bound problems defined through
22+
relaxation of implicit functions by fixed-point methods.
23+
24+
The routine are used extensively in the `EAGO.jl`[https://github.com/MatthewStuber/EAGO.jl] package solver.
25+
Please see the example files for usage cases.
26+
27+
## Future Work
28+
29+
- Update the interval-constraint propagation algorithm to incorporate propagation heuristics in Vu2008.
30+
- Incorporate control-flow syntax support into constraint propagation algorithm.
31+
- Incorporate improvements to probing and optimality based-bound tightening.
32+
- Add support for Mixed-Integer NLP.
33+
34+
## Related Packages
35+
- **EAGO.jl**[https://github.com/MatthewStuber/EAGO.jl]: A package containing global and robust solvers based mainly on McCormick relaxations.
36+
This package supports a JuMP and MathProgBase interface.
37+
- **IntervalConstraintProgramming.jl**[https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl]: Provides algorithms that furnish bounds
38+
on constraints defined by expressions. The constraint propagation routine in **EAGODomainReduction.jl** can generate tape objects that are
39+
reusable for generically-defined functions. In addition, we use a `Vector{Interval}` storage object that allows for in-place mutation of intervals.
40+
- **IntervalContractors.jl**[https://github.com/JuliaIntervals/IntervalContractors.jl]: Provides a library of reverse interval contractors.
41+
42+
## References
43+
- Benhamou, F., & Older, W.J. (1997). Applying interval arithmetic to real, integer, and boolean constraints. The Journal of Logic Programming, 32, 1–24.
44+
- Caprara, A., & Locatelli, M. (2010). Global optimization problems and domain reduction strategies. Mathematical Programming, 125, 123–137.
45+
- Gleixner, A.M., Berthold, T., Müller, B., & Weltge, S. (2016). Three enhancements for optimization-based bound tightening. ZIB Report, 15–16.
46+
- Ryoo, H.S., & Sahinidis, N.V. (1996). A branch-and-reduce approach to global optimization. Journal of Global Optimization, 8, 107–139.
47+
- Schichl, H., & Neumaier, A. (2005). Interval analysis on directed acyclic graphs for global optimization. Journal of Global Optimization, 33, 541–562.
48+
- Tawarmalani, M., & Sahinidis, N.V. (2005). A polyhedral branch-and-cut approach to global optimization. Mathematical Programming, 103, 225–249.
49+
- Vu, X., Schichl, H., & Sam-Haroud, D. (2009). Interval propagation and search on directed acyclic
50+
graphs for numerical constraint solving. Journal of Global Optimization, 45, 499–531.

src/src/FBBT/DAGprop.jl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,18 @@ function ForwardPass!(x::Tape)
272272
end
273273
end
274274

275+
"""
276+
ForwardPassOne!(x::Tape)
277+
278+
Performs a forward contractor pass using tape `x::Tape` with some uninitialized nodes.
279+
"""
280+
function ForwardPassOne!(x::Tape)
281+
for i=1:length(x.Edge_List)
282+
x.FW_Expr[i].args = vcat([x.Head_List[i]],x.Intv_Storage[x.FW_Arg[i]])
283+
x.Intv_Storage[x.Edge_List[i][1][2]] = eval(x.FW_Expr[i])
284+
end
285+
end
286+
275287
"""
276288
ReversePass!(x::Tape)
277289
@@ -293,12 +305,15 @@ and the initial interval bounds `X::Vector{Interval{T}}`.
293305
function DAGContractor!(X::Vector{Interval{T}},x::TapeList,r) where {T}
294306
Xprev::Vector{Interval} = copy(X) # sets variable bounds on first Array to Box Bounds
295307
SetConstraintNode!(x)
296-
#SetConstantNode!(x)
297308
for i=1:r
298309
for j=1:length(x.sto)
299310
SetVarBounds!(x.sto[j],Xprev) # take refined bounds from previous graph
300311
SetConstantNode!(x)
301-
ForwardPass!(x.sto[j]) # run forward and reverse pass
312+
if (i == 1)
313+
ForwardPassOne!(x.sto[j])
314+
else
315+
ForwardPass!(x.sto[j]) # run forward and reverse pass
316+
end
302317
ReversePass!(x.sto[j])
303318
Xprev = x.sto[j].Intv_Storage[1:length(X)]
304319
end

src/src/FBBT/NodeFinder.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ immutable NodeFinder
88
ind::Int64
99
end
1010

11+
step(x::T) where T = x>0 ? one(T) : zero(T)
12+
1113
# Defines conversion for NodeFinder Type
1214
for flt in (Float16,Float32,Float64,Int8,Int16,Int32,Int64,Int128,
1315
UInt8,UInt16,UInt32,UInt64,UInt128)

src/src/OBBT/STD_LP_Probe.jl

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ that indicates the upper bound is finite. The upper bound is `UBD::Float64`.
1212
"""
1313
function STD_LP_Probe!(X::Vector{Interval{Float64}},opt,UBD::Float64)
1414

15+
mu_temp::Int64 = copy(EAGOSmoothMcCormickGrad.MC_param.mu)
16+
set_diff_relax(0)
17+
1518
# constructs LP relaxation
1619
Xlo::Vector{Float64} = [X[i].lo for i=1:opt[1].numVar]
1720
Xhi::Vector{Float64} = [X[i].hi for i=1:opt[1].numVar]
@@ -27,39 +30,52 @@ function STD_LP_Probe!(X::Vector{Interval{Float64}},opt,UBD::Float64)
2730
# probes upper bound
2831
f_mc::SMCg{opt[1].numVar,Float64} = opt[1].f(x_SMC)
2932
f_cv::Float64 = f_mc.cv
30-
c::Vector{SMCg{opt[1].numVar,Float64}} = opt[1].g(x_SMC)
31-
# forms coefficients of linear relaxations
32-
dcdx::SparseMatrixCSC{Float64,Int64} = spzeros(length(opt[1].gL_loc)+length(opt[1].gU_loc)+1,opt[1].numVar)
33+
if opt[1].numConstr>0
34+
c::Vector{SMCg{opt[1].numVar,Float64}} = opt[1].g(x_SMC)
35+
dcdx::SparseMatrixCSC{Float64,Int64} = spzeros(length(opt[1].gL_loc)+length(opt[1].gU_loc)+1,opt[1].numVar)
36+
else
37+
dcdx = spzeros(1,opt[1].numVar)
38+
end
39+
3340
dcdx[1,:] = f_mc.cv_grad
34-
cx_ind1::Int64 = 2
35-
for i in opt[1].gL_loc
36-
for j=1:opt[1].numVar
37-
if (c[i].cv_grad[j] != 0.0)
38-
dcdx[cx_ind1,j] = c[i].cv_grad[j]
41+
if opt[1].numConstr>0
42+
cx_ind1::Int64 = 2
43+
for i in opt[1].gL_loc
44+
for j=1:opt[1].numVar
45+
if (c[i].cv_grad[j] != 0.0)
46+
dcdx[cx_ind1,j] = c[i].cv_grad[j]
47+
end
3948
end
49+
cx_ind1 += 1
4050
end
41-
cx_ind1 += 1
42-
end
43-
for i in opt[1].gU_loc
44-
for j=1:opt[1].numVar
45-
if (c[i].cc_grad[j] != 0.0)
46-
dcdx[cx_ind1,j] = -c[i].cc_grad[j]
51+
for i in opt[1].gU_loc
52+
for j=1:opt[1].numVar
53+
if (c[i].cc_grad[j] != 0.0)
54+
dcdx[cx_ind1,j] = -c[i].cc_grad[j]
55+
end
4756
end
57+
cx_ind1 += 1
4858
end
49-
cx_ind1 += 1
5059
end
5160

5261
# forms rhs of linear relaxations
53-
rhs::Vector{Float64} = zeros(Float64,length(opt[1].gL_loc)+length(opt[1].gU_loc)+1)
54-
rhs[1] = UBD + f_mc.cv - sum(x0.*f_mc.cv_grad)
55-
cx_ind2::Int64 = 2
56-
for i in opt[1].gU_loc
57-
rhs[cx_ind2] = sum(x0[:].*c[i].cv_grad[:])+opt[1].gU[i]-c[i].cv
58-
cx_ind2 += 1
62+
if opt[1].numConstr>0
63+
rhs::Vector{Float64} = zeros(Float64,length(opt[1].gL_loc)+length(opt[1].gU_loc)+1)
64+
else
65+
rhs = zeros(Float64,1)
5966
end
60-
for i in opt[1].gL_loc
61-
rhs[cx_ind2] = sum(-x0[:].*c[i].cc_grad[:])-opt[1].gL[i]+c[i].cc
62-
cx_ind2 += 1
67+
rhs[1] = UBD + f_mc.cv - sum(x0.*f_mc.cv_grad)
68+
69+
if opt[1].numConstr>0
70+
cx_ind2::Int64 = 2
71+
for i in opt[1].gU_loc
72+
rhs[cx_ind2] = sum(x0[:].*c[i].cv_grad[:])+opt[1].gU[i]-c[i].cv
73+
cx_ind2 += 1
74+
end
75+
for i in opt[1].gL_loc
76+
rhs[cx_ind2] = sum(-x0[:].*c[i].cc_grad[:])-opt[1].gL[i]+c[i].cc
77+
cx_ind2 += 1
78+
end
6379
end
6480

6581
if (opt[1].numConstr>0)
@@ -78,8 +94,8 @@ function STD_LP_Probe!(X::Vector{Interval{Float64}},opt,UBD::Float64)
7894
val::Float64 = result.objval + f_cv - sum([x0[i]*f_mc.cv_grad[i] for i=1:opt[1].numVar])
7995
pnt::Vector{Float64} = result.sol
8096
mult::Vector{Float64} = result.attrs[:redcost]
81-
mult_lo::Vector{Float64} = [tol_eq(X[i].lo,pnt[i],1E-12) ? mult[i] : 0.0 for i=1:opt[1].numVar]
82-
mult_hi::Vector{Float64} = [tol_eq(X[i].hi,pnt[i],1E-12) ? mult[i] : 0.0 for i=1:opt[1].numVar]
97+
mult_lo::Vector{Float64} = [tol_eq(X[i].lo,pnt[i],opt[1].solver.dual_tol) ? mult[i] : 0.0 for i=1:opt[1].numVar]
98+
mult_hi::Vector{Float64} = [tol_eq(X[i].hi,pnt[i],opt[1].solver.dual_tol) ? mult[i] : 0.0 for i=1:opt[1].numVar]
8399
Variable_DR!(X,mult_lo,mult_hi,val,UBD)
84100
end
85101
# probes lower bound
@@ -90,11 +106,18 @@ function STD_LP_Probe!(X::Vector{Interval{Float64}},opt,UBD::Float64)
90106
val = result.objval + f_cv - sum([x0[i]*f_mc.cv_grad[i] for i=1:opt[1].numVar])
91107
pnt = result.sol
92108
mult = result.attrs[:redcost]
93-
mult_lo = [tol_eq(X[i].lo,pnt[i],1E-12) ? mult[i] : 0.0 for i=1:opt[1].numVar]
94-
mult_hi = [tol_eq(X[i].hi,pnt[i],1E-12) ? mult[i] : 0.0 for i=1:opt[1].numVar]
109+
mult_lo = [tol_eq(X[i].lo,pnt[i],opt[1].solver.dual_tol) ? mult[i] : 0.0 for i=1:opt[1].numVar]
110+
mult_hi = [tol_eq(X[i].hi,pnt[i],opt[1].solver.dual_tol) ? mult[i] : 0.0 for i=1:opt[1].numVar]
95111
Variable_DR!(X,mult_lo,mult_hi,val,UBD)
96112
end
97113
end
114+
115+
# reset McCormick relaxation to original value
116+
set_diff_relax(mu_temp)
117+
118+
# stores outputs
119+
X[:] = X
120+
return true
98121
end
99122

100123
"""

0 commit comments

Comments
 (0)