def test_from_networkx_digraph():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    nxG = directed_graph_transformations.to_networkx_digraph(H)

    G = directed_graph_transformations.from_networkx_digraph(nxG)

    nxG_nodes = nxG.node.keys()
    G_nodes = G.get_node_set()

    assert G_nodes == set(nxG_nodes)

    for edge in nxG.edges_iter():
        tail_node = edge[0]
        head_node = edge[1]
        assert G.has_hyperedge(tail_node, head_node)

    # Try transforming an invalid directed hypergraph
    try:
        directed_graph_transformations.from_networkx_digraph("G")
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #2
0
def test_get_successors():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'
    node_e = 'E'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    tail3 = set([node_d])
    head3 = set([node_e])
    frozen_tail3 = frozenset(tail3)
    frozen_head3 = frozenset(head3)

    hyperedges = [(tail1, head1), (tail2, head2), (tail3, head3), (tail3, "F")]

    H = DirectedHypergraph()
    hyperedge_names = H.add_hyperedges(hyperedges)

    assert 'e1' in H.get_successors(tail1)
    assert 'e2' in H.get_successors(tail2)
    assert 'e3' in H.get_successors(tail3)
    assert 'e4' in H.get_successors(tail3)

    assert H.get_successors([node_a]) == set()
def from_networkx_digraph(nx_digraph):
    """Returns a DirectedHypergraph object that is the graph equivalent of the
    given NetworkX DiGraph object.

    :param nx_digraph: the NetworkX directed graph object to transform.
    :returns: DirectedHypergraph -- hypergraph object equivalent to the
            NetworkX directed graph.
    :raises: TypeError -- Transformation only applicable to directed
            NetworkX graphs

    """
    import networkx as nx

    if not isinstance(nx_digraph, nx.DiGraph):
        raise TypeError("Transformation only applicable to directed \
                        NetworkX graphs")

    G = DirectedHypergraph()

    for node in nx_digraph.nodes_iter():
        G.add_node(node, copy.copy(nx_digraph.node[node]))

    for edge in nx_digraph.edges_iter():
        tail_node = edge[0]
        head_node = edge[1]
        G.add_hyperedge(tail_node,
                        head_node,
                        copy.copy(nx_digraph[tail_node][head_node]))

    return G
 def test_raises_exception_if_k_not_integer(self):
     H = DirectedHypergraph()
     source, destination = 1, 2
     H.add_nodes([source, destination])
     self.assertRaises(TypeError,
                       ksh.k_shortest_hyperpaths,
                       H, source, destination, 0.1)
예제 #5
0
def test_stationary_distribution():
    H = DirectedHypergraph()
    H.read("./tests/data/basic_directed_hypergraph.txt")

    # Try random-walking a directed hypergraph with a node
    # with no outgoing hyperedges
    try:
        pi = rw.stationary_distribution(H)
        assert False
    except AssertionError:
        pass
    except BaseException as e:
        assert False, e

    # Try random-walking a valid directed hypergraph
    H.add_hyperedge(["u"], ["u"], weight=1)
    pi = rw.stationary_distribution(H)

    # Correctness tests go here

    # Try partitioning an invalid directed hypergraph
    try:
        pi = rw.stationary_distribution("H")
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #6
0
def test_visit():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    visited_nodes, Pv, Pe = directed_paths.visit(H, 's')

    assert visited_nodes == set(['s', 'x', 'y', 'z', 'u', 't', 'a'])

    assert Pv['s'] is None
    assert (Pe['e1'], Pe['e2'], Pe['e3']) == ('s', 's', 's')
    assert Pv['x'] in ('e1', 'e2')
    assert Pv['y'] == 'e2'
    assert Pv['z'] == 'e3'
    assert Pe['e4'] in ('x', 'y', 'z')
    assert Pv['u'] == 'e4'
    assert Pv['t'] == 'e8'
    assert Pv['a'] == 'e7'
    assert Pe['e5'] == 'a'
    assert Pe['e6'] == 'x'
    assert Pe['e7'] == 't'
    assert Pe['e8'] == 's'
    assert Pv['b'] is None

    try:
        directed_paths.visit('s', 't')
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #7
0
def test_add_nodes():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    attrib_c = {'alt_name': 1337}
    node_d = 'D'
    attrib_d = {'label': 'black', 'sink': True}
    common_attrib = {'common': True, 'source': False}

    node_list = [node_a, (node_b, {'source': False}),
                 (node_c, attrib_c), (node_d, attrib_d)]

    # Test adding unadded nodes with various attribute settings
    H = DirectedHypergraph()
    H.add_nodes(node_list, common_attrib)

    assert node_a in H._node_attributes
    assert H._node_attributes[node_a] == common_attrib

    assert node_b in H._node_attributes
    assert H._node_attributes[node_b]['source'] is False

    assert node_c in H._node_attributes
    assert H._node_attributes[node_c]['alt_name'] == 1337

    assert node_d in H._node_attributes
    assert H._node_attributes[node_d]['label'] == 'black'
    assert H._node_attributes[node_d]['sink'] is True

    node_set = H.get_node_set()
    assert node_set == set(['A', 'B', 'C', 'D'])
    assert len(node_set) == len(node_list)
    for node in H.node_iterator():
        assert node in node_set
 def test_raises_exception_if_H_not_B_hypegraph(self):
     H = DirectedHypergraph()
     H.add_nodes([1, 2, 3])
     H.add_hyperedge([1], [2, 3])
     source, destination = 1, 2
     self.assertRaises(TypeError,
                       ksh.k_shortest_hyperpaths, H, source, destination, 1)
예제 #9
0
def test_get_hyperedge_weight():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    attrib = {'weight': 6, 'color': 'black'}
    common_attrib = {'sink': False}

    hyperedges = [(tail1, head1, attrib), (tail2, head2)]

    H = DirectedHypergraph()
    hyperedge_names = \
        H.add_hyperedges(hyperedges, common_attrib, color='white')

    weight_e1 = H.get_hyperedge_weight('e1')
    weight_e2 = H.get_hyperedge_weight('e2')
    assert weight_e1 == 6
    assert weight_e2 == 1
예제 #10
0
 def test_returns_hyperpath_containing_source_if_source_equals_destination(
         self):
     s = '1'
     T = {s: None}
     H = DirectedHypergraph()
     H.add_node(s)
     path = directed_paths.get_hyperpath_from_predecessors(H, T, s, s)
     self.assertTrue(path.has_node(s))
예제 #11
0
def test_hyperedge_cardinality_ratio_list():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    ratio_list = [0.5, 1.0, 1.0, 1.0, 2.0, 1.0, 1.5, 0.5]
    returned_list = directed_statistics.hyperedge_cardinality_ratio_list(H)

    assert sorted(ratio_list) == sorted(returned_list)
