Commit 3c4fd1e6 authored by Carlos GO's avatar Carlos GO
Browse files

custom cost matrix

parent 338b7611
......@@ -73,6 +73,36 @@ def label_path(op_node, g1, g2):
else:
return f"{short(e1)} {label(e1,g1)} - {short(e2)} {label(e2,g2)} --> {label_path(op_node.parent, g1, g2)}"
def edge_edit_cost_custom(u,v, g1, g2, node, sub_matrix, indel_cost=4, sub_cost=1, ss_break_cost=2):
"""
Recursively search for edge substitution.
NOTE: need to supply sub_matrix (see below) and edge labels should be encoded as integers.
`sub_matrix` gives the cost for substitution between labels i and j
"""
if node == None:
return 0
else:
u1, v1 = node.op
e1 = (u1, u)
e2 = (v1, v)
# print(e1, e2)
cost = 0
if e1 in g1.edges and e2 in g2.edges:
#edge substitution
l1 = g1[e1[0]][e1[1]]['label']
l2 = g2[e2[0]][e2[1]]['label']
cost = sub_matrix[l1][l2]
elif e1 not in g1.edges and e2 in g2.edges:
#edge insert+ion
cost = indel_cost
elif e1 in g1.edges and e2 not in g2.edges:
cost = indel_cost
else:
cost = 0
return cost + edge_edit_cost(u,v,g1,g2,node.parent)
def edge_edit_cost(u,v, g1, g2, node, indel_cost=4, sub_cost=1, ss_break_cost=2):
"""
Recursively search for edge substitution.
......@@ -143,7 +173,7 @@ def node_cost(op, G1, G2):
else:
return 0
def cost(op, G1, G2, parent, loop_cost=True, skeleton=False):
def cost(op, G1, G2, parent, loop_cost=True, skeleton=False, sub_matrix=None):
"""
Returns the cost of an operation.
TODO: add edge edit cost here.
......@@ -157,6 +187,8 @@ def cost(op, G1, G2, parent, loop_cost=True, skeleton=False):
return 0
if loop_cost:
return edge_edit_cost(u,v,G1,G2,parent) + node_cost(op, G1, G2)
elif sub_matrix:
return edge_edit_cost_custom(u,v,G1,G2, parent, sub_matrix)
else:
return edge_edit_cost(u,v,G1,G2, parent)
......@@ -241,7 +273,7 @@ def local_heuristic(op, parent, g1, g2):
diff = 2 * (abs(len(unmapped_nei_v) - len(unmapped_nei_u)))
return diff
def ged(graphs, with_heuristic=False, timeout=30, halt=None, source_only=False):
def ged(graphs, with_heuristic=False, timeout=30, halt=None, source_only=False, sub_matrix=None):
"""
Compute GED of two graphs.
"""
......@@ -264,15 +296,14 @@ def ged(graphs, with_heuristic=False, timeout=30, halt=None, source_only=False):
for n in g2_nodes:
op = (g1_nodes[0], n)
c = cost(op, g1, g2, None)
c = cost(op, g1, g2, None, sub_matrix=sub_matrix)
h=0
if with_heuristic:
h = heuristic(op,None, g1, g2)
heappush(open, (c+h, count, OpNode(op, c, root)))
# G.add_edge(op, root, label=c)
count += 1
del_op = (g1_nodes[0], 'NILL')
c = cost(del_op, g1, g2, None)
c = cost(del_op, g1, g2, None, sub_matrix=sub_matrix)
h = 0
if with_heuristic:
h = heuristic(op,None, g1, g2)
......@@ -298,14 +329,14 @@ def ged(graphs, with_heuristic=False, timeout=30, halt=None, source_only=False):
ops = [(g1_nodes[p_min.depth], u) for u in g2.nodes if
u not in p_min.target_map]
for op in ops:
c = cost(op, g1, g2, p_min) + cum_cost
c = cost(op, g1, g2, p_min, sub_matrix=sub_matrix) + cum_cost
h=0
if with_heuristic:
h = heuristic(op,p_min, g1, g2)
heappush(open, (c+h , count, OpNode(op,c,p_min)))
count += 1
del_op = (g1_nodes[p_min.depth], 'NILL')
c = cost(del_op, g1, g2, p_min) + cum_cost
c = cost(del_op, g1, g2, p_min, sub_matrix=sub_matrix) + cum_cost
h=0
if with_heuristic:
h = heuristic(op,p_min, g1, g2)
......@@ -314,13 +345,13 @@ def ged(graphs, with_heuristic=False, timeout=30, halt=None, source_only=False):
else:
if source_only:
return (p_min, graphs, time.time() - start)
#all nodes in g1 tested, add nodes from g2 to check
#all nodes in g1 tested, add nodes from g2 to check
ops = [('NILL', u) for u in g2_nodes if u not in p_min.target_map]
if len(ops) == 0:
cur_node = p_min
return (p_min, graphs, time.time() - start)
for op in ops:
c = cost(op, g1, g2, p_min) + cum_cost
c = cost(op, g1, g2, p_min, sub_matrix=sub_matrix) + cum_cost
h=0
if with_heuristic:
h = heuristic(op,p_min, g1, g2)
......@@ -551,43 +582,3 @@ if __name__ == "__main__":
# simple_graph()
simple_rna()
sys.exit()
nodes = []
times = []
times_heur = []
too_big = 0
for g1, g2 in random_graphs():
if len(g1.nodes) > 10 or len(g2.nodes) > 10:
too_big += 1
continue
g1 = nx.relabel_nodes(g1, {n:(*n, 's') for n in g1.nodes})
g2 = nx.relabel_nodes(g2, {n:(*n, 'd') for n in g2.nodes})
nodes.append(len(g1.nodes) * len(g2.nodes))
print(len(g1.nodes), len(g2.nodes))
start = time.time()
print("WITH HEURISTIC")
ops = ged(g1, g2, with_heuristic=True)
t_h = time.time() - start
graph_align(g1, g2, ops)
times_heur.append(t_h)
print(f"TIME: {time.time() - start}")
print("NO HEURISTIC")
start = time.time()
ops = ged(g1, g2, with_heuristic=False)
t_reg = time.time() - start
times.append(t_reg)
print(f"TIME: {time.time() - start}")
graph_align(g1, g2, ops)
print(too_big)
print(nodes)
print(len(nodes))
print(times)
print(times_heur)
plt.scatter(nodes, times, label='normal')
plt.scatter(nodes, times_heur , label='heuristic')
plt.legend()
plt.ylabel('time')
plt.xlabel('n+m')
plt.show()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment