class_docstr: Class for representing Junction Tree.
  
  Junction tree is undirected graph where each node represents a clique
  (list, tuple or set of nodes) and edges represent sepset between two cliques.
  Each sepset in G separates the variables strictly on one side of edge to
  other.
  
  Parameters
  ----------
  data: input graph
      Data to initialize graph. If data=None (default) an empty graph is
      created. The data is an edge list.
  
  Examples
  --------
  Create an empty JunctionTree with no nodes and no edges
  
  >>> from pgmpy.models import JunctionTree
  >>> G = JunctionTree()
  
  G can be grown by adding clique nodes.
  
  **Nodes:**
  
  Add a tuple (or list or set) of nodes as single clique node.
  
  >>> G.add_node(('a', 'b', 'c'))
  >>> G.add_nodes_from([('a', 'b'), ('a', 'b', 'c')])
  
  **Edges:**
  
  G can also be grown by adding edges.
  
  >>> G.add_edge(('a', 'b', 'c'), ('a', 'b'))
  
  or a list of edges
  
  >>> G.add_edges_from([(('a', 'b', 'c'), ('a', 'b')),
  ...                   (('a', 'b', 'c'), ('a', 'c'))])
docstr: Returns a copy of JunctionTree.
  
  Returns
  -------
  JunctionTree : copy of JunctionTree
  
  Examples
  --------
  >>> import numpy as np
  >>> from pgmpy.factors.discrete import DiscreteFactor
  >>> from pgmpy.models import JunctionTree
  >>> G = JunctionTree()
  >>> G.add_edges_from([(('a', 'b', 'c'), ('a', 'b')), (('a', 'b', 'c'), ('a', 'c'))])
  >>> phi1 = DiscreteFactor(['a', 'b'], [1, 2], np.random.rand(2))
  >>> phi2 = DiscreteFactor(['a', 'c'], [1, 2], np.random.rand(2))
  >>> G.add_factors(phi1,phi2)
  >>> modelCopy = G.copy()
  >>> modelCopy.edges()
  EdgeView([(('a', 'b'), ('a', 'b', 'c')), (('a', 'c'), ('a', 'b', 'c'))])
  >>> G.factors
  [<DiscreteFactor representing phi(a:1, b:2) at 0xb720ee4c>,
   <DiscreteFactor representing phi(a:1, c:2) at 0xb4e1e06c>]
  >>> modelCopy.factors
  [<DiscreteFactor representing phi(a:1, b:2) at 0xb4bd11ec>,
   <DiscreteFactor representing phi(a:1, c:2) at 0xb4bd138c>]
code: def copy(self):
      """
      Returns a copy of JunctionTree.
  
      Returns
      -------
      JunctionTree : copy of JunctionTree
  
      Examples
      --------
      >>> import numpy as np
      >>> from pgmpy.factors.discrete import DiscreteFactor
      >>> from pgmpy.models import JunctionTree
      >>> G = JunctionTree()
      >>> G.add_edges_from([(('a', 'b', 'c'), ('a', 'b')), (('a', 'b', 'c'), ('a', 'c'))])
      >>> phi1 = DiscreteFactor(['a', 'b'], [1, 2], np.random.rand(2))
      >>> phi2 = DiscreteFactor(['a', 'c'], [1, 2], np.random.rand(2))
      >>> G.add_factors(phi1,phi2)
      >>> modelCopy = G.copy()
      >>> modelCopy.edges()
      EdgeView([(('a', 'b'), ('a', 'b', 'c')), (('a', 'c'), ('a', 'b', 'c'))])
      >>> G.factors
      [<DiscreteFactor representing phi(a:1, b:2) at 0xb720ee4c>,
       <DiscreteFactor representing phi(a:1, c:2) at 0xb4e1e06c>]
      >>> modelCopy.factors
      [<DiscreteFactor representing phi(a:1, b:2) at 0xb4bd11ec>,
       <DiscreteFactor representing phi(a:1, c:2) at 0xb4bd138c>]
  
      """
      copy = JunctionTree(self.edges())
      copy.add_nodes_from(self.nodes())
      if self.factors:
          factors_copy = [factor.copy() for factor in self.factors]
          copy.add_factors(*factors_copy)
      return copy
  
file_path: pgmpy/pgmpy/models/JunctionTree.py
imports: import networkx
  from pgmpy.models import ClusterGraph
label_desc: Use image node_id 5 for calling the JunctionTree obj's underlying member method code with example usage: obj.copy() and returns: copy