예제 #12
0
def test_get_symmetric_image():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'
    node_e = 'E'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    tail3 = set([node_d])
    head3 = set([node_e])
    frozen_tail3 = frozenset(tail3)
    frozen_head3 = frozenset(head3)

    hyperedges = [(tail1, head1), (tail2, head2), (tail3, head3)]

    H = DirectedHypergraph()
    hyperedge_names = H.add_hyperedges(hyperedges)

    sym_H = H.get_symmetric_image()

    sym_H._check_consistency()

    assert sym_H._node_attributes == H._node_attributes

    assert sym_H._hyperedge_attributes["e1"]["tail"] == head1
    assert sym_H._hyperedge_attributes["e1"]["head"] == tail1
    assert sym_H._hyperedge_attributes["e1"]["__frozen_tail"] == frozen_head1
    assert sym_H._hyperedge_attributes["e1"]["__frozen_head"] == frozen_tail1
    assert sym_H._hyperedge_attributes["e2"]["tail"] == head2
    assert sym_H._hyperedge_attributes["e2"]["head"] == tail2
    assert sym_H._hyperedge_attributes["e2"]["__frozen_tail"] == frozen_head2
    assert sym_H._hyperedge_attributes["e2"]["__frozen_head"] == frozen_tail2
    assert sym_H._hyperedge_attributes["e3"]["tail"] == head3
    assert sym_H._hyperedge_attributes["e3"]["head"] == tail3
    assert sym_H._hyperedge_attributes["e3"]["__frozen_tail"] == frozen_head3
    assert sym_H._hyperedge_attributes["e3"]["__frozen_head"] == frozen_tail3

    assert sym_H._forward_star[node_a] == set(["e2"])
    assert sym_H._forward_star[node_b] == set()
    assert sym_H._forward_star[node_c] == set(["e1"])
    assert sym_H._forward_star[node_d] == set(["e1", "e2"])
    assert sym_H._forward_star[node_e] == set(["e3"])

    assert sym_H._backward_star[node_a] == set(["e1"])
    assert sym_H._backward_star[node_b] == set(["e1", "e2"])
    assert sym_H._backward_star[node_c] == set(["e2"])
    assert sym_H._backward_star[node_d] == set(["e3"])
    assert sym_H._backward_star[node_e] == set()
예제 #13
0
def test_remove_nodes():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'
    node_e = 'E'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    tail3 = set([node_d])
    head3 = set([node_e])
    frozen_tail3 = frozenset(tail3)
    frozen_head3 = frozenset(head3)

    tail4 = set([node_c])
    head4 = set([node_e])
    frozen_tail4 = frozenset(tail4)
    frozen_head4 = frozenset(head4)

    attrib = {'weight': 6, 'color': 'black'}
    common_attrib = {'sink': False}

    hyperedges = [(tail1, head1, attrib),
                  (tail2, head2),
                  (tail3, head3),
                  (tail4, head4)]

    H = DirectedHypergraph()
    hyperedge_names = \
        H.add_hyperedges(hyperedges, common_attrib, color='white')
    H.remove_nodes([node_a, node_d])

    # Test that everything that needed to be removed was removed
    assert node_a not in H._node_attributes
    assert node_a not in H._forward_star
    assert node_a not in H._backward_star
    assert "e1" not in H._hyperedge_attributes
    assert "e2" not in H._hyperedge_attributes
    assert frozen_tail1 not in H._successors
    assert frozen_head1 not in H._predecessors
    assert frozen_head2 not in H._predecessors
    assert frozen_tail2 not in H._successors

    assert node_d not in H._node_attributes
    assert node_d not in H._forward_star
    assert node_d not in H._backward_star
    assert "e3" not in H._hyperedge_attributes
    assert "e3" not in H._predecessors[frozen_head3]
    assert frozen_tail3 not in H._predecessors[frozen_head3]
예제 #14
0
 def test_returns_hyperpath_with_single_node_if_source_equals_destination(
         self):
     s = '1'
     T = {s: None}
     H = DirectedHypergraph()
     H.add_node(s)
     path = directed_paths.get_hyperpath_from_predecessors(H, T, s, s)
     self.assertEqual(len(path.get_node_set()), 1)
     self.assertEqual(len(path.get_hyperedge_id_set()), 0)
예제 #15
0
 def test_raises_exception_if_all_nodes_have_predecessors(self):
     s1, s2, s3 = 1, 2, 3
     H = DirectedHypergraph()
     H.add_nodes([s1, s2, s3])
     e1 = H.add_hyperedge([s1], [s2])
     T = {s1: e1, s2: e1, s3: e1}
     self.assertRaises(ValueError,
                       directed_paths.get_hyperpath_from_predecessors,
                       H, T, s1, s2)
예제 #16
0
def test_hyperedge_head_cardinality_list():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    hyperedge_head_cardinality_list = \
        directed_statistics.hyperedge_head_cardinality_list(H)
    assert len(hyperedge_head_cardinality_list) == 8
    assert hyperedge_head_cardinality_list.count(1) == 5
    assert hyperedge_head_cardinality_list.count(2) == 3
예제 #17
0
def test_get_hypertree_from_predecessors():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    # Test with a weighting
    Pv, W, valid_ordering = \
        directed_paths.shortest_b_tree(
            H, 's', directed_paths.sum_function, True)

    sub_H = directed_paths.get_hypertree_from_predecessors(H, Pv, 's', W)

    sub_H._check_consistency()

    assert sub_H.get_node_set() == set(['s', 'x', 'y', 'z', 't', 'u'])

    assert sub_H.get_node_attribute('s', 'weight') == 0
    assert sub_H.get_node_attribute('x', 'weight') == 1
    assert sub_H.get_node_attribute('y', 'weight') == 2
    assert sub_H.get_node_attribute('z', 'weight') == 2
    assert sub_H.get_node_attribute('u', 'weight') == 8
    assert sub_H.get_node_attribute('t', 'weight') == 8

    assert Pv['s'] == None
    assert Pv['x'] == "e1"
    assert Pv['y'] == "e2"
    assert Pv['z'] == "e3"
    assert (Pv['u'], Pv['t']) == ("e4", "e4")
    assert (Pv['a'], Pv['b']) == (None, None)

    assert len(sub_H.get_hyperedge_id_set()) == 4
    assert sub_H.has_hyperedge(['s'], ['x'])
    assert sub_H.has_hyperedge(['s'], ['x', 'y'])
    assert sub_H.has_hyperedge(['s'], ['z'])
    assert sub_H.has_hyperedge(['x', 'y', 'z'], ['u', 't'])

    # Test without a weighting
    Pv, W = directed_paths.shortest_f_tree(H, 't', directed_paths.sum_function)

    sub_H = directed_paths.get_hypertree_from_predecessors(H, Pv, 't')

    sub_H._check_consistency()

    assert sub_H.get_node_set() == set(['t', 's', 'x'])

    assert len(sub_H.get_hyperedge_id_set()) == 2
    assert sub_H.has_hyperedge(['x'], ['s'])
    assert sub_H.has_hyperedge(['s'], ['t'])

	# Try an invalid hypergraph
    try:
        directed_paths.shortest_b_tree('s', 't')
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #18
0
def test_outdegree_list():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    outdegree_list = directed_statistics.outdegree_list(H)
    assert len(outdegree_list) == 8
    assert outdegree_list.count(0) == 1
    assert outdegree_list.count(1) == 5
    assert outdegree_list.count(2) == 1
    assert outdegree_list.count(4) == 1
