-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for bipartite graphs #38
Comments
I like the idea of modelling bipartite graphs. Not sure how to model partition membership though. One option is to demand that membership in a partition A or B should be deducible from the vertex label. Perhaps this could be modeled using Alternatively, we could also introduce new primitives for controlling partition membership, like |
@boggle Oops. Somehow I didn't realise we need to do this. Indeed, if we'd like to abstract over bipartite graphs and, for example, have a generic algorithm for bipartite matching, then we need to expose the partitions. Seems to be a pretty large design space, again. |
I came up with this: https://github.com/snowleopard/alga/compare/master...boggle:bipartite?expand=1 Observations:
|
@boggle Thanks for the experiment! It looks like some of the complications in the code are due to the fact that you make sure that no edges are created inside partitions. However, we don't necessarily need to do that, because the law says it's OK to have edges inside a partition -- they don't matter and can later be removed. For example, consider expressions We can of course allow the user to obtain a canonical representation of a bipartite graph, by providing a function like One aspect which is unclear to me is how to properly define the {-|
The class of /bipartite graphs/ that splits vertices into two partitions A and B
and satisfies the following axiom
* u + v = u * v for all u,v \in A or u,v \in B
-}
class Graph g => Bipartite g It feels awkward that the law refers to non-existing notions We could add a predicate, e.g. |
Agreed, we shouldn't rule out any valid algebraic description of a bipartite graph. However what is the end goal for alga? Right now it seems to be focused primarily on being able to construct graphs using the algebra in a way that allows using different representations. I would expect that mid to long term actual operations on graphs that extract data (triangle counts, connected components, ...) would be considered very useful. One would probably not want to implement those again for different classes of graphs (bipartite, undirected) if possible and rather implement them by e.g. transforming a bipartite graph to a regular graph without intra-partition edges. One way of achieving this is by going via an edge list, although this feels unnecessarily sequential. In the experiment, I was trying to instead construct such a graph inside On the topic of representing partitions, I see only two viable options:
I think using predicates Also, only providing instances like |
@boggle Indeed, at the moment Alga is not very useful. It can construct various graphs, but the rest of the functionality is poor and can be split into two categories:
Yes, of course! However, most interesting algorithms (even as simple as triangle counts) are non-trivial to implement directly in the algebraic graph representation. I'm working on several algorithms at the moment, starting with very basic ones such as Note that most algorithms are also very sensitive to the actual graph and to get the best performance you actually need to write different algorithms for general graphs and for bipartite graphs. As a representative example, consider the matching problem -- it's relatively easy for unweighted bipartite graphs, but becomes much harder for general graphs and/or for weighted graphs. Alas, we can't hope to reuse any code here.
Can you give a specific example of an algorithm you'd like to run on bipartite graphs? Let's see if we can find a way to reuse some code for general and for bipartite graphs for a specific example -- perhaps this could help us figure out the best design. |
After reading the discussion, one thing is not clear: Do we need/want to express vertices types in the type of a
I personally prefer the first option, because I think type-safe functions are very important, and it will allows a very clean syntax (like
About the matching problem on unweighted graphs, there is the Hopcroft–Karp algorithm which provide the maximum matching in a bipartite graph. There are much simpler/common ones like the Hungarian Algorithm but there are for edge labeled graphs, so maybe not for now in alga. |
@nobrakal I also prefer the typed variant. If we summarise the discussions so far, we can have something like: {-|
The class of /bipartite graphs/ whose vertices are partitioned into two parts L (left)
and R (right), such that there are no edges within parts. Bipartite graphs satisfy the
following axiom:
* u + v = u * v for all u,v \in L or u,v \in R
-}
class Graph g => Bipartite g
type LeftPart g
type RightPart g
partition :: Vertex g -> Either (LeftPart g) (RightPart g)
We will have labelled graphs soon! :-) |
I think we can close this issue. We don't have an algebraic implementation yet but |
https://en.wikipedia.org/wiki/Bipartite_graph
Note that
Graph (Either a b)
with vertices of typesa
andb
allows connecting vertices of the same type, that is, the resulting graph is not bipartite.One possible approach to this has been discussed in this twitter thread.
The text was updated successfully, but these errors were encountered: