diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml new file mode 100644 index 0000000..0a6bb20 --- /dev/null +++ b/.JuliaFormatter.toml @@ -0,0 +1,6 @@ +margin = 100 +import_to_using = false +always_use_return = true +whitespace_in_kwargs = false +annotate_untyped_fields_with_any = true +always_for_in = true diff --git a/Project.toml b/Project.toml index 30004d2..537da44 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "CombinatorialLinearOracles" uuid = "0002e35e-4a6a-41c8-a2f5-6940c7e5949f" -authors = ["Mathieu Besançon and contributors"] +authors = ["ZIB-IOL and contributors"] version = "1.0.0-DEV" [deps] diff --git a/README.md b/README.md index c859a7e..53cf6e8 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,14 @@ [![Build Status](https://github.com/ZIB-IOL/CombinatorialLinearOracles.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/ZIB-IOL/CombinatorialLinearOracles.jl/actions/workflows/CI.yml?query=branch%3Amain) [![Coverage](https://codecov.io/gh/ZIB-IOL/CombinatorialLinearOracles.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/ZIB-IOL/CombinatorialLinearOracles.jl) + +This package is primarily a companion of [FrankWolfe.jl](https://github.com/ZIB-IOL/FrankWolfe.jl/) and implements several combinatorial linear minimization oracles, for instance for minimizing a linear function over a polytope defined by objects on graphs (spanning trees, matchings, ...). + +## Installation + +```julia +import Pkg +Pkg.add("https://github.com/ZIB-IOL/CombinatorialLinearOracles.jl") + +import CombinatorialLinearOracles +``` diff --git a/src/MatchingLinearOracle.jl b/src/MatchingLinearOracle.jl index 082f752..033c0cd 100644 --- a/src/MatchingLinearOracle.jl +++ b/src/MatchingLinearOracle.jl @@ -9,15 +9,10 @@ struct MatchingLMO{G} <: FrankWolfe.LinearMinimizationOracle graph::G end -function compute_extreme_point( - lmo::MatchingLMO, - direction::M; - v=nothing, - kwargs..., -) where {M} +function compute_extreme_point(lmo::MatchingLMO, direction::M; v=nothing, kwargs...) where {M} N = length(direction) v = spzeros(N) - if(nv(lmo.graph) % 2 != 0) + if (nv(lmo.graph) % 2 != 0) return v end iter = collect(Graphs.edges(lmo.graph)) @@ -25,12 +20,12 @@ function compute_extreme_point( for i in 1:N w[iter[i]] = direction[i] end - - match = GraphsMatching.minimum_weight_perfect_matching(lmo.graph,w) + + match = GraphsMatching.minimum_weight_perfect_matching(lmo.graph, w) K = length(match.mate) for i in 1:K for j in 1:N - if(match.mate[i] == src(iter[j]) && dst(iter[j]) == i) + if (match.mate[i] == src(iter[j]) && dst(iter[j]) == i) v[j] = 1 end end diff --git a/src/SpanningTreeLinearOracle.jl b/src/SpanningTreeLinearOracle.jl index 4aad915..e4681b2 100644 --- a/src/SpanningTreeLinearOracle.jl +++ b/src/SpanningTreeLinearOracle.jl @@ -9,26 +9,21 @@ struct SpanningTreeLMO{G} <: FrankWolfe.LinearMinimizationOracle graph::G end -function compute_extreme_point( - lmo::SpanningTreeLMO, - direction::M; - v=nothing, - kwargs..., -) where {M} +function compute_extreme_point(lmo::SpanningTreeLMO, direction::M; v=nothing, kwargs...) where {M} N = length(direction) iter = collect(Graphs.edges(lmo.graph)) - distmx = spzeros(N,N) + distmx = spzeros(N, N) for idx in 1:N - if(direction[idx] > 0) - distmx[src(iter[idx]),dst(iter[idx])] = direction[idx] - distmx[dst(iter[idx]),src(iter[idx])] = direction[idx] + if (direction[idx] > 0) + distmx[src(iter[idx]), dst(iter[idx])] = direction[idx] + distmx[dst(iter[idx]), src(iter[idx])] = direction[idx] end end - span = Graphs.kruskal_mst(lmo.graph,distmx) + span = Graphs.kruskal_mst(lmo.graph, distmx) v = spzeros(N) for edge in span for i in 1:N - if(src(edge) == src(iter[i]) && dst(edge) == dst(iter[i])) + if (src(edge) == src(iter[i]) && dst(edge) == dst(iter[i])) v[i] = 1 end end diff --git a/test/runtests.jl b/test/runtests.jl index b3f0e28..3aebc92 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -11,18 +11,18 @@ using Graphs M = length(iter) direction = randn(M) lmo = CombinatorialLinearOracles.MatchingLMO(g) - v = CombinatorialLinearOracles.compute_extreme_point(lmo,direction) + v = CombinatorialLinearOracles.compute_extreme_point(lmo, direction) tab = zeros(M) is_matching = true for i in 1:M - if(v[i] == 1) + if (v[i] == 1) is_matching = (tab[src(iter[i])] == 0 && tab[dst(iter[i])] == 0) - if(!is_matching) + if (!is_matching) break end tab[src(iter[i])] = 1 tab[dst(iter[i])] = 1 - end + end end @test is_matching == true end @@ -35,13 +35,12 @@ end M = length(iter) direction = randn(M) lmo = CombinatorialLinearOracles.SpanningTreeLMO(g) - v = CombinatorialLinearOracles.compute_extreme_point(lmo,direction) - tree = Array{Edge}(undef,(0,)) + v = CombinatorialLinearOracles.compute_extreme_point(lmo, direction) + tree = Array{Edge}(undef, (0,)) for i in 1:M - if(v[i] == 1) - push!(tree,iter[i]) + if (v[i] == 1) + push!(tree, iter[i]) end end @test Graphs.is_tree(SimpleGraphFromIterator(tree)) == true end -