You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

costfunctions.py 4.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import numpy as np
  2. from scipy.optimize import linear_sum_assignment
  3. class ConstantCostFunction:
  4. """ Define a symmetric constant cost fonction for edit operations """
  5. def __init__(self, cns, cni, ces, cei):
  6. self.cns_ = cns
  7. self.cni_ = self.cnd_ = cni
  8. self.ces_ = ces
  9. self.cei_ = self.ced_ = cei
  10. def cns(self, node_u, node_v, g1, g2):
  11. """ return substitution edit operation cost between node_u of G1 and node_v of G2"""
  12. return (g1.node[node_u]['label'] != g2.node[node_v]['label'])*self.cns_
  13. def cnd(self, u, G1):
  14. return self.cnd_
  15. def cni(self, v, G2):
  16. return self.cni_
  17. def ces(self, e1, e2, G1, G2):
  18. """tester avec des attributs autres que symboliques en testant
  19. l'operateur __eq__"""
  20. return (e1[2]['label'] != e2[2]['label'])*self.ces_
  21. def ced(self, e1, G1):
  22. return self.ced_
  23. def cei(self, e2, G2):
  24. return self.cei_
  25. class RiesenCostFunction():
  26. """ Cost function associated to the computation of a cost matrix between nodes for LSAP"""
  27. def __init__(self, cf, lsap_solver=linear_sum_assignment):
  28. self.cf_ = cf
  29. self.lsap_solver_ = lsap_solver
  30. def cns(self, u, v, G1, G2):
  31. """ u et v sont des id de noeuds """
  32. n = len(G1[u])
  33. m = len(G2[v])
  34. sub_C = np.ones([n+m, n+m]) * np.inf
  35. sub_C[n:, m:] = 0
  36. i = 0
  37. l_nbr_u = G1[u]
  38. l_nbr_v = G2[v]
  39. for nbr_u in l_nbr_u:
  40. j = 0
  41. e1 = [u, nbr_u, G1[u][nbr_u]]
  42. for nbr_v in G2[v]:
  43. e2 = [v, nbr_v, G2[v][nbr_v]]
  44. sub_C[i, j] = self.cf_.ces(e1, e2, G1, G2)
  45. j += 1
  46. i += 1
  47. i = 0
  48. for nbr_u in l_nbr_u:
  49. sub_C[i, m+i] = self.cf_.ced([u, nbr_u, G1[u][nbr_u]], G1)
  50. i += 1
  51. j = 0
  52. for nbr_v in l_nbr_v:
  53. sub_C[n+j, j] = self.cf_.cei([v, nbr_v, G2[v][nbr_v]], G2)
  54. j += 1
  55. row_ind, col_ind = self.lsap_solver_(sub_C)
  56. cost = np.sum(sub_C[row_ind, col_ind])
  57. return self.cf_.cns(u, v, G1, G2) + cost
  58. def cnd(self, u, G1):
  59. cost = 0
  60. for nbr in G1[u]:
  61. cost += self.cf_.ced([u,nbr,G1[u][nbr]],G1)
  62. return self.cf_.cnd(u,G1) + cost
  63. def cni(self, v, G2):
  64. cost = 0
  65. for nbr in G2[v]:
  66. cost += self.cf_.cei([v,nbr,G2[v][nbr]], G2)
  67. return self.cf_.cni(v, G2) + cost
  68. class NeighboorhoodCostFunction():
  69. """ Cost function associated to the computation of a cost matrix between nodes for LSAP"""
  70. def __init__(self, cf, lsap_solver=linear_sum_assignment):
  71. self.cf_ = cf
  72. self.lsap_solver_ = lsap_solver
  73. def cns(self, u, v, G1, G2):
  74. """ u et v sont des id de noeuds """
  75. n = len(G1[u])
  76. m = len(G2[v])
  77. sub_C = np.ones([n+m, n+m]) * np.inf
  78. sub_C[n:, m:] = 0
  79. i = 0
  80. l_nbr_u = G1[u]
  81. l_nbr_v = G2[v]
  82. for nbr_u in l_nbr_u:
  83. j = 0
  84. e1 = [u, nbr_u, G1[u][nbr_u]]
  85. for nbr_v in G2[v]:
  86. e2 = [v, nbr_v, G2[v][nbr_v]]
  87. sub_C[i, j] = self.cf_.ces(e1, e2, G1, G2)
  88. sub_C[i, j] += self.cf_.cns(nbr_u, nbr_v, G1, G2)
  89. j += 1
  90. i += 1
  91. i = 0
  92. for nbr_u in l_nbr_u:
  93. sub_C[i, m+i] = self.cf_.ced([u, nbr_u, G1[u][nbr_u]], G1)
  94. sub_C[i, m+i] += self.cf_.cnd(nbr_u, G1)
  95. i += 1
  96. j = 0
  97. for nbr_v in l_nbr_v:
  98. sub_C[n+j, j] = self.cf_.cei([v, nbr_v, G2[v][nbr_v]], G2)
  99. sub_C[n+j, j] += self.cf_.cni(nbr_v, G2)
  100. j += 1
  101. row_ind, col_ind = self.lsap_solver_(sub_C)
  102. cost = np.sum(sub_C[row_ind, col_ind])
  103. return self.cf_.cns(u, v, G1, G2) + cost
  104. def cnd(self, u, G1):
  105. cost = 0
  106. for nbr in G1[u]:
  107. cost += self.cf_.ced([u, nbr, G1[u][nbr]], G1)
  108. return self.cf_.cnd(u, G1) + cost
  109. def cni(self, v, G2):
  110. cost = 0
  111. for nbr in G2[v]:
  112. cost += self.cf_.cei([v, nbr, G2[v][nbr]], G2)
  113. return self.cf_.cni(v, G2) + cost

A Python package for graph kernels, graph edit distances and graph pre-image problem.