예제 #19
0
def test_indegree_list():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    indegree_list = directed_statistics.indegree_list(H)
    assert len(indegree_list) == 8
    assert indegree_list.count(0) == 1
    assert indegree_list.count(1) == 4
    assert indegree_list.count(2) == 2
    assert indegree_list.count(3) == 1
 def test_raises_exception_if_k_not_positive(self):
     H = DirectedHypergraph()
     source, destination = 1, 2
     H.add_nodes([source, destination])
     self.assertRaises(ValueError,
                       ksh.k_shortest_hyperpaths,
                       H, source, destination, -4)
     self.assertRaises(ValueError,
                       ksh.k_shortest_hyperpaths,
                       H, source, destination, 0)
예제 #21
0
 def test_raises_exception_if_values_of_function_are_not__in_hypergraph(
         self):
     s1, s2, s3 = 1, 2, 3
     H = DirectedHypergraph()
     H.add_nodes([s1, s2])
     e1 = H.add_hyperedge([s1], [s2])
     T = {s1: None, s2: 'e2'}
     self.assertRaises(KeyError,
                       directed_paths.get_hyperpath_from_predecessors,
                       H, T, s1, s2)
예제 #22
0
def get_hypertree_from_predecessors(H, Pv, source_node,
                                    node_weights=None, attr_name="weight"):
    """Gives the hypertree (i.e., the subhypergraph formed from the union of
    the set of paths from an execution of, e.g., the SBT algorithm) defined by
    Pv beginning at a source node. Returns a dictionary mapping each node to
    the ID of the hyperedge that preceeded it in the path (i.e., a Pv vector).
    Assigns the node weights (if provided) as attributes of the nodes (e.g.,
    the rank of that node in a specific instance of the SBT algorithm, or the
    cardinality of that node in a B-Visit traversal, etc.).

    :note: The IDs of the hyperedges in the subhypergraph returned may be
        different than those in the original hypergraph (even though the
        tail and head sets are identical).

    :param H: the hypergraph which the path algorithm was executed on.
    :param Pv: dictionary mapping each node to the ID of the hyperedge that
            preceeded it in the path.
    :param source_node: the root of the executed path algorithm.
    :param node_weights: [optional] dictionary mapping each node to some weight
                        measure.
    :param attr_name: key into the nodes' attribute dictionaries for their
                    weight values (if node_weights is provided).
    :returns: DirectedHypergraph -- subhypergraph induced by the path
            algorithm specified by the predecessor vector (Pv) from a
            source node.
    :raises: TypeError -- Algorithm only applicable to directed hypergraphs

    """
    if not isinstance(H, DirectedHypergraph):
        raise TypeError("Algorithm only applicable to directed hypergraphs")

    sub_H = DirectedHypergraph()

    # If node weights are not provided, simply collect all the nodes that are
    # will be in the hypertree
    if node_weights is None:
        nodes = [node for node in Pv.keys() if Pv[node] is not None]
        nodes.append(source_node)
    # If node weights are provided, collect all the nodes that will be in the
    # tree and pair them with their corresponding weights
    else:
        nodes = [(node, {attr_name: node_weights[node]})
                 for node in Pv.keys() if Pv[node] is not None]
        nodes.append((source_node, {attr_name: node_weights[source_node]}))
    # Add the collected elements to the hypergraph
    sub_H.add_nodes(nodes)

    # Add all hyperedges, specified by Pv, to the hypergraph
    hyperedges = [(H.get_hyperedge_tail(hyperedge_id),
                   H.get_hyperedge_head(hyperedge_id),
                   H.get_hyperedge_attributes(hyperedge_id))
                  for hyperedge_id in Pv.values() if hyperedge_id is not None]
    sub_H.add_hyperedges(hyperedges)

    return sub_H
 def test_returns_disconnected_nodes_on_graph_with_two_nodes(self):
     H = DirectedHypergraph()
     s, t = 's', 't'
     H.add_node(s)
     H.add_node(t)
     e1 = H.add_hyperedge({s}, {t})
     predecessor = {s: None, t: e1}
     ordering = [s, t]
     branch = ksh._branching_step(H, predecessor, ordering)[0]
     self.assertEqual(branch.get_hyperedge_id_set(), set([]))
     self.assertEqual(branch.get_node_set(), {'s', 't'})
예제 #24
0
def test_is_connected():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    assert directed_paths.is_connected(H, 's', 'x')
    assert directed_paths.is_connected(H, 's', 'y')
    assert directed_paths.is_connected(H, 's', 'z')
    assert directed_paths.is_connected(H, 's', 't')
    assert directed_paths.is_connected(H, 's', 'u')
    assert directed_paths.is_connected(H, 's', 'a')
    assert not directed_paths.is_connected(H, 's', 'b')
예제 #25
0
def test_shortest_sum_b_tree():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    Pv, W, valid_ordering = \
        directed_paths.shortest_b_tree(
            H, 's', directed_paths.sum_function, True)

    assert valid_ordering.count('s') == 1
    assert valid_ordering.index('s') < valid_ordering.index('x')
    assert valid_ordering.index('s') < valid_ordering.index('y')
    assert valid_ordering.index('s') < valid_ordering.index('z')
    assert valid_ordering.index('s') < valid_ordering.index('t')
    assert valid_ordering.index('s') < valid_ordering.index('u')
    assert valid_ordering.count('x') == 1
    assert valid_ordering.index('x') < valid_ordering.index('t')
    assert valid_ordering.index('x') < valid_ordering.index('u')
    assert valid_ordering.count('y') == 1
    assert valid_ordering.index('y') < valid_ordering.index('t')
    assert valid_ordering.index('y') < valid_ordering.index('u')
    assert valid_ordering.count('z') == 1
    assert valid_ordering.index('z') < valid_ordering.index('t')
    assert valid_ordering.index('z') < valid_ordering.index('u')
    assert valid_ordering.count('t') == 1
    assert valid_ordering.count('u') == 1
    assert valid_ordering.count('a') == 0
    assert valid_ordering.count('b') == 0

    assert Pv['s'] is None
    assert Pv['x'] == 'e1'
    assert Pv['y'] == 'e2'
    assert Pv['z'] == 'e3'
    assert Pv['t'] == 'e4'
    assert Pv['u'] == 'e4'
    assert (Pv['a'], Pv['b']) == (None, None)

    assert W['s'] == 0
    assert W['x'] == 1
    assert W['y'] == 2
    assert W['z'] == 2
    assert W['u'] == 8
    assert W['t'] == 8
    assert W['a'] == float('inf')
    assert W['b'] == float('inf')

    # Try an invalid hypergraph
    try:
        directed_paths.shortest_b_tree('s', 't')
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
def test_to_networkx_digraph():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    G = directed_graph_transformations.to_networkx_digraph(H)

    H_nodes = H.get_node_set()
    G_nodes = G.node.keys()

    assert H_nodes == set(G_nodes)

    H_nodes_attributes = [H.get_node_attributes(node) for node in H_nodes]
    for node in G_nodes:
        assert G.node[node] in H_nodes_attributes

    for hyperedge_id in H.hyperedge_id_iterator():
        tail_set = H.get_hyperedge_tail(hyperedge_id)
        head_set = H.get_hyperedge_head(hyperedge_id)
        for tail_node in tail_set:
            for head_node in head_set:
                assert G[tail_node][head_node]

    # Try transforming an invalid directed hypergraph
    try:
        directed_graph_transformations.to_networkx_digraph("invalid H")
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #27
0
def test_max_indegree():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    assert directed_statistics.max_indegree(H) == 3

    # Try counting an invalid directed hypergraph
    try:
        directed_statistics.max_indegree("invalid hypergraph")
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #28
0
def test_number_of_nodes():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    assert directed_statistics.number_of_nodes(H) == 8

    # Try counting an invalid directed hypergraph
    try:
        directed_statistics.number_of_nodes("invalid hypergraph")
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
    def test_returns_empty_list_if_no_s_t_path(self):
        H = DirectedHypergraph()
        H.add_node('s')
        H.add_node('1')
        H.add_node('2')
        H.add_node('t')
        H.add_hyperedge({'s'}, {'1'}, weight=1)
        H.add_hyperedge({'1', '2'}, {'t'}, weight=1)

        output = ksh.k_shortest_hyperpaths(H, 's', 't', 1)
        self.assertEqual(output, [])
