Skip to content

Commit f2cf29d

Browse files
olegfafuringdalle
andauthored
Vertex cover (#19)
* add vertex cover * add vertex cover * fix test and rename method * docs * fix docs + small fixes * fix missing docstring --------- Co-authored-by: Guillaume Dalle <22795598+gdalle@users.noreply.github.com>
1 parent d87b65d commit f2cf29d

File tree

5 files changed

+100
-0
lines changed

5 files changed

+100
-0
lines changed

docs/src/algorithms.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ min_cost_assignment
6161
GraphsOptim.min_cost_assignment!
6262
```
6363

64+
## Minimum Vertex Cover
65+
66+
```@docs
67+
min_vertex_cover
68+
GraphsOptim.min_vertex_cover!
69+
```
70+
71+
Finds a subset $S \subset V$ of vertices of an undirected graph $G = (V,E)$ such that $\forall (u,v) \in E: u \in S \lor v \in S$
72+
6473
## Graph matching
6574

6675
!!! danger "Work in progress"

src/GraphsOptim.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ using OptimalTransport: sinkhorn
2323
export min_cost_flow
2424
export min_cost_assignment
2525
export FAQ, GOAT, graph_matching
26+
export min_vertex_cover
2627
export fractional_chromatic_number, fractional_clique_number
2728
export shortest_path
2829

2930
include("utils.jl")
3031
include("flow.jl")
3132
include("assignment.jl")
3233
include("graph_matching.jl")
34+
include("min_vertex_cover.jl")
3335
include("fractional_coloring.jl")
3436
include("shortest_path.jl")
3537

src/min_vertex_cover.jl

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""
2+
min_vertex_cover!(
3+
model, g;
4+
var_name
5+
)
6+
7+
Modify a JuMP model by adding the variable, constraints and objective necessary to compute a minimum vertex cove of an undirected graph.
8+
9+
The vertex cover indicator variable will be named `var_name`
10+
"""
11+
function min_vertex_cover!(model::Model, g::AbstractGraph; integer::Bool, var_name)
12+
if is_directed(g)
13+
throw(ArgumentError("The graph must not be directed"))
14+
end
15+
16+
ver = collect(vertices(g))
17+
18+
f = @variable(model, [ver]; integer=integer, base_name=String(var_name))
19+
model[Symbol(var_name)] = f
20+
21+
for v in ver
22+
@constraint(model, f[v] >= 0)
23+
@constraint(model, f[v] <= 1)
24+
end
25+
26+
for e in edges(g)
27+
@constraint(model, f[src(e)] + f[dst(e)] >= 1)
28+
end
29+
30+
obj = objective_function(model)
31+
for v in ver
32+
add_to_expression!(obj, f[v])
33+
end
34+
@objective(model, Min, obj)
35+
36+
return model
37+
end
38+
39+
"""
40+
min_vertex_cover(
41+
g, optimizer
42+
)
43+
44+
Compute a minimum vertex cover of an undirected graph.
45+
46+
# Arguments
47+
48+
- `g::Graphs.AbstractGraph`: an undirected graph `G = (V, E)`
49+
50+
# Keyword arguments
51+
52+
- `optimizer`: JuMP-compatible solver (default is `HiGHS.Optimizer`)
53+
"""
54+
function min_vertex_cover(g::AbstractGraph; integer::Bool=true, optimizer=HiGHS.Optimizer)
55+
model = Model(optimizer)
56+
set_silent(model)
57+
58+
min_vertex_cover!(model, g; integer=integer, var_name=:cover)
59+
60+
optimize!(model)
61+
@assert termination_status(model) == OPTIMAL
62+
63+
cover_values = Vector(value.(model[:cover]))
64+
cover_vertices = findall(==(1), cover_values)
65+
66+
return cover_vertices
67+
end

test/min_vertex_cover.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Graphs: SimpleGraph
2+
using GraphsOptim
3+
using Test
4+
5+
adj_matrix = [
6+
0 1 1 0 0 0
7+
1 0 1 1 1 1
8+
1 1 0 0 0 0
9+
0 1 0 0 0 0
10+
0 1 0 0 0 0
11+
0 1 0 0 0 0
12+
]
13+
14+
expected_ans_options = [Set([1, 2]), Set([2, 3])]
15+
16+
graph = SimpleGraph(adj_matrix)
17+
18+
@test Set(min_vertex_cover(graph)) in expected_ans_options

test/runtests.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ using Test
4040
include("graph_matching.jl")
4141
end
4242

43+
@testset verbose = true "Vertex cover" begin
44+
include("min_vertex_cover.jl")
45+
end
46+
4347
@testset verbose = true "Fractional coloring" begin
4448
include("fractional_coloring.jl")
4549
end

0 commit comments

Comments
 (0)