function [ adj, nedge ] = graph_adj_random_bipartite ( nnode1, nnode2 )

%*****************************************************************************80
%
%% graph_adj_random_bipartite() generates a random bipartite graph.
%
%  Definition:
%
%    A bipartite graph has the property that its nodes may be divided
%    into two groups, NODE1 and NODE2, with the property that the only
%    edges in the graph are between a node in NODE1 and a node in NODE2.
%
%  Licensing:
%
%    This code is distributed under the MIT license. 
%
%  Modified:
%
%    25 March 2023
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer NNODE1, NNODE2, the number of nodes in the 
%    first and second groups of nodes.
%
%  Output:
%
%    integer NEDGE, the number of edges.
%
%    integer ADJ(NNODE1+NNODE2,NNODE1+NNODE2), the adjacency matrix.
%
  if ( nnode1 <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'graph_adj_random_bipartite(): Fatal error!\n' );
    fprintf ( 1, '  NNODE1 = %d\n', nnode1 );
    fprintf ( 1, '  but NNODE1 must be at least 1.\n' );
    error (  'graph_adj_random_bipartite(): Fatal error!\n' );
  end

  if ( nnode2 <= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'graph_adj_random_bipartite(): Fatal error!\n' );
    fprintf ( 1, '  NNODE2 = %d\n', nnode2 );
    fprintf ( 1, '  but NNODE2 must be at least 1.\n' );
    error (  'graph_adj_random_bipartite(): Fatal error!\n' );
  end

  nnode = nnode1 + nnode2;
  nedge = 0;

  adj = zeros ( nnode, nnode );
%
%  For each node in the NODE1 group, 
%  consider a edge to each node in the NODE2 group.
%
  for i = 1 : nnode1
    for j = nnode1 + 1 : nnode1 + nnode2

      k = randi ( [ 0, 1 ] );

      adj(i,j) = k;
      adj(j,i) = k;
      nedge = nedge + k;

    end
  end
%
%  Now perform a random permutation of the rows and columns.
%
  adj = i4mat_perm_random ( adj );

  return
end