예제 #30
0
 def test_returns_hyperpath_for_simple_tree(self):
     s1, s2, s3, s4 = 1, 2, 3, 4
     H = DirectedHypergraph()
     H.add_nodes([s1, s2, s3, s4])
     e1 = H.add_hyperedge([s1], [s2])
     e2 = H.add_hyperedge([s1], [s3])
     e3 = H.add_hyperedge([s3], [s4])
     T = {s4: e3, s3: e2, s2: e1, s1: None}
     path = directed_paths.get_hyperpath_from_predecessors(H, T, s1, s4)
     # validate nodes
     self.assertEqual(path.get_node_set(), {s1, s3, s4})
     # validate hyperedges
     self.assertEqual(len(path.get_hyperedge_id_set()), 2)
     self.assertTrue(path.get_hyperedge_id([1], [3]))
     self.assertTrue(path.get_hyperedge_id([3], [4]))
예제 #31
0
def test_add_hyperedge():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'

    tail = set([node_a, node_b])
    head = set([node_c, node_d])
    frozen_tail = frozenset(tail)
    frozen_head = frozenset(head)

    attrib = {'weight': 6, 'color': 'black'}

    H = DirectedHypergraph()
    H.add_node(node_a, label=1337)
    hyperedge_name = H.add_hyperedge(tail, head, attrib, weight=5)

    assert hyperedge_name == 'e1'

    # Test that all hyperedge attributes are correct
    assert H._hyperedge_attributes[hyperedge_name]['tail'] == tail
    assert H._hyperedge_attributes[hyperedge_name]['head'] == head
    assert H._hyperedge_attributes[hyperedge_name]['weight'] == 5
    assert H._hyperedge_attributes[hyperedge_name]['color'] == 'black'

    # Test that successor list contains the correct info
    assert frozen_head in H._successors[frozen_tail]
    assert hyperedge_name in H._successors[frozen_tail][frozen_head]

    # Test that the precessor list contains the correct info
    assert frozen_tail in H._predecessors[frozen_head]
    assert hyperedge_name in H._predecessors[frozen_head][frozen_tail]

    # Test that forward-stars and backward-stars contain the correct info
    for node in frozen_tail:
        assert hyperedge_name in H._forward_star[node]
    for node in frozen_head:
        assert hyperedge_name in H._backward_star[node]

    # Test that adding same hyperedge will only update attributes
    new_attrib = {'weight': 10}
    H.add_hyperedge(tail, head, new_attrib)
    assert H._hyperedge_attributes[hyperedge_name]['weight'] == 10
    assert H._hyperedge_attributes[hyperedge_name]['color'] == 'black'

    try:
        H.add_hyperedge(set(), set())
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e
예제 #32
0
    def test_returns_hyperpath_when_node_is_in_tail_of_two_edges(self):
        s1, s2, s3 = 1, 2, 3
        s4 = 4
        H = DirectedHypergraph()
        e1 = H.add_hyperedge([s1], [s2])
        e2 = H.add_hyperedge([s2], [s3])
        e3 = H.add_hyperedge([s2, s3], [s4])

        T = {s4: e3, s3: e2, s2: e1, s1: None}
        path = directed_paths.get_hyperpath_from_predecessors(H, T, s1, s4)
        # validate nodes
        self.assertEqual(path.get_node_set(), {s1, s2, s3, s4})
        # validate hyperedges
        self.assertEqual(len(path.get_hyperedge_id_set()), 3)
        self.assertTrue(path.get_hyperedge_id([2, 3], [4]))
        self.assertTrue(path.get_hyperedge_id([2], [3]))
        self.assertTrue(path.get_hyperedge_id([1], [2]))
예제 #33
0
def test_get_hyperedge_attribute():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    attrib = {'weight': 6, 'color': 'black'}
    common_attrib = {'sink': False}

    hyperedges = [(tail1, head1, attrib), (tail2, head2)]

    H = DirectedHypergraph()
    hyperedge_names = \
        H.add_hyperedges(hyperedges, common_attrib, color='white')

    assert H.get_hyperedge_attribute('e1', 'weight') == 6
    assert H.get_hyperedge_attribute('e1', 'color') == 'black'
    assert H.get_hyperedge_attribute('e1', 'sink') is False

    # Try requesting an invalid hyperedge
    try:
        H.get_hyperedge_attribute('e5', 'weight')
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Try requesting an invalid attribute
    try:
        H.get_hyperedge_attribute('e1', 'source')
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e
예제 #34
0
def test_hyperedge_cardinality_pairs_list():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    returned = directed_statistics.hyperedge_cardinality_pairs_list(H)
    actual = [(1, 1), (1, 2), (1, 1), (3, 2), (1, 2), (1, 1), (2, 1), (1, 1)]
    assert sorted(returned) == sorted(actual)

    # Try counting an invalid directed hypergraph
    try:
        directed_statistics.hyperedge_cardinality_pairs_list(
            "invalid hypergraph")
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #35
0
def test_shortest_sum_f_tree():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    Pv, W = directed_paths.shortest_f_tree(H, 't', directed_paths.sum_function)

    assert Pv['s'] == 'e8'
    assert Pv['x'] == 'e6'
    assert (Pv['y'], Pv['z'], Pv['t'], Pv['u'], Pv['a'], Pv['b']) == \
        (None, None, None, None, None, None)

    assert W['t'] == 0
    assert W['s'] == 100
    assert W['x'] == 101
    assert (W['y'], W['z'], W['u'], W['a'], W['b']) == \
        (float('inf'), float('inf'), float('inf'),
         float('inf'), float('inf'))
예제 #36
0
 def setUp(self):
     self.nielsenGraph = DirectedHypergraph()
     self.nielsenGraph.add_node('s')
     self.nielsenGraph.add_node('1')
     self.nielsenGraph.add_node('2')
     self.nielsenGraph.add_node('3')
     self.nielsenGraph.add_node('4')
     self.nielsenGraph.add_node('t')
     self.nielsenGraph.add_hyperedge({'s'}, {'1'}, weight=1)
     self.nielsenGraph.add_hyperedge({'s'}, {'2'}, weight=1)
     self.nielsenGraph.add_hyperedge({'s'}, {'3'}, weight=1)
     self.nielsenGraph.add_hyperedge({'1'}, {'2'}, weight=1)
     self.nielsenGraph.add_hyperedge({'2'}, {'3'}, weight=1)
     self.nielsenGraph.add_hyperedge({'1', '2'}, {'t'}, weight=1)
     self.nielsenGraph.add_hyperedge({'4'}, {'t'}, weight=1)
     self.nielsenGraph.add_hyperedge({'2', '3'}, {'4'}, weight=1)
     self.nielsenGraph.add_hyperedge({'4'}, {'1'}, weight=1)
