Skip to content
This repository has been archived by the owner on Oct 22, 2021. It is now read-only.

[WIP] Feature cardinality matching #18

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Wikunia
Copy link
Contributor

@Wikunia Wikunia commented Nov 17, 2019

Finding a maximum cardinality matching using a simple BFS algorithm to increase the matching weight by 1 every time.
Implements #15
Might be helpful to have more test cases.

Requesting review @matbesancon

Current version only works for bipartite graphs.

matching[e.dst] = e.src
matching_len += 1
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be a good idea, to have this as a separate function? Then it could also be used for finding a greed maximal cardinality matching and be used by other functions. We could pass it in as an optional argument or a keyword argument.

Furthermore, I was thinking, maybe it would be more efficient to loop over the vertices and then over all neighbors of that vertex? I.e something like

for u in vertices(g)
   matching[u] == -1 || continue
   for v in neighbors[u]
      u <= v && continue
      matching[u] = v
      matching[v] = u
     matching_len += 1
   end
end

This approach only works, if we assume that vertices(g) is ordered in increasing order, but it can also be adapted, such that the increasing order is not required.

Also, be careful with self-loops, these should never be in a matching.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If neighbors is implemented in a fast manner yes. Thought that looping over the edges might be faster than accessing the neighbors but yours has an earlier break. Maybe I can test it on a larger graph. Good point with self loops!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for SimpleGraphthe edges iterator is implemented using neighbors anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is now a separate function but still uses edges for now.

@simonschoelly
Copy link
Contributor

It's kind of late here, so I cannot check now, but does your algorithm handle graphs with odd cycles correctly? Odd cycles are the main reason why maximum matching is non-trivial and why Edmonds came up with his blossom algorithm.

@Wikunia
Copy link
Contributor Author

Wikunia commented Nov 17, 2019

Yes it's too late here as well. You have a good point though. I came here from bipartite matchings. The algorithm fails because it doesn't allow odd cycles. Works for bipartite graphs because that can't happen there. Learned something again today. Thanks for pointing it out. Either I can check if the graph is bipartite or the PR can be removed as the Blossom algorithm will have the same runtime for bipartite graphs there is no real gain.

@Wikunia Wikunia changed the title Feature cardinality matching [WIP] Feature cardinality matching Nov 18, 2019
@bilelomrani1
Copy link

Is this still worked on? If I may, here is a proposition:
In SpecialGraphs.jl, there is a special concrete type called CompleteBipartiteGraph which directly subtype AbstractGraph. I suggest creating an AbstractBipartiteGraph and having something like

abstract type AbstractBipartiteGraph <: AbstractGraph end

struct BipartiteGraph <: AbstractBipartiteGraph
    ...
end

struct CompleteBipartiteGraph <: AbstractBipartiteGraph
    ...
end

You could then dispatch this PR's maximum_cardinality_matching on AbstractBipartiteGraph to ensure correctness while having a dependency-less method for solving maximum matching in bipartite graphs (which is common enough to have a specialized method I believe, and this can prove to be more efficient than solving an LP for the general case)

@matbesancon
Copy link
Member

@bilelomrani1 hi! If you get the PR in SpecialGraphs feel free to ping me for review

@bilelomrani1
Copy link

Hi @matbesancon, actually I was thinking about filing an issue to get some discussion going around leveraging graph structures for solving graph theoretic problems (including matching). I don't know if special concrete types are the best solution because some graphs may exhibit very special structure (e.g. planar-bipartite) and it does not play nicely with the hierarchical type system.
I think a better approach would be something similar to what has been done in DifferentialEquations.jl: a single function to solve the problem (graph coloring, maximum cardinality matching, etc.) but with the flexibility of provinding a solver dedicated to some structure (with nice documentation about the assumption made by the solver, like bipartiteness in this case). I noticed that this approach has been adopted in LightGraphsFlows.jl but not in other parts of the ecosystem, which is a bit inconsistent.
Where do you think this issue should go?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants