Skip to content

Commit

Permalink
Merge changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hendrych committed Oct 19, 2023
2 parents 005db86 + f47ce9c commit 512d5cb
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 115 deletions.
7 changes: 3 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
name = "Boscia"
uuid = "36b166db-dac5-4d05-b36a-e6c4cef071c9"
authors = ["ZIB IOL"]
version = "0.1.9"
version = "0.1.12"

[deps]
Bonobo = "f7b14807-3d4d-461a-888a-05dd4bca8bc3"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FrankWolfe = "f55ce6ea-fdc5-4628-88c5-0087fe54bd30"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Expand All @@ -16,7 +15,6 @@ Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SCIP = "82193955-e24f-5292-bf16-6f2c5261a85f"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[compat]
Bonobo = "0.1.3"
Expand All @@ -30,8 +28,9 @@ SCIP = "0.11"
julia = "1.6"

[extras]
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "HiGHS"]
test = ["Test", "HiGHS", "Distributions"]
10 changes: 8 additions & 2 deletions examples/mps-examples/mip-examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ seed = rand(UInt64)
@show seed
Random.seed!(seed)

example = "neos5"
# To see debug statements
#ENV["JULIA_DEBUG"] = "Boscia"

example = "n5-3"

function build_example(example, num_v)
file_name = string(example, ".mps")
Expand All @@ -38,6 +41,9 @@ function build_example(example, num_v)
n = MOI.get(o, MOI.NumberOfVariables())
lmo = FrankWolfe.MathOptLMO(o)

# Disable Presolving
MOI.set(o, MOI.RawOptimizerAttribute("presolving/maxrounds"), 0)

#trick to push the optimum towards the interior
vs = [FrankWolfe.compute_extreme_point(lmo, randn(n)) for _ in 1:num_v]
# done to avoid one vertex being systematically selected
Expand Down Expand Up @@ -88,7 +94,7 @@ test_instance = string("MPS ", example, " instance")
@testset "$test_instance" begin
println("Example $(example)")
lmo, f, grad! = build_example(example, num_v)
x, _, result = Boscia.solve(f, grad!, lmo, verbose=true, print_iter = 10, fw_epsilon = 1e-1, min_node_fw_epsilon = 1e-3, time_limit=2000)
x, _, result = Boscia.solve(f, grad!, lmo, verbose=true, print_iter = 10, fw_epsilon = 1e-1, min_node_fw_epsilon = 1e-3, time_limit=600)
@test f(x) <= f(result[:raw_solution])
end