예제 #37
0
def test_get_predecessors():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'
    node_e = 'E'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    tail3 = set([node_d])
    head3 = set([node_e])
    frozen_tail3 = frozenset(tail3)
    frozen_head3 = frozenset(head3)

    hyperedges = [(tail1, head1), (tail2, head2), (tail3, head3), (tail3, "F")]

    H = DirectedHypergraph()
    hyperedge_names = H.add_hyperedges(hyperedges)

    assert 'e1' in H.get_predecessors(head1)
    assert 'e2' in H.get_predecessors(head2)
    assert 'e3' in H.get_predecessors(head3)
    assert 'e4' in H.get_predecessors("F")

    assert H.get_predecessors([node_a]) == set()
예제 #38
0
def test_remove_hyperedges():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'
    node_e = 'E'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    tail3 = set([node_d])
    head3 = set([node_e])
    frozen_tail3 = frozenset(tail3)
    frozen_head3 = frozenset(head3)

    attrib = {'weight': 6, 'color': 'black'}
    common_attrib = {'sink': False}

    hyperedges = [(tail1, head1, attrib), (tail2, head2), (tail3, head3)]

    H = DirectedHypergraph()
    hyperedge_names = \
        H.add_hyperedges(hyperedges, common_attrib, color='white')
    H.remove_hyperedges(['e1', 'e3'])

    assert 'e1' not in H._hyperedge_attributes
    assert frozen_tail1 not in H._successors
    assert frozen_head1 not in H._predecessors
    assert 'e1' not in H._forward_star[node_a]
    assert 'e1' not in H._forward_star[node_b]
    assert 'e1' not in H._backward_star[node_c]
    assert 'e1' not in H._backward_star[node_d]

    assert 'e3' not in H._hyperedge_attributes
    assert frozen_tail3 not in H._successors
    assert frozen_head3 not in H._predecessors
    assert 'e3' not in H._forward_star[node_d]
    assert 'e3' not in H._backward_star[node_e]
예제 #39
0
def to_graph_decomposition(H):
    """Returns a DirectedHypergraph object that has the same nodes (and
    corresponding attributes) as the given hypergraph, except that for all
    hyperedges in the given hypergraph, each node in the tail of the hyperedge
    is pairwise connected to each node in the head of the hyperedge in the
    new hypergraph.
    Said another way, each of the original hyperedges are decomposed in the
    new hypergraph into fully-connected bipartite components.

    :param H: the hypergraph to decompose into a graph.
    :returns: DirectedHypergraph -- the decomposed hypergraph.
    :raises: TypeError -- Transformation only applicable to
            directed hypergraphs

    """
    if not isinstance(H, DirectedHypergraph):
        raise TypeError("Transformation only applicable to \
                        directed hypergraphs")

    G = DirectedHypergraph()

    nodes = [(node, H.get_node_attributes(node_attributes))
             for node in G.node_iterator()]
    G.add_nodes(nodes)

    edges = [([tail_node], [head_node])
             for hyperedge_id in H.hyperedge_id_iterator()
             for tail_node in H.get_hyperedge_tail(hyperedge_id)
             for head_node in H.get_hyperedge_head(hyperedge_id)]
    G.add_hyperedges(edges)

    return G
예제 #40
0
def test_add_hyperedges():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    attrib = {'weight': 6, 'color': 'black'}
    common_attrib = {'sink': False}

    hyperedges = [(tail1, head1, attrib), (tail2, head2)]

    H = DirectedHypergraph()
    hyperedge_names = \
        H.add_hyperedges(hyperedges, common_attrib, color='white')

    assert 'e1' in hyperedge_names
    assert 'e2' in hyperedge_names

    assert H._hyperedge_attributes['e1']['tail'] == tail1
    assert H._hyperedge_attributes['e1']['head'] == head1
    assert H._hyperedge_attributes['e1']['weight'] == 6
    assert H._hyperedge_attributes['e1']['color'] == 'black'
    assert H._hyperedge_attributes['e1']['sink'] is False

    assert H._hyperedge_attributes['e2']['tail'] == tail2
    assert H._hyperedge_attributes['e2']['head'] == head2
    assert H._hyperedge_attributes['e2']['weight'] == 1
    assert H._hyperedge_attributes['e2']['color'] == 'white'
    assert H._hyperedge_attributes['e2']['sink'] is False

    assert set(hyperedge_names) == H.get_hyperedge_id_set()
    for hyperedge_id in H.hyperedge_id_iterator():
        assert hyperedge_id in hyperedge_names
예제 #41
0
def test_f_visit():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    # Let 's' be the source node:
    f_visited_nodes, Pv, Pe, v = directed_paths.f_visit(H, 's')

    assert f_visited_nodes == set(['s', 'x'])

    assert Pv['s'] is None
    assert v['s'] == 0
    assert Pe['e1'] == 'x'
    assert (Pe['e2'], Pe['e3'], Pe['e4'], Pe['e5'], Pe['e7']) == \
        (None, None, None, None, None)
    assert (Pv['y'], Pv['z'], Pv['u'], Pv['t'], Pv['a'], Pv['b']) == \
        (None, None, None, None, None, None)

    # Let 't' be the source node:
    f_visited_nodes, Pv, Pe, v = directed_paths.f_visit(H, 't')

    assert f_visited_nodes == set(['t', 's', 'x'])

    assert Pv['t'] is None
    assert Pv['s'] == 'e8'
    assert Pv['x'] == 'e6'
    assert (Pv['y'], Pv['z'], Pv['u'], Pv['a'], Pv['b']) == \
        (None, None, None, None, None)
    assert Pe["e8"] == 't'
    assert Pe["e6"] == 's'
    assert Pe["e1"] == 'x'
    assert (Pe["e2"], Pe["e3"], Pe["e4"],
            Pe["e5"], Pe["e7"]) == \
        (None, None, None, None, None)

    # Try invalid F-visit
    try:
        directed_paths.f_visit('s', 't')
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #42
0
def trim(H, F, e, source, taildistancelist):
    '''
    Takes the edge list F, which is a super path from the source vertex to e and repeatedly removes an edge and checks reachability for each edge in F
    Returns the trimmed edge list and prints that the sink is not reachable from the source if the original edge set is not a superpath
    '''
    sortededges = []
    if e[0] != 'e':
        reachingset = [e]
    else:
        reachingset = H.get_hyperedge_tail(e)

    for f in F:
        sortededges.append((taildistancelist[f], f))
    sortededges.sort()
    justedges = [s[1] for s in sortededges]
    H2 = DirectedHypergraph()
    H2.add_node(source)
    H2edgeids = {}
    for f in justedges:
        newf = H2.add_hyperedge(H.get_hyperedge_tail(f),
                                H.get_hyperedge_head(f))
        H2edgeids[f] = newf
    nodeset, _, __, ___ = b_visit(H2, source)
    isereached = True
    for v in reachingset:
        if v not in nodeset:
            isereached = False
    if isereached == False:
        print('invalid edge set given to trim. Sink not reachable from source')
        print(nodeset)
    F2 = []
    tailedges = []
    for f in justedges:
        H2.remove_hyperedge(H2edgeids[f])
        nodeset, _, __, ___ = b_visit(H2, source)
        isereached = True
        for v in reachingset:
            if v not in nodeset:
                isereached = False
        if isereached == False:
            #This means we cannot remove f
            newf = H2.add_hyperedge(H.get_hyperedge_tail(f),
                                    H.get_hyperedge_head(f))
            H2edgeids[f] = newf
            F2.append(f)
            if e[0] == 'e':
                for v in H.get_hyperedge_tail(e):
                    if v in H.get_hyperedge_head(f):
                        tailedges.append(f)
    if e[0] == 'e':
        F2.append(e)
    return F2, tailedges
