code: def edit_cost_from_node_matching(
      G1, G2, cost_matrix_nodes, cost_matrix_edges, node_matching
  ):
      matched_cost = 0.0
      matched_nodes = ([], [])
      matched_edges = ([], [])
      # Add the cost of matching nodes
      for i in range(G1.num_nodes()):
          matched_cost += cost_matrix_nodes[i, node_matching[i]]
          matched_nodes[0].append(i)
          if node_matching[i] < G2.num_nodes():
              matched_nodes[1].append(node_matching[i])
          else:
              matched_nodes[1].append(None)
      for i in range(G1.num_nodes(), len(node_matching)):
          matched_cost += cost_matrix_nodes[i, node_matching[i]]
          if node_matching[i] < G2.num_nodes():
              matched_nodes[0].append(None)
              matched_nodes[1].append(node_matching[i])
  
      for i in range(len(matched_nodes[0])):
          # Add the cost of matching edges
          incident_edges_G1 = []
          if (
              matched_nodes[0][i] is not None
          ):  # Find the edges with one end-point as node_G1 and other in matched nodes or node_G1
              (
                  incident_edges_G1,
                  index_G1,
                  direction_G1,
              ) = get_edges_to_match(
                  G1, matched_nodes[0][i], matched_nodes[0][:i]
              )
  
          incident_edges_G2 = np.array([])
          if (
              matched_nodes[1][i] is not None
          ):  # Find the edges with one end-point as node_G2 and other in matched nodes or node_G2
              (
                  incident_edges_G2,
                  index_G2,
                  direction_G2,
              ) = get_edges_to_match(
                  G2, matched_nodes[1][i], matched_nodes[1][:i]
              )
  
          if (
              len(incident_edges_G1) > 0 and len(incident_edges_G2) > 0
          ):  # Consider substituting
              matched_edges_cost_matrix = subset_cost_matrix(
                  cost_matrix_edges,
                  incident_edges_G1,
                  incident_edges_G2,
                  G1.num_edges(),
                  G2.num_edges(),
              )
              max_sum = matched_edges_cost_matrix.sum()
              # take care of impossible assignments by assigning maximum cost
              for i in range(len(incident_edges_G1)):
                  for j in range(len(incident_edges_G2)):
                      # both edges need to have same direction and the other end nodes are matched
                      if (
                          direction_G1[i] == direction_G2[j]
                          and index_G1[i] == index_G2[j]
                      ):
                          continue
                      else:
                          matched_edges_cost_matrix[i, j] = max_sum
              # Match the edges as per the LAP solution
              row_ind, col_ind, _ = lapjv(matched_edges_cost_matrix)
              lap_cost = 0.00
              for i in range(len(row_ind)):
                  lap_cost += matched_edges_cost_matrix[i, row_ind[i]]
  
              # Update matched edges
              for i in range(len(row_ind)):
                  if i < len(incident_edges_G1):
                      matched_edges[0].append(incident_edges_G1[i])
                      if row_ind[i] < len(incident_edges_G2):
                          matched_edges[1].append(
                              incident_edges_G2[row_ind[i]]
                          )
                      else:
                          matched_edges[1].append(None)
                  elif row_ind[i] < len(incident_edges_G2):
                      matched_edges[0].append(None)
                      matched_edges[1].append(
                          incident_edges_G2[row_ind[i]]
                      )
              matched_cost += lap_cost
  
          elif len(incident_edges_G1) > 0:  # only deletion possible
              edge_deletion_cost = 0.0
              for edge in incident_edges_G1:
                  edge_deletion_cost += cost_matrix_edges[
                      edge, G2.num_edges() + edge
                  ]
              # Update matched edges
              for edge in incident_edges_G1:
                  matched_edges[0].append(edge)
                  matched_edges[1].append(None)
  
                  # Update matched edges
  
              matched_cost += edge_deletion_cost
  
          elif len(incident_edges_G2) > 0:  # only insertion possible
              edge_insertion_cost = 0.0
              for edge in incident_edges_G2:
                  edge_insertion_cost += cost_matrix_edges[
                      G1.num_edges() + edge, edge
                  ]
              # Update matched edges
              for edge in incident_edges_G2:
                  matched_edges[0].append(None)
                  matched_edges[1].append(edge)
  
              matched_cost += edge_insertion_cost
  
      return (matched_cost, matched_nodes, matched_edges)
  
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 5 for calling a global function with example usage: edit_cost_from_node_matching(G1, G2, cost_matrix_nodes, cost_matrix_edges, node_matching) and returns: matched_cost,  matched_nodes,  matched_edges