Skip to content
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

Introduce a PartitionedGraph Type #41

Closed
JoeyT1994 opened this issue Dec 6, 2023 · 2 comments
Closed

Introduce a PartitionedGraph Type #41

JoeyT1994 opened this issue Dec 6, 2023 · 2 comments

Comments

@JoeyT1994
Copy link
Contributor

JoeyT1994 commented Dec 6, 2023

We should introduce a PartitionedGraph structure. Ideally this should be separate from NamedGraphs and just be an abstract graph type with the relevant functionality. For now though we will make a PartitionedGraphs.jl submodule within NamedGraphs.jl.

The general structure could look like

abstract type AbstractPartitionedGraph{V,PV} <: AbstractGraph{V} end

struct PartitionedGraph{V,PV,G<:AbstractGraph{V},PG<:AbstractGraph{PV}} <: AbstractPartitionedGraph{PV}
  graph::G
  partioned_graph::PG
  partition_vertices::Dictionary{PV,Vector{V}}
  partition::Dictionary{V,PV}
end

such that a partitioned graph essentially consists of two graphs: the original graph G and the partitioned graph PG. The structure then also contains a map (and its reverse) between the subsets of vertices of G which consistute the vertices of PG.

We then need to define functionality for this structure. It would make sense to define standard Graphs.jl calls on a PartitionedGraph to pass to the original graph G. For instance vertices(pg::PartitionedGraph) = vertices(pg.G) Then we define partitioned versions of those calls which operate on PG instead. E.g. partitioned_vertices(pg::PartitionedGraph) = vertices(pg.PG).
Other examples of such functions might be has_vertex versus partitioned_has_vertex, is_tree versus partitioned_is_tree etc.

Helpful functions might then be determining whether an edge of G is within a partition or between partitions. And which partitions.
E.g

function edge_partitions(e::AbstractEdge, PG::PartitionedGraph)
   return find_key(PG.partition, src(e)), find_key(PG.partition, dst(e))
end

function edge_in_partition(e::AbstractEdge, PG::PartitionedGraph)
  return all_equal(edge_partitions(e, PG))
end

Another question is whether we define types such as PartitionedVertex and PartitionedEdge so that calls such as has_vertex(PG, PartitionedVertex(1)) pass directly to partitioned_has_vertex. This is mostly for convenience.

@mtfishman

@JoeyT1994
Copy link
Contributor Author

We should also define default constructors for a PartitionedGraph.

For instance PartitionedGraph(G::AbstractGraph, partition_vertices::Vector{Vector{V}}) should return a partitioned graph which defaults to integer naming for the vertices of PG. This works by constructing the relevant dictionary with integer keys and passing to the constructor PartitionedGraph(G::AbstractGraph, partition_vertices::Dictionary{PV,Vector{V}}).

Meanwhile we should consider constructors such as PartitionedGraph(G::AbstractGraph, npartitions::Integer; kwargs) which constructs a partitioned graph from G (defaulting to integer naming) with npartitions. The default construction could be via some sort min_cut search and corresponding algorithms already exist in KaHyPar and Metis. This would supersede the current functionality in ITensorNetworks/src/partition.jl which has some code for partitioned_graphs.

@mtfishman
Copy link
Member

Closed by #44.

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

No branches or pull requests

2 participants