예제 #43
0
def from_networkx_digraph(nx_digraph):
    """Returns a DirectedHypergraph object that is the graph equivalent of the
    given NetworkX DiGraph object.

    :param nx_digraph: the NetworkX directed graph object to transform.
    :returns: DirectedHypergraph -- hypergraph object equivalent to the
            NetworkX directed graph.
    :raises: TypeError -- Transformation only applicable to directed
            NetworkX graphs

    """
    import networkx as nx

    if not isinstance(nx_digraph, nx.DiGraph):
        raise TypeError("Transformation only applicable to directed \
                        NetworkX graphs")

    G = DirectedHypergraph()

    for node in nx_digraph.nodes():
        G.add_node(node, **copy.copy(nx_digraph.nodes[node]))

    for edge in nx_digraph.edges():
        tail_node = edge[0]
        head_node = edge[1]
        G.add_hyperedge(tail_node, head_node,
                        copy.copy(nx_digraph[tail_node][head_node]))

    return G
예제 #44
0
 def test_raises_exception_if_H_not_B_hypegraph(self):
     H = DirectedHypergraph()
     H.add_nodes([1, 2, 3])
     H.add_hyperedge([1], [2, 3])
     source, destination = 1, 2
     self.assertRaises(TypeError, ksh.k_shortest_hyperpaths, H, source,
                       destination, 1)
예제 #45
0
def get_hypertree_from_predecessors(H,
                                    Pv,
                                    source_node,
                                    node_weights=None,
                                    attr_name="weight"):
    """Gives the hypertree (i.e., the subhypergraph formed from the union of
    the set of paths from an execution of, e.g., the SBT algorithm) defined by
    Pv beginning at a source node. Returns a dictionary mapping each node to
    the ID of the hyperedge that preceeded it in the path (i.e., a Pv vector).
    Assigns the node weights (if provided) as attributes of the nodes (e.g.,
    the rank of that node in a specific instance of the SBT algorithm, or the
    cardinality of that node in a B-Visit traversal, etc.).

    :note: The IDs of the hyperedges in the subhypergraph returned may be
        different than those in the original hypergraph (even though the
        tail and head sets are identical).

    :param H: the hypergraph which the path algorithm was executed on.
    :param Pv: dictionary mapping each node to the ID of the hyperedge that
            preceeded it in the path.
    :param source_node: the root of the executed path algorithm.
    :param node_weights: [optional] dictionary mapping each node to some weight
                        measure.
    :param attr_name: key into the nodes' attribute dictionaries for their
                    weight values (if node_weights is provided).
    :returns: DirectedHypergraph -- subhypergraph induced by the path
            algorithm specified by the predecessor vector (Pv) from a
            source node.
    :raises: TypeError -- Algorithm only applicable to directed hypergraphs

    """
    if not isinstance(H, DirectedHypergraph):
        raise TypeError("Algorithm only applicable to directed hypergraphs")

    sub_H = DirectedHypergraph()

    # If node weights are not provided, simply collect all the nodes that are
    # will be in the hypertree
    if node_weights is None:
        nodes = [node for node in Pv.keys() if Pv[node] is not None]
        nodes.append(source_node)
    # If node weights are provided, collect all the nodes that will be in the
    # tree and pair them with their corresponding weights
    else:
        nodes = [(node, {
            attr_name: node_weights[node]
        }) for node in Pv.keys() if Pv[node] is not None]
        nodes.append((source_node, {attr_name: node_weights[source_node]}))
    # Add the collected elements to the hypergraph
    sub_H.add_nodes(nodes)

    # Add all hyperedges, specified by Pv, to the hypergraph
    hyperedges = [(H.get_hyperedge_tail(hyperedge_id),
                   H.get_hyperedge_head(hyperedge_id),
                   H.get_hyperedge_attributes(hyperedge_id))
                  for hyperedge_id in Pv.values() if hyperedge_id is not None]
    sub_H.add_hyperedges(hyperedges)

    return sub_H
예제 #46
0
def test_shortest_gap_b_tree():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    Pv, W = \
        directed_paths.shortest_b_tree(H, 's', directed_paths.gap_function)

    assert Pv['s'] is None
    assert Pv['x'] == 'e1'
    assert Pv['y'] == 'e2'
    assert Pv['z'] == 'e3'
    assert Pv['t'] == 'e4'
    assert Pv['u'] == 'e4'
    assert (Pv['a'], Pv['b']) == (None, None)

    assert W['s'] == 0
    assert W['x'] == 1
    assert W['y'] == 2
    assert W['z'] == 2
    assert W['u'] == 4
    assert W['t'] == 4
    assert W['a'] == float('inf')
    assert W['b'] == float('inf')
def convert_bpmn_to_process_hgraph(bpmn_file_name):
    hyperg = DirectedHypergraph()
    #namespace
    ns = {'bpmn': 'http://www.omg.org/spec/BPMN/20100524/MODEL'}
    #parse bpmn file
    tree = ET.parse(file_name)
    bpmndiagram = tree.getroot()
    #parse process
    processes = bpmndiagram.findall("./bpmn:process", ns)
    for process in processes:
        #pick start event
        starts = bpmndiagram.findall("./bpmn:process/bpmn:startEvent", ns)
        for start in starts:
            hyperg.add_node(start.attrib['id'],
                            name=start.attrib['name'],
                            cost=0.1,
                            qual=0.1,
                            avail=0.1,
                            time=0.1)
            #logger.info(get_tag(start))
            visited = []
            hyperg = inspect_task(start, hyperg, bpmndiagram, [])
    print_hg_std_out_only(hyperg)
    return hyperg
예제 #48
0
def test_to_graph_decomposition():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    G = directed_graph_transformations.to_graph_decomposition(H)
    G._check_consistency()

    assert G.get_node_set() == H.get_node_set()

    for hyperedge_id in G.hyperedge_id_iterator():
        tail_set = G.get_hyperedge_tail(hyperedge_id)
        head_set = G.get_hyperedge_head(hyperedge_id)
        assert len(tail_set) == 1
        assert len(head_set) == 1
        assert G.has_hyperedge(tail_set.pop(), head_set.pop())

    # Try posting an invalid directed hypergraph
    try:
        directed_graph_transformations.to_graph_decomposition("invalid H")
        assert False
    except TypeError:
        pass
    except BaseException as e:
        assert False, e
