def _test_cycle(self, succs): logging.info(succs) graph = Digraph(succs) logging.info(graph.dot('g')) cycle = graph.find_cycle() logging.info(cycle.dot('cycle')) return cycle
def _graph(instances, root='1', use_prob=True): """ instances are quadruplets of the form: source, target, probability_of_attachment, relation root is the "root" of the graph, that is the node that has no incoming nodes returns the Maximum Spanning Tree """ targets = defaultdict(list) labels = dict() scores = dict() for source, target, prob, rel in instances: src = source.id tgt = target.id if tgt == root: continue scores[src, tgt] = prob labels[src, tgt] = rel if use_prob: # probability scores scores[src, tgt] = log(prob if prob != 0.0 else sys.float_info.min) targets[src].append(tgt) return Digraph(targets, lambda s, t: scores[s, t], lambda s, t: labels[s, t]).mst()
def _msdag(graph): """ Returns a subgraph of graph (a Digraph) corresponding to its Maximum Spanning Directed Acyclic Graph Algorithm is semi-greedy-MSDAG as described in Schluter_: .. _Schluter (2014): http://aclweb.org/anthology/W14-2412 """ tree = graph.mst() # Sort edges in orginal graph by decreasing score # pylint: disable=star-args edges = sorted(graph.iteredges(), key=lambda p: -graph.get_score(*p)) # pylint: enable=star-args for src, tgt in edges: # Already in graph ? if tgt in tree.successors[src]: continue # Add the edge, revert if cycle is created tree.successors[src].append(tgt) if tree.find_cycle(): tree.successors[src].remove(tgt) # Update score and label functions new_map = lambda f: dict(((s, t), f(s, t)) for s, t in tree.iteredges()) nscores = new_map(graph.get_score) nlabels = new_map(graph.get_label) return Digraph(tree.successors, lambda s, t: nscores[s, t], lambda s, t: nlabels[s, t])
def _graph(instances, use_prob=True): """ Builds a directed graph for instances instances are quadruplets of the form: edu_source, edu_target, probability_of_attachment, relation returns a Digraph """ root_id = _get_root(set(e for s, t, _, _ in instances for e in (s, t))).id targets = defaultdict(list) labels = dict() scores = dict() for source, target, prob, rel in instances: src, tgt = source.id, target.id # Ignore all edges directed to the root if tgt == root_id: continue scores[src, tgt] = _cap_score(logit(prob)) if use_prob else prob labels[src, tgt] = rel targets[src].append(tgt) return Digraph(targets, lambda s, t: scores[s, t], lambda s, t: labels[s, t])
def _test_chuliuedmonds(self, scores, cycles_and_edges): logging.info('**********') succs = collections.defaultdict(list) for s, t in scores: succs[s].append(t) succs[t] num_nodes = len(succs) num_edges = len(scores) graph = Digraph(succs, lambda s, t: scores[s, t][0], lambda s, t: scores[s, t][1]) logging.info(graph.dot('g')) self.assertEqual(num_nodes, len(graph.successors)) self.assertEqual(num_edges, len(tuple(graph.iteredges()))) self.__test_chuliuedmonds(graph, num_nodes, num_edges, cycles_and_edges)
def _graph(self, instances): """ Builds a directed graph for instances instances are quadruplets of the form: edu_source, edu_target, probability_of_attachment, relation :rtype Digraph """ if self._root_strategy == MstRootStrategy.leftmost: root_id = _leftmost_edu(set(e for s, t, _, _ in instances for e in (s, t))).id elif self._root_strategy == MstRootStrategy.fake_root: root_id = FAKE_ROOT_ID else: raise DecoderException('Unknown root finding strategy: ' + str(self._root_strategy)) targets = defaultdict(list) labels = dict() scores = dict() for source, target, prob, rel in instances: src, tgt = source.id, target.id # Ignore all edges directed to the root if tgt == root_id: continue if self._use_prob: scores[src, tgt] = _cap_score(logit(prob)) else: scores[src, tgt] = prob labels[src, tgt] = rel targets[src].append(tgt) return Digraph(targets, lambda s, t: scores[s, t], lambda s, t: labels[s, t])