1 change: 0 additions & 1 deletion src/callbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ function build_FW_callback(tree, min_number_lower, check_rounding_value::Bool, f
check_infeasible_vertex(tree.root.problem.tlmo.blmo, tree)
@assert is_linear_feasible(tree.root.problem.tlmo, state.v)
end
# @assert is_linear_feasible(tree.root.problem.lmo, state.x)
push!(fw_iterations, state.t)

if state.lmo !== nothing # can happen with using Blended Conditional Gradient
Expand Down
9 changes: 8 additions & 1 deletion src/frank_wolfe_variants.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function solve_frank_wolfe(
extra_vertex_storage=nothing,
callback=nothing,
lazy=false,
lazy_tolerance=2.0,
timeout=Inf,
verbose=false,
workspace=nothing
Expand All @@ -62,7 +63,8 @@ function solve_frank_wolfe(
max_iteration=max_iteration,
line_search=line_search,
callback=callback,
lazy=lazy,
lazy=lazy,
lazy_tolerance=lazy_tolerance,
timeout=timeout,
add_dropped_vertices=add_dropped_vertices,
use_extra_vertex_storage=use_extra_vertex_storage,
Expand Down Expand Up @@ -95,6 +97,7 @@ function solve_frank_wolfe(
extra_vertex_storage=nothing,
callback=nothing,
lazy=false,
lazy_tolerance=2.0,
timeout=Inf,
verbose=false,
workspace=nothing
Expand All @@ -113,6 +116,7 @@ function solve_frank_wolfe(
callback=callback,
timeout=timeout,
verbose=verbose,
lazy_tolerance=lazy_tolerance,
)

return x, primal, dual_gap, active_set
Expand All @@ -139,6 +143,7 @@ function solve_frank_wolfe(
extra_vertex_storage=nothing,
callback=nothing,
lazy=false,
lazy_tolerance=2.0,
timeout=Inf,
verbose=false,
workspace=nothing
Expand All @@ -156,6 +161,7 @@ function solve_frank_wolfe(
extra_vertex_storage=extra_vertex_storage,
callback=callback,
lazy=lazy,
lazy_tolerance=lazy_tolerance,
timeout=timeout,
verbose=verbose
)
Expand Down Expand Up @@ -188,6 +194,7 @@ function solve_frank_wolfe(
extra_vertex_storage=nothing,
callback=nothing,
lazy=false,
lazy_tolerance=2.0,
timeout=Inf,
verbose=false,
workspace=nothing
Expand Down
35 changes: 25 additions & 10 deletions src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,14 @@ variant - variant of FrankWolfe to be used to solve the node prob
AFW -- Away FrankWolfe
BPCG -- Blended Pairwise Conditional Gradient
line_search - specifies the Line Search method used in the FrankWolfe variant.
Default is the Adaptive Line Search. For other types, check the FrankWolfe.jl package.
Default is the Adaptive Line Search. For other types, check the FrankWolfe.jl package.
active_set - can be used to specify a starting point, e.g. if the feasible region is not completely
contained in the domain of the objective. By default, the direction (1,..,n) where n is
the size of the problem is used to find a start vertex. Beware that the active set may
only contain actual vertices of the feasible region.
lazy - specifies whether the lazification shoud be used. Per default true.
Beware that it has no effect with Vanilla Frank-Wolfe.
lazy_tolerance - decides how much progress is deemed enough to not have to call the LMO.
fw_epsilon - the tolerance for FrankWolfe in the root node.
verbose - if true, a log and solution statistics are printed.
dual_gap - if this absolute dual gap is reached, the algorithm stops.
Expand Down Expand Up @@ -115,6 +122,8 @@ function solve(
variant::FrankWolfeVariant=BPCG(),
line_search::FrankWolfe.LineSearchMethod=FrankWolfe.Adaptive(),
active_set::Union{Nothing, FrankWolfe.ActiveSet} = nothing,
lazy=true,
lazy_tolerance = 2.0,
fw_epsilon=1e-2,
verbose=false,
dual_gap=1e-6,
Expand Down Expand Up @@ -144,6 +153,8 @@ function solve(
println("\t Branching strategy: ", _value_to_print(branching_strategy))
println("\t FrankWolfe variant: $(variant)")
println("\t Line Search Method: $(line_search)")
println("\t Lazification: $(lazy)")
lazy ? println("\t Lazification Tolerance: $(lazy_tolerance)") : nothing
@printf("\t Absolute dual gap tolerance: %e\n", dual_gap)
@printf("\t Relative dual gap tolerance: %e\n", rel_dual_gap)
@printf("\t Frank-Wolfe subproblem tolerance: %e\n", fw_epsilon)
Expand Down Expand Up @@ -231,20 +242,22 @@ function solve(
),
global_tightenings = IntegerBounds(),
options=Dict{Symbol,Any}(
:dual_gap_decay_factor => dual_gap_decay_factor,
:domain_oracle => domain_oracle,
:dual_gap => dual_gap,
:print_iter => print_iter,
:max_fw_iter => max_fw_iter,
:min_node_fw_epsilon => min_node_fw_epsilon,
:time_limit => time_limit,
:dual_gap_decay_factor => dual_gap_decay_factor,
:dual_tightening => dual_tightening,
:fwVerbose => fw_verbose,
:global_dual_tightening => global_dual_tightening,
:strong_convexity => strong_convexity,
:variant => variant,
:lazy => lazy,
:lazy_tolerance => lazy_tolerance,
:lineSearch => line_search,
:domain_oracle => domain_oracle,
:min_node_fw_epsilon => min_node_fw_epsilon,
:max_fw_iter => max_fw_iter,
:print_iter => print_iter,
:strong_convexity => strong_convexity,
:time_limit => time_limit,
:usePostsolve => use_postsolve,
:fwVerbose => fw_verbose,
:variant => variant,
),
),
branch_strategy=branching_strategy,
Expand All @@ -271,6 +284,8 @@ function solve(
if size(start_solution) != size(v)
error("size of starting solution differs from vertices: $(size(start_solution)), $(size(v))")
end
# Sanity check that the provided solution is in fact feasible.
@assert is_linear_feasible(lmo, start_solution) && is_integer_feasible(tree, start_solution)
node = tree.nodes[1]
sol = FrankWolfeSolution(f(start_solution), start_solution, node, :start)
push!(tree.solutions, sol)
Expand Down
Loading

0 comments on commit 512d5cb

Please sign in to comment.