예제 #49
0
def test_get_induced_subhypergraph():
    H = DirectedHypergraph()
    H.read("tests/data/basic_directed_hypergraph.txt")

    induce_on_nodes = H.get_node_set() - {'t'}
    induced_H = H.get_induced_subhypergraph(induce_on_nodes)

    induced_nodes = induced_H.get_node_set()
    assert induced_nodes == H.get_node_set() - {'t'}

    hyperedges = [(induced_H.get_hyperedge_tail(hyperedge_id),
                   induced_H.get_hyperedge_head(hyperedge_id))
                  for hyperedge_id in induced_H.get_hyperedge_id_set()]
    for hyperedge in hyperedges:
        tail, head = hyperedge
        assert set(tail) - induce_on_nodes == set()
        assert set(head) - induce_on_nodes == set()
        assert H.has_hyperedge(tail, head)
예제 #50
0
def test_get_backward_star():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'
    node_e = 'E'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    tail3 = set([node_d])
    head3 = set([node_e])
    frozen_tail3 = frozenset(tail3)
    frozen_head3 = frozenset(head3)

    hyperedges = [(tail1, head1), (tail2, head2), (tail3, head3)]

    H = DirectedHypergraph()
    hyperedge_names = H.add_hyperedges(hyperedges)

    assert H.get_backward_star(node_a) == set(['e2'])
    assert H.get_backward_star(node_b) == set()
    assert H.get_backward_star(node_c) == set(['e1'])
    assert H.get_backward_star(node_d) == set(['e1', 'e2'])
    assert H.get_backward_star(node_e) == set(['e3'])

    # Try requesting an invalid node
    try:
        H.get_backward_star("F")
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e
예제 #51
0
    def test_returns_hyperpath_for_tree_with_multiple_nodes_in_tail(self):
        s1, s2, s3 = 1, 2, 3
        s4, s5, s6 = 4, 5, 6
        H = DirectedHypergraph()
        H.add_nodes([s1, s2, s3, s4, s5, s6])
        e1 = H.add_hyperedge([s1], [s2])
        e2 = H.add_hyperedge([s1], [s3])
        e3 = H.add_hyperedge([s1], [s4])
        e4 = H.add_hyperedge([s2, s3], [s5])
        e5 = H.add_hyperedge([s5], [s6])

        T = {s6: e5, s5: e4, s4: e3, s3: e2, s2: e1, s1: None}
        path = directed_paths.get_hyperpath_from_predecessors(H, T, s1, s6)
        # validate nodes
        self.assertEqual(path.get_node_set(), {s1, s2, s3, s5, s6})
        # validate hyperedges
        self.assertEqual(len(path.get_hyperedge_id_set()), 4)
        self.assertTrue(path.get_hyperedge_id([5], [6]))
        self.assertTrue(path.get_hyperedge_id([2, 3], [5]))
        self.assertTrue(path.get_hyperedge_id([1], [3]))
        self.assertTrue(path.get_hyperedge_id([1], [2]))
예제 #52
0
 def test_returns_hyperpath_for_simple_tree(self):
     s1, s2, s3, s4 = 1, 2, 3, 4
     H = DirectedHypergraph()
     H.add_nodes([s1, s2, s3, s4])
     e1 = H.add_hyperedge([s1], [s2])
     e2 = H.add_hyperedge([s1], [s3])
     e3 = H.add_hyperedge([s3], [s4])
     T = {s4: e3, s3: e2, s2: e1, s1: None}
     path = directed_paths.get_hyperpath_from_predecessors(H, T, s1, s4)
     # validate nodes
     self.assertEqual(path.get_node_set(), {s1, s3, s4})
     # validate hyperedges
     self.assertEqual(len(path.get_hyperedge_id_set()), 2)
     self.assertTrue(path.get_hyperedge_id([1], [3]))
     self.assertTrue(path.get_hyperedge_id([3], [4]))
예제 #53
0
def test_get_hyperedge_id():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    node_d = 'D'
    node_e = 'E'

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    tail3 = set([node_d])
    head3 = set([node_e])
    frozen_tail3 = frozenset(tail3)
    frozen_head3 = frozenset(head3)

    attrib = {'weight': 6, 'color': 'black'}
    common_attrib = {'sink': False}

    hyperedges = [(tail1, head1, attrib), (tail2, head2), (tail3, head3)]

    H = DirectedHypergraph()
    hyperedge_names = \
        H.add_hyperedges(hyperedges, common_attrib, color='white')

    assert H.get_hyperedge_id(tail1, head1) == 'e1'
    assert H.get_hyperedge_id(tail2, head2) == 'e2'
    assert H.get_hyperedge_id(tail3, head3) == 'e3'

    try:
        H.get_hyperedge_id(tail1, head2)
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e
예제 #54
0
def setup_conversion_pnet_to_hg(file_root, input_eval_dir, output_eval_dir):
    '''

    :param file_root:
    :param input_eval_dir
    :param output_eval_dir:
    '''

    # extract root of pnml file: onet
    #pnet = get_pnml_tree(input_eval_dir, file_root).getroot()
    file_name = input_eval_dir + "/" + file_root + ".pnml"

    # setup logger
    #logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s', filename=log_file,level=logging.DEBUG)

    hg = DirectedHypergraph()

    # STEP 1: convert pnet into hypergraph + tau post processing
    start_time_conv = time()

    hg = convert_to_hg_and_rw_pnml(file_name)

    end_time_conv = time()
    conv_pnet_to_hg_time = end_time_conv - start_time_conv
    print("{1}: Conversion Petri net to hypergraph took: {0}s".format(
        conv_pnet_to_hg_time, file_root))

    start_time_post = time()
    hg = tau_post_processing(hg)
    end_time_post = time()
    tau_post_time = end_time_post - start_time_post
    print("{1}: Tau post processing on hypergraph took: {0}".format(
        tau_post_time, file_root))
    #STEP 2: randomly initialise hypergraph's nodes utility values
    hg = random_init_attributes(hg)
    # TBC TBC TBC: PERSIST hg ON FILE
    print("{0}: Hypergraph utility randomly initialised".format("file_root"))

    return (hg, conv_pnet_to_hg_time, tau_post_time)
예제 #55
0
def test_copy():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    attrib_c = {'alt_name': 1337}
    common_attrib = {'common': True, 'source': False}

    node_list = [node_a, (node_b, {'source': True}), (node_c, attrib_c)]

    node_d = 'D'

    H = DirectedHypergraph()
    H.add_nodes(node_list, common_attrib)

    tail1 = set([node_a, node_b])
    head1 = set([node_c, node_d])
    frozen_tail1 = frozenset(tail1)
    frozen_head1 = frozenset(head1)

    tail2 = set([node_b, node_c])
    head2 = set([node_d, node_a])
    frozen_tail2 = frozenset(tail2)
    frozen_head2 = frozenset(head2)

    attrib = {'weight': 6, 'color': 'black'}
    common_attrib = {'sink': False}

    hyperedges = [(tail1, head1, attrib), (tail2, head2)]

    hyperedge_names = \
        H.add_hyperedges(hyperedges, common_attrib, color='white')

    new_H = H.copy()

    assert new_H._node_attributes == H._node_attributes
    assert new_H._hyperedge_attributes == H._hyperedge_attributes

    assert new_H._backward_star == H._backward_star
    assert new_H._forward_star == H._forward_star

    assert new_H._successors == H._successors
    assert new_H._predecessors == H._predecessors
def makeHypergraph(model):

    S = create_stoichiometric_matrix(model, array_type='DataFrame')
    H = DirectedHypergraph()

    for i in range(len(S.columns)):
        nodes_df = S.iloc[:, i][S.iloc[:, i] != 0]

        edge_name = nodes_df.name
        head_nodes = set(nodes_df[nodes_df > 0].index)
        tail_nodes = set(nodes_df[nodes_df < 0].index)

        H.add_hyperedge(head_nodes, tail_nodes, {'reaction': edge_name})

        if model.reactions.get_by_id(edge_name).reversibility:

            H.add_hyperedge(tail_nodes, head_nodes,
                            {'reaction': edge_name + '_rev'})

    return H
예제 #57
0
def read_hg_from_file(file_name):
    '''
    returns a hypergraph based on the info in a file. Assumption: file_name has been written using write_hg_on_file
    :param file_name:
    '''
    hg = DirectedHypergraph()
    
    in_file = open(file_name, 'r')
    lines = in_file.readlines()
    sep = '\t'
    for line in lines:
        #line.strip()
        values = line.split(sep)
        #for value in values:
        if values[0] == 'node':
            # I am processing a node
            node_id = values[1]
            node_attrs = ast.literal_eval(values[2])
            hg.add_node(node_id, node_attrs)
        if values[0] == 'edge':
            tail = None
            head = None
            edge = values[1]
            edge_attrs = ast.literal_eval(values[2])
            # I am processsing an edge
            for j in range(2, len(values), 1):
                values[j] = values[j].strip()
                tail = edge_attrs['tail']
                #print(tail)
                #tail_list = eval(tail)
                head = edge_attrs['head']
                # turn string representation of head into an actual list
                #head_list = ast.literal_eval(head)
            #print("ID, TAIL, HEAD: {2} - {0} - {1} - {3}".format(tail,head,values[1], edge_attrs))
            hg.add_hyperedge(tail, head, edge_attrs)
    print_hg_std_out_only(hg)
    in_file.close()    
    return hg
예제 #58
0
def test_add_nodes():
    node_a = 'A'
    node_b = 'B'
    node_c = 'C'
    attrib_c = {'alt_name': 1337}
    node_d = 'D'
    attrib_d = {'label': 'black', 'sink': True}
    common_attrib = {'common': True, 'source': False}

    node_list = [
        node_a, (node_b, {
            'source': False
        }), (node_c, attrib_c), (node_d, attrib_d)
    ]

    # Test adding unadded nodes with various attribute settings
    H = DirectedHypergraph()
    H.add_nodes(node_list, common_attrib)

    assert node_a in H._node_attributes
    assert H._node_attributes[node_a] == common_attrib

    assert node_b in H._node_attributes
    assert H._node_attributes[node_b]['source'] is False

    assert node_c in H._node_attributes
    assert H._node_attributes[node_c]['alt_name'] == 1337

    assert node_d in H._node_attributes
    assert H._node_attributes[node_d]['label'] == 'black'
    assert H._node_attributes[node_d]['sink'] is True

    node_set = H.get_node_set()
    assert node_set == set(['A', 'B', 'C', 'D'])
    assert len(node_set) == len(node_list)
    for node in H.node_iterator():
        assert node in node_set
예제 #59
0
'''
Created on Jun 16, 2016

@author: UNIST
'''
from halp.directed_hypergraph import DirectedHypergraph
from org.emettelatripla.util.util import *
from org.emettelatripla.aco.ACO_directed_hypergraph import *
from org.emettelatripla.aco.ACO_util import *
import logging

# Initialize an empty hypergraph
H = DirectedHypergraph()

# Add nodes 's' and 't' individually with arbitrary attributes
H.add_node('A',
           sink=False,
           source=True,
           cost=0.245,
           avail=0.99,
           qual=0.7,
           time=0.78)
H.add_node('B',
           sink=False,
           source=False,
           cost=0.245,
           avail=0.99,
           qual=0.7,
           time=0.78)
H.add_node('C',
           sink=False,
예제 #60
0
def initialize(H, source, target, node_dict={}):
    '''
    Finds the set of reachable and backwards-recoverable edges, sets up the tail reached counters, the inedge lists,  and the heap pointer for each edge.
    Initializes the taillength for each edge, and the heap, and the reachable edge counter
    '''
    edgedict = {}

    #find reachable and backwards-recoverable edge list
    reachableedges = findreachableandbackrecoverable(H, source, target)

    #trim H
    H2 = DirectedHypergraph()
    if len(node_dict) == 0:
        for v in H.node_iterator():
            H2.add_node(v, H.get_node_attributes(v))
    for edge in reachableedges:
        H2.add_hyperedge(H.get_hyperedge_tail(edge),
                         H.get_hyperedge_head(edge),
                         weight=H.get_hyperedge_weight(edge))
    H2.add_node('SUPERSOURCE', {'label': 'SUPERSOURCE'})
    for edge in H2.get_forward_star('SUPERSOURCE'):
        forwardstarlist = []
        for v in H2.get_hyperedge_head(edge):
            if len(H2.get_forward_star(v)) > 0:
                forwardstarlist.append(v)
        H2.remove_hyperedge(edge)
        if len(forwardstarlist) > 0:
            H2.add_hyperedge(['SUPERSOURCE'], forwardstarlist, weight=0)
        else:
            H2.add_hyperedge(['SUPERSOURCE'], [], weight=0)

    H = H2
    for v in H.get_node_set():
        #need to remap the edges because just calling remove_node(v) removes also all the hyperedges v is in
        if len(H.get_forward_star(v)) == 0 and v != 'SUPERTARGET':
            #find edges that need to be replaced
            backedges = H.get_backward_star(v)
            for e in backedges:
                tail = H.get_hyperedge_tail(e)
                head = H.get_hyperedge_head(e)
                head.remove(v)
                w = H.get_hyperedge_weight(e)
                H.remove_hyperedge(e)
                H.add_hyperedge(tail, head, weight=w)
            H.remove_node(v)
    reachableedges = []
    H2.add_node('SUPERSOURCE', {'label': 'SUPERSOURCE'})
    for edge in H.hyperedge_id_iterator():
        reachableedges.append(edge)

    #initialize edgedict
    for e in H.hyperedge_id_iterator():
        edgedict[e] = {
            'isremoved': False,
            'bestinedges': [],
            'candidateinedges': [],
            'tailcount': len(H.get_hyperedge_tail(e))
        }

    #initialize taildistancelist
    taildistancelist = {}
    for e in reachableedges:
        taildistancelist[e] = 'inf'

    #initialize reachableedgecounter
    reachableedgecounter = len(reachableedges)

    #initialize heap
    heap = []
    entry_finder = {
    }  # mapping of tasks to entries, this and the line below are strictly for the heap
    counter = itertools.count()  # unique sequence count
    for e in H.get_forward_star(source):
        if e in reachableedges:
            add_node(heap, e, weight(H, [e]), counter, entry_finder)

    #initialize reachedtable
    reachedtable = {}
    for e in H.hyperedge_id_iterator():
        reachedtable[e] = []

    return reachableedges, edgedict, taildistancelist, heap, reachableedgecounter, reachedtable, entry_finder, counter, H