code: def a_star_search(
      G1, G2, cost_matrix_nodes, cost_matrix_edges, max_beam_size
  ):
      # A-star traversal
      open_list = []
      # Create first nodes in the A-star search tree, matching node 0 of G1 with all possibilities (each node of G2, and deletion)
      matched_cost = 0.0
      matched_nodes = ([], [])
      # No nodes matched in the beginning
      matched_edges = ([], [])
      # No edges matched in the beginning
      unprocessed_nodes_G1 = [
          i for i in range(G1.num_nodes())
      ]  # No nodes matched in the beginning
      unprocessed_nodes_G2 = [
          i for i in range(G2.num_nodes())
      ]  # No nodes matched in the beginning
      unprocessed_edges_G1 = [
          i for i in range(G1.num_edges())
      ]  # No edges matched in the beginning
      unprocessed_edges_G2 = [
          i for i in range(G2.num_edges())
      ]  # No edges matched in the beginning
  
      for i in range(len(unprocessed_nodes_G2)):
          tree_node = search_tree_node(
              G1,
              G2,
              matched_cost,
              matched_nodes,
              matched_edges,
              unprocessed_nodes_G1[0],
              unprocessed_nodes_G2[i],
              unprocessed_nodes_G1,
              unprocessed_nodes_G2,
              unprocessed_edges_G1,
              unprocessed_edges_G2,
              cost_matrix_nodes,
              cost_matrix_edges,
          )
          # Insert into open-list, implemented as a heap
  
          heappush(open_list, tree_node)
  
      # Consider node deletion
      tree_node = search_tree_node(
          G1,
          G2,
          matched_cost,
          matched_nodes,
          matched_edges,
          unprocessed_nodes_G1[0],
          None,
          unprocessed_nodes_G1,
          unprocessed_nodes_G2,
          unprocessed_edges_G1,
          unprocessed_edges_G2,
          cost_matrix_nodes,
          cost_matrix_edges,
      )
      # Insert into open-list, implemented as a heap
      heappush(open_list, tree_node)
  
      while len(open_list) > 0:
          # TODO: Create a node that processes multi node insertion deletion in one search node,
          # as opposed in multiple search nodes here
          parent_tree_node = heappop(open_list)
          matched_cost = parent_tree_node.matched_cost
          matched_nodes = parent_tree_node.matched_nodes
          matched_edges = parent_tree_node.matched_edges
          unprocessed_nodes_G1 = parent_tree_node.unprocessed_nodes_G1
          unprocessed_nodes_G2 = parent_tree_node.unprocessed_nodes_G2
          unprocessed_edges_G1 = parent_tree_node.unprocessed_edges_G1
          unprocessed_edges_G2 = parent_tree_node.unprocessed_edges_G2
  
          if (
              len(unprocessed_nodes_G1) == 0
              and len(unprocessed_nodes_G2) == 0
          ):
              return (matched_cost, matched_nodes, matched_edges)
          elif len(unprocessed_nodes_G1) > 0:
              for i in range(len(unprocessed_nodes_G2)):
                  tree_node = search_tree_node(
                      G1,
                      G2,
                      matched_cost,
                      matched_nodes,
                      matched_edges,
                      unprocessed_nodes_G1[0],
                      unprocessed_nodes_G2[i],
                      unprocessed_nodes_G1,
                      unprocessed_nodes_G2,
                      unprocessed_edges_G1,
                      unprocessed_edges_G2,
                      cost_matrix_nodes,
                      cost_matrix_edges,
                  )
                  # Insert into open-list, implemented as a heap
                  heappush(open_list, tree_node)
  
              # Consider node deletion
              tree_node = search_tree_node(
                  G1,
                  G2,
                  matched_cost,
                  matched_nodes,
                  matched_edges,
                  unprocessed_nodes_G1[0],
                  None,
                  unprocessed_nodes_G1,
                  unprocessed_nodes_G2,
                  unprocessed_edges_G1,
                  unprocessed_edges_G2,
                  cost_matrix_nodes,
                  cost_matrix_edges,
              )
              # Insert into open-list, implemented as a heap
              heappush(open_list, tree_node)
  
          elif len(unprocessed_nodes_G2) > 0:
              for i in range(len(unprocessed_nodes_G2)):
                  tree_node = search_tree_node(
                      G1,
                      G2,
                      matched_cost,
                      matched_nodes,
                      matched_edges,
                      None,
                      unprocessed_nodes_G2[i],
                      unprocessed_nodes_G1,
                      unprocessed_nodes_G2,
                      unprocessed_edges_G1,
                      unprocessed_edges_G2,
                      cost_matrix_nodes,
                      cost_matrix_edges,
                  )
                  # Insert into open-list, implemented as a heap
                  heappush(open_list, tree_node)
  
          # Retain the top-k elements in open-list iff algorithm is beam
          if max_beam_size > 0 and len(open_list) > max_beam_size:
              open_list = nsmallest(max_beam_size, open_list)
              heapify(open_list)
  
      return None
  
file_path: dgl/examples/pytorch/graph_matching/ged.py
imports: from copy import deepcopy
  from heapq import heapify, heappop, heappush, nsmallest
  import dgl
  import numpy
  from lapjv import lapjv
label_desc: Use image node_id 8 for calling a global function with example usage: a_star_search(G1, G2, cost_matrix_nodes, cost_matrix_edges, max_beam_size) and returns: None, matched_cost,  matched_nodes,  matched_edges