How to generate and draw simple bipartite graphs?
You can use BipartiteEmbedding
:
Graph[{3, 2, 1, z, y, x}, DirectedEdge@@@{{1, x}, {1, y}, {1, z}, {2, x}, {2, y}, {3, x}},
GraphLayout -> "BipartiteEmbedding" ,
VertexLabels -> "Name", ImagePadding -> 15, VertexLabelStyle -> 16]
Mathematica automatically determines the vertex coordinates.
One way is to specify VertexCoordinates
:
g=Graph[{1 <-> x, 1 <-> y,
1 <-> z, 2 <-> x, 2 <-> y,
3 <-> x},
VertexCoordinates -> {{0, 2}, {1, 2}, {1, 1}, {1, 0}, {0, 1}, {0,
0}}]
Note that the vertices {v1, v2, ...} are given in the order returned by VertexList
.
VertexList[g]
(* {1, x, y, z, 2, 3} *)
Update
To automatize a bit the generation of bipartite graphs the way you want you could use this function:
bipartiteGraph[elements_List] := Module[{g1, el, c1, c2, cc, vrt},
g1 = Graph[
MapThread[
UndirectedEdge, {Sort[elements][[All, 1]],
Sort[elements][[All, 2]]}]];
el = VertexList[g1];
c1 = Transpose[{Select[el, IntegerQ],
Table[{0, i}, {i, 1, 0, -1/(Length[Select[el, IntegerQ]] - 1)}]}];
c2 = Transpose[{Complement[el, Select[el, IntegerQ]],
Table[{1, i}, {i, 1,
0, -1/(Length[Complement[el, Select[el, IntegerQ]]] - 1)}]}];
cc = Join[c1, c2];
vrt = cc[[Table[Position[cc, el[[i]]], {i, Length[cc]}][[All, 1,
1]], 2]];
Graph[MapThread[
UndirectedEdge, {Sort[elements][[All, 1]],
Sort[elements][[All, 2]]}], VertexCoordinates -> vrt,
VertexLabels -> "Name", VertexLabelStyle -> 16,
ImagePadding -> 20]
]
bipartiteGraph[{{1, x}, {1, y}, {1, z},{2, x}, {2, y}, {3, x}}]
bipartiteGraph[{{4, p}, {1, x}, {1, y}, {1, z}, {2, x}, {2, y}, {3, x}, {4, r}}]
GraphicsGrid[Partition[
Table[bipartiteGraph[
Union[Transpose[{RandomInteger[{1, 4}, 8],
RandomChoice[CharacterRange["a", "d"], 8]}]]], {16}], 4]]
This is a bit different approach. A balanced bipartite graph (where the two vertex sets have the same cardinality, $N$) can be represented as an adjacency matrix, where the rows and columns of the matrix stand for the left and right side vertices, respectively. This approach generates a random adjacency matrix and translates it to edges, representing left nodes as $(1, 2, ..., N)$ and right nodes as $(N+1, N+2, ..., 2N)$. Letters are only used for labelling right-side vertices.
n = 5; (* node number of ONE side of the graph *)
m = RandomInteger[{0, 1}, {n, n}];
adjacencyToEdge[m_List] := Module[{n = Length@m},
DeleteCases[Flatten@Table[If[m[[i, j]] == 1, i -> n + j], {i, n}, {j, n}], Null]];
Row@{
Graph[Range[2 n], adjacencyToEdge@m,
VertexCoordinates -> Join[
Table[{0, 1 - i/n}, {i, n}], Table[{1, 1 - i/n}, {i, Length@m}]],
VertexLabels -> Join[
Thread[Range@n -> Range@n],
Thread[Range[n + 1, 2 n] -> Take[CharacterRange["a", "z"], n]]],
ImagePadding -> 10, VertexLabelStyle -> 16, ImageSize -> 300],
MatrixForm@m}
Note that even unconnected nodes are placed at the correct position (which GraphLayout -> "BipartiteEmbedding"
won't do).