Commit eeab1f7a authored by Yoann Dufresne's avatar Yoann Dufresne

naive branch & bound

parent cba8bbe2
......@@ -20,6 +20,8 @@ class D2Graph(nx.Graph):
self.barcode_graph = barcode_graph
self.index = None
self.variables_per_node = {}
# Number the edges from original graph
self.barcode_edge_idxs = {}
self.nb_uniq_edge = 0
......@@ -89,6 +91,13 @@ class D2Graph(nx.Graph):
self.bidict_nodes = self.create_graph_from_node_neighborhoods(neighbor_threshold)
def get_covering_variable_node(self, node):
if node not in self.variables_per_node:
udg = self.node_by_idx[node]
self.variables_per_node[node] = [x for x in self.get_covering_variables(udg)]
return self.variables_per_node[node]
def get_covering_variables(self, udg):
variables = []
for e in udg.edges:
......
import random
import networkx as nx
from collections import Counter
from deconvolution.d2graph.d2_path import Path
......@@ -16,6 +17,87 @@ class Optimizer:
rnd_sol.random_init_best_quality()
self.solutions.append(rnd_sol)
def bb_solution(self, verbose=False):
nb_steps_since_last_score_up = 0
total_nb_steps = 0
first_pass = True
used_nodes = {n:False for n in self.d2g.nodes()}
coverage = Counter()
# Init solution for
init = list(used_nodes.keys())
init = init[random.randint(0, len(init)-1)]
best_path = []
best_score = 0
stack = [[init]]
current_path = []
last_increase_node = None
while len(stack) > 0:
total_nb_steps += 1
# 1 - Get next node to extend
current_node = stack[-1].pop()
# 2 - Node exploitation
# 2.1 - Add the node
used_nodes[current_node] = True
current_path.append(current_node)
# 2.2 - Compute the coverage score
vars = self.d2g.get_covering_variable_node(int(current_node))
coverage += Counter(vars)
# 2.3 - If best, save
if len(coverage) > best_score:
nb_steps_since_last_score_up = 0
best_path = current_path.copy()
best_score = len(coverage)
last_increase_node = current_node
if verbose:
print(f"New best: {len(best_path)} {best_score}")
else:
nb_steps_since_last_score_up += 1
# 3 - Neighbors preparation
neighbors = [x for x in self.d2g[current_node] if not used_nodes[x]]
opt = self
def node_sorting_value(node):
u = opt.d2g.node_by_idx[int(node)]
return (0 if len(Counter(opt.d2g.get_covering_variable_node(int(node))) - coverage) == 0 else 1,
- u.get_link_divergence())
neighbors.sort(key=node_sorting_value)
stack.append(neighbors)
# 4 - No more neighbors here - back up
while len(stack[-1]) == 0:
stack.pop()
previous = current_path.pop()
used_nodes[previous] = False
prev_vars = self.d2g.get_covering_variable_node(int(previous))
coverage -= Counter(prev_vars)
# 5 - Reinit the search from a side and stop when done
if total_nb_steps > 10000 and nb_steps_since_last_score_up >= total_nb_steps / 2:
if first_pass:
used_nodes = {n: False for n in self.d2g.nodes()}
coverage = Counter()
best_path = []
best_score = 0
stack = [[last_increase_node]]
current_path = []
if verbose:
print("Start again !")
first_pass = False
total_nb_steps = 0
nb_steps_since_last_score_up = 0
import time
time.sleep(3)
else:
return best_path
return best_path
def extends_until_end(self, solution):
while self.extends(solution):
continue
......
......@@ -12,6 +12,7 @@ def parse_arguments():
parser.add_argument('barcode_graph', help='The barcode graph file. Must be a gefx formatted file.')
parser.add_argument('d2_graph', help='d2 graph to reduce. Must be a gexf formatted file.')
parser.add_argument('--out_prefix', '-o', default="", help="Output file prefix.")
parser.add_argument('--verbose', '-v', action="store_true", help="Verbose")
args = parser.parse_args()
......@@ -42,16 +43,19 @@ def main():
# Start optimization
optimizer = po.Optimizer(largest_component)
optimizer.init_random_solutions(1)
solution = optimizer.solutions[0]
print("Solution creation...")
optimizer.extends_until_end(solution)
nodes = optimizer.bb_solution(verbose=args.verbose)
solution = po.Solution(largest_component)
solution.add_path([largest_component.node_by_idx[int(n)] for n in nodes])
# optimizer.init_random_solutions(1)
# solution = optimizer.solutions[0]
# print("Solution creation...")
# optimizer.extends_until_end(solution)
print(f"covering score: {solution.covering_score()}")
#
# solution.save_path_in_graph(f"{args.out_prefix}_d2_path.gexf")
solution.save_path(f"{args.out_prefix}_path.gexf")
solution.save_barcode_path(f"{args.out_prefix}_barcode_count.gexf")
# solution.save_barcode_path(f"{args.out_prefix}_barcode_count.gexf")
print("Solution saved")
# from d2_path import d2_path_to_barcode_path
......
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