Skip to content

Commit c25de0d

Browse files
committed
forgot
1 parent b8e443d commit c25de0d

File tree

1 file changed

+281
-0
lines changed

1 file changed

+281
-0
lines changed
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
import itertools
2+
import time
3+
import copy
4+
import random
5+
from random import shuffle
6+
import numpy as np
7+
from scipy import optimize
8+
import pytheus.fancy_classes as fc
9+
import pytheus.theseus as th
10+
11+
12+
def flatten(l):
13+
return [item for sublist in l for item in sublist]
14+
15+
16+
def is_connected(lst):
17+
# print('lst: ',lst)
18+
in_list = [lst[0][0], lst[0][1]]
19+
20+
cnum_vertices = len(set(flatten([[vv[0], vv[1]] for vv in lst])))
21+
22+
curr_len = len(in_list) - 1
23+
# print('len(in_list)<cnum_vertices: ',len(in_list)<cnum_vertices)
24+
# print('len(in_list)>curr_len: ',len(in_list)>curr_len)
25+
26+
while len(in_list) < cnum_vertices and len(in_list) > curr_len:
27+
curr_len = len(in_list)
28+
for ee in lst[1:]:
29+
if (ee[0] in in_list) and (not ee[1] in in_list):
30+
in_list.append(ee[1])
31+
if (ee[1] in in_list) and (not ee[0] in in_list):
32+
in_list.append(ee[0])
33+
34+
# print(in_list)
35+
# print(cnum_vertices)
36+
return len(in_list) == cnum_vertices
37+
38+
39+
def make_list_unique(lst):
40+
unique_lst = [list(x) for x in set(tuple(x) for x in lst)]
41+
return unique_lst
42+
43+
44+
def is_substructure(lst1, lst2):
45+
if len(lst1) < len(lst2):
46+
return False
47+
48+
rr = [ll in lst1 for ll in lst2]
49+
if not all(rr):
50+
return False
51+
52+
unique_lst2 = make_list_unique(lst2)
53+
if len(lst2) > len(unique_lst2):
54+
return False
55+
56+
return True
57+
58+
59+
def compute_all_possibilies(full_graph, all_curr_subsequence, num_vertices, num_cols):
60+
# print('all_curr_subsequence: ', all_curr_subsequence)
61+
# time.sleep(0.5)
62+
all_permutations = list(itertools.permutations(list(range(num_vertices))))
63+
all_permutations_cols = list(itertools.permutations(list(range(num_cols))))
64+
curr_graph = all_curr_subsequence[-1]
65+
66+
# print('len(all_permutations): ', len(all_permutations))
67+
68+
all_curr_subsequence_ext = all_curr_subsequence + [[ee] for ee in full_graph]
69+
# print('len(all_curr_subgraphs_ext): ', len(all_curr_subsequence_ext))
70+
all_possibilities = []
71+
for curr_substr in all_curr_subsequence_ext:
72+
if len(curr_substr) == 1:
73+
new_graph = curr_graph + curr_substr
74+
if is_substructure(full_graph, new_graph):
75+
if not new_graph in all_possibilities:
76+
all_possibilities.append(new_graph)
77+
78+
if len(curr_substr) > 1:
79+
if is_connected(curr_substr):
80+
# print('curr_substr: ',curr_substr)
81+
for curr_perm in all_permutations:
82+
# print('all_permutations: ', all_permutations)
83+
84+
# print('curr_substr: ',curr_substr)
85+
for curr_col_perm in all_permutations_cols:
86+
curr_substr_perm = []
87+
for cedge in curr_substr:
88+
nedge = [curr_perm[cedge[0]], curr_perm[cedge[1]], curr_col_perm[cedge[2]],
89+
curr_col_perm[cedge[3]]]
90+
# print('nedge: ', nedge)
91+
if nedge[0] > nedge[1]:
92+
nedge = [nedge[1], nedge[0], nedge[2], nedge[3]]
93+
curr_substr_perm.append(nedge)
94+
# time.sleep(0.1)
95+
96+
new_graph = curr_graph + curr_substr_perm
97+
# print(' new_graph: ',new_graph, '(curr_perm: ', curr_perm,')')
98+
99+
# time.sleep(0.1)
100+
if is_substructure(full_graph, new_graph):
101+
# print('is_substructure')
102+
if not new_graph in all_possibilities:
103+
# print('not new_graph in all_possibilities')
104+
all_possibilities.append(new_graph)
105+
106+
return all_possibilities
107+
108+
109+
def compute_assembly_index(full_graph, all_curr_subsequence, assembly_index_col, num_vertices, num_cols):
110+
# print(' - - - - -')
111+
# print('in compute_assembly_index')
112+
# print(' full_graph: ',full_graph)
113+
# for csg in all_curr_subsequence:
114+
# print(' csg: ', csg)
115+
# time.sleep(0.25)
116+
117+
if len(full_graph) == 0:
118+
return 0, []
119+
if len(full_graph) == 1:
120+
return 1, [[full_graph[0]]]
121+
if len(full_graph) == 2:
122+
return 2, [[full_graph[0]], full_graph]
123+
124+
global min_assembly_idx, min_ai_structure, assembly_index_collection
125+
num_vertices = max([max(ll[0:2]) for ll in full_graph]) + 1
126+
num_cols = max([max(ll[2:4]) for ll in full_graph]) + 1
127+
128+
all_possibilies = compute_all_possibilies(full_graph, all_curr_subsequence, num_vertices, num_cols)
129+
# print('len(all_possibilies): ', len(all_possibilies))
130+
for new_graph in all_possibilies:
131+
new_curr_subgraphs = copy.deepcopy(all_curr_subsequence)
132+
new_curr_subgraphs.append(new_graph)
133+
# print('new_graph: ', new_graph)
134+
# time.sleep(1)
135+
136+
if len(new_curr_subgraphs) < min_assembly_idx:
137+
if is_substructure(full_graph, new_graph) and is_substructure(new_graph, full_graph):
138+
# print(' DONE !!! Assembly Index: ', len(new_curr_subgraphs))
139+
assembly_index_col.append(len(new_curr_subgraphs))
140+
if len(new_curr_subgraphs) < min_assembly_idx:
141+
min_assembly_idx = len(new_curr_subgraphs)
142+
min_ai_structure = new_curr_subgraphs
143+
# print('new best value: ', min_assembly_idx)
144+
else:
145+
compute_assembly_index(full_graph, new_curr_subgraphs, assembly_index_collection, num_vertices,
146+
num_cols)
147+
148+
return min_assembly_idx, min_ai_structure
149+
150+
151+
def assembly_index_unweighted(gg, num_vertices, num_cols):
152+
global min_assembly_idx, min_ai_structure, assembly_index_collection
153+
min_assembly_idx = 666
154+
min_ai_structure = []
155+
assembly_index_collection = []
156+
157+
if len(gg) == 0:
158+
# print('assembly_index_collection: ', 0)
159+
return 0
160+
161+
init_structure = [gg[0]]
162+
# print(gg)
163+
164+
min_assembly_idx, min_ai_structure = compute_assembly_index(gg, [init_structure], assembly_index_collection,
165+
num_vertices, num_cols)
166+
# print('assembly_index_collection: ', min_assembly_idx)
167+
# for ii in min_ai_structure:
168+
# print(ii)
169+
170+
return min_assembly_idx
171+
172+
173+
def sample_subgraph(graph, size_of_graph):
174+
all_edges = graph.edges
175+
all_weights = graph.weights
176+
177+
curr_edges = []
178+
while len(curr_edges) < size_of_graph:
179+
ridx = random.randint(0, len(all_edges) - 1)
180+
if random.random() < abs(all_weights[ridx]):
181+
if not all_edges[ridx] in curr_edges:
182+
curr_edges.append(all_edges[ridx])
183+
184+
curr_graph = fc.Graph(curr_edges)
185+
for edge in curr_edges:
186+
curr_graph[edge] = graph[edge]
187+
188+
return curr_graph
189+
190+
191+
def assembly_index(graph, cnfg):
192+
print("computing assembly index")
193+
num_vertices = cnfg["num_vertices"]
194+
num_cols = cnfg["num_cols"]
195+
size_of_graph = cnfg["size_of_graph"]
196+
197+
all_sampled_assembly_indices = []
198+
199+
for ii in range(cnfg["sample_size"]):
200+
sampled_graph = sample_subgraph(graph, size_of_graph)
201+
sampled_graph = sampled_graph.edges
202+
sampled_graph = [list(edge) for edge in sampled_graph]
203+
sampled_graph.sort()
204+
min_assembly_idx = assembly_index_unweighted(sampled_graph, num_vertices, num_cols)
205+
all_sampled_assembly_indices.append(min_assembly_idx)
206+
207+
weighted_assembly_index = sum(all_sampled_assembly_indices) / len(all_sampled_assembly_indices)
208+
return weighted_assembly_index
209+
210+
211+
def sample_top(graph, cnfg, ii):
212+
sorted_inds = list(np.argsort(graph.weights))
213+
sorted_inds.reverse()
214+
sorted_edges = [graph.edges[ind] for ind in sorted_inds]
215+
# weight of the edge that gets promoted
216+
weight = graph[sorted_edges[ii + cnfg["size_of_graph"]]]
217+
sampled_edges = sorted_edges[:cnfg["size_of_graph"] - 1] + [sorted_edges[ii + cnfg["size_of_graph"]]]
218+
sampled_edges = [list(edge) for edge in sampled_edges]
219+
sampled_edges.sort()
220+
return sampled_edges, weight
221+
222+
223+
def sample_bottom(graph, cnfg, ii):
224+
sorted_inds = list(np.argsort(graph.weights))
225+
sorted_inds.reverse()
226+
sorted_edges = [graph.edges[ind] for ind in sorted_inds]
227+
# weight of the edge that gets demoted
228+
weight = graph[sorted_edges[ii]]
229+
sampled_edges = sorted_edges[:ii] + sorted_edges[ii + 1:cnfg["size_of_graph"]] + [sorted_edges[
230+
cnfg["size_of_graph"] + ii]]
231+
sampled_edges = [list(edge) for edge in sampled_edges]
232+
sampled_edges.sort()
233+
return sampled_edges, weight
234+
235+
236+
def top_n_assembly(graph, cnfg):
237+
print("computing top_n_assembly loss")
238+
num_vertices = cnfg["num_vertices"]
239+
num_cols = cnfg["num_cols"]
240+
size_of_graph = cnfg["size_of_graph"]
241+
242+
for e in graph.edges:
243+
graph[e] = np.abs(graph[e])
244+
245+
sorted_inds = list(np.argsort(graph.weights))
246+
sorted_inds.reverse()
247+
sorted_edges = [graph.edges[ind] for ind in sorted_inds]
248+
top_edges = sorted_edges[:cnfg["size_of_graph"]]
249+
top_edges = [list(edge) for edge in top_edges]
250+
top_edges.sort()
251+
curr_assembly = assembly_index_unweighted(top_edges, num_vertices, num_cols)
252+
253+
lossfunc = 0
254+
255+
for ii in range(len(graph) - cnfg["size_of_graph"]):
256+
# check the assembly index if smallest of top edges was switched out for each of the bottom edges
257+
# get weight of bottom edge to be promoted
258+
sampled_edges, weight = sample_top(graph, cnfg, ii)
259+
sample_assembly = assembly_index_unweighted(sampled_edges, num_vertices, num_cols)
260+
lossfunc += (sample_assembly - curr_assembly) * weight
261+
262+
for ii in range(cnfg["size_of_graph"]):
263+
# check the assembly index if biggest of bottom edges was switched out for each of the top edges
264+
# get weight of top edge to be demoted
265+
sampled_edges, weight = sample_bottom(graph, cnfg, ii)
266+
sample_assembly = assembly_index_unweighted(sampled_edges, num_vertices, num_cols)
267+
lossfunc += (curr_assembly - sample_assembly) * weight
268+
269+
return lossfunc
270+
271+
272+
if __name__ == "__main__":
273+
cnfg = {
274+
"num_vertices": 4,
275+
"num_cols": 2,
276+
"size_of_graph": 8}
277+
gg = fc.Graph(th.buildAllEdges([2, 2, 2, 2]))
278+
for e in gg.edges:
279+
gg[e] = random.random()
280+
ai = top_n_assembly(gg, cnfg)
281+
print(ai)

0 commit comments

Comments
 (0)