class TestComputeLowerBound(unittest.TestCase):

    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)

    def test_returns_12_for_lower_bound_for_nielsen_H_21(self):
        '''
            Test graph is discussed in Section 3.2 example 2 of
            Nielsen et al.\
        '''
        H_2 = self.nielsenGraph.copy()
        e1 = H_2.get_hyperedge_id({'s'}, {'1'})
        e2 = H_2.get_hyperedge_id({'1'}, {'2'})
        e3 = H_2.get_hyperedge_id({'1', '2'}, {'t'})
        H_2.remove_hyperedge(H_2.get_hyperedge_id({'s'}, {'2'}))
        H_2.remove_hyperedge(H_2.get_hyperedge_id({'4'}, {'t'}))

        # weight vector
        W = {'s': 0, '1': 1, '2': 2, '3': 1, '4': 4, 't': 4}
        # predecessor function
        pred = {'s': None, '1': e1, '2': e2, 't': e3}
        # ordering
        ordering = ['s', '1', '2', 't']

        # branch of H_2 for the test
        H_2_1 = H_2.copy()
        H_2_1.remove_hyperedge(
            H_2_1.get_hyperedge_id({'s'}, {'1'}))

        self.assertEqual(ksh._compute_lower_bound(
            H_2_1, 0, pred, ordering, W, 't'), 12)
Esempio n. 2
0
class TestComputeLowerBound(unittest.TestCase):
    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)

    def test_returns_12_for_lower_bound_for_nielsen_H_21(self):
        '''
            Test graph is discussed in Section 3.2 example 2 of
            Nielsen et al.\
        '''
        H_2 = self.nielsenGraph.copy()
        e1 = H_2.get_hyperedge_id({'s'}, {'1'})
        e2 = H_2.get_hyperedge_id({'1'}, {'2'})
        e3 = H_2.get_hyperedge_id({'1', '2'}, {'t'})
        H_2.remove_hyperedge(H_2.get_hyperedge_id({'s'}, {'2'}))
        H_2.remove_hyperedge(H_2.get_hyperedge_id({'4'}, {'t'}))

        # weight vector
        W = {'s': 0, '1': 1, '2': 2, '3': 1, '4': 4, 't': 4}
        # predecessor function
        pred = {'s': None, '1': e1, '2': e2, 't': e3}
        # ordering
        ordering = ['s', '1', '2', 't']

        # branch of H_2 for the test
        H_2_1 = H_2.copy()
        H_2_1.remove_hyperedge(H_2_1.get_hyperedge_id({'s'}, {'1'}))

        self.assertEqual(
            ksh._compute_lower_bound(H_2_1, 0, pred, ordering, W, 't'), 12)
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
Esempio n. 4
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 test_check_hyperedge_attributes_consistency():
    # make test hypergraph
    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')

    # This should not fail
    H._check_consistency()

    # The following consistency checks should fail
    # Check 1.1
    new_H = H.copy()
    del new_H._hyperedge_attributes["e1"]["weight"]
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.2
    new_H = H.copy()
    new_H._hyperedge_attributes["e1"]["tail"] = head1
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.3
    new_H = H.copy()
    new_H._hyperedge_attributes["e1"]["head"] = tail1
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.4
    new_H = H.copy()
    del new_H._successors[frozen_tail1]
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.5
    new_H = H.copy()
    del new_H._predecessors[frozen_head1]
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.6
    new_H = H.copy()
    new_H._forward_star["A"].pop()
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.7
    new_H = H.copy()
    new_H._backward_star["C"].pop()
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e
def test_check_node_consistency():
    # make test hypergraph
    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')

    # This should not fail
    H._check_consistency()

    # Check 5.1
    new_H = H.copy()
    new_H._forward_star["X"] = {}
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.2
    new_H = H.copy()
    new_H._backward_star["X"] = {}
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.3.1
    new_H = H.copy()
    new_H.add_hyperedge("X", "Y")
    del new_H._node_attributes["X"]
    del new_H._forward_star["X"]
    del new_H._forward_star["Y"]
    del new_H._backward_star["X"]
    del new_H._backward_star["Y"]
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.3.2
    new_H = H.copy()
    new_H.add_hyperedge("X", "Y")
    del new_H._node_attributes["Y"]
    del new_H._forward_star["X"]
    del new_H._forward_star["Y"]
    del new_H._backward_star["X"]
    del new_H._backward_star["Y"]
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.4
    new_H = H.copy()
    new_H._predecessors[frozenset("X")] = {}
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.5
    new_H = H.copy()
    new_H._successors[frozenset("X")] = {}
    new_H._predecessors[frozenset("X")] = {}
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e
def main():
    # setup working directory and root file
    working_dir = "C://opsupport_bpm_files"
    input_dir = working_dir + "/pnml_input"

    # files for testing ====================================================
    #file_root = "ex1_inductive"
    file_root = "bpi_challenge2012"
    #file_root = "road_fine_process"
    #file_root = "hospital_inductive"
    #file_root = "repair_start_end_inductive"

    file_type = "inductive"
    #io_subdir = "/real_logs"
    io_subdir = "/inductive"

    #MINED WITH ALPHA MINER
    #file_root = "ex6_claim_alpha"
    #file_type = "alpha"

    #pnml_file = "C://BPMNexamples/"+file_type+"/"+file_root+".pnml"
    pnml_file = input_dir + io_subdir + "/" + file_root + ".pnml"

    # output directory
    output_dir = working_dir + "/output_single"

    #setup the logger =====================================================
    log_file = working_dir + "/aco.log"
    logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s',
                        filename=log_file,
                        level=logging.DEBUG)
    logger = logging.getLogger(__name__)

    # increase recursion limit (if needed)
    # print(str(sys.getrecursionlimit()))
    # sys.setrecursionlimit(100000000)
    # print(str(sys.getrecursionlimit()))

    # ========================= A BUNCH OF FILES FOR TESTING =============================
    #pnml_file = "C://BPMNexamples/inductive/ex1_inductive.pnml"
    #pnml_file = "C://BPMNexamples/inductive/ex4_inductive.pnml"
    #pnml_file = "C://BPMNexamples/real_logs/hospital_inductive.pnml"
    #pnml_file = "C://BPMNexamples/inductive/repair_start_end_inductive.pnml"
    #pnml_file = "C://BPMNexamples/inductive/ex6_claim_inductive.pnml"
    #The following has loop:
    #pnml_file = "C://BPMNexamples/inductive/ex5_review_inductive.pnml"
    #pnml_file = "C://BPMNexamples/alpha/ex1_alpha.pnml"

    #===========================================================
    # =========================================================================================

    # ===================================================================================================
    #===========================================================
    #===========================================================
    #===========================================================

    # START: read the pnml file....
    tree = ET.parse(pnml_file)
    pnet = tree.getroot()

    hg = DirectedHypergraph()

    # STEP 1: convert pnet into hypergraph + tau post processing
    start_time_conv = time()
    hg = convert_pnet_to_hypergraph(pnet)
    end_time_conv = time()
    print(
        "Conversion Petri net to hypergraph took: {0}".format(end_time_conv -
                                                              start_time_conv))

    start_time_post = time()
    hg = tau_post_processing(hg)
    end_time_post = time()
    print(
        "Tau post processing on hypergraph took: {0}".format(end_time_post -
                                                             start_time_post))
    #STEP 2: randomly initialise hypergraph's nodes utility values
    hg = random_init_attributes(hg)

    # test write and rewrite
    hg_rw_test = hg.copy()
    reset_pheromone(hg_rw_test)
    write_hg_to_file(hg_rw_test, output_dir + "/hg_file_write.txt")
    hg_rw_read = read_hg_from_file(output_dir + "/hg_file_write.txt")
    print_hg_std_out_only(hg_rw_read)
    write_hg_to_file(hg_rw_read, output_dir + "/hg_file_rewrite.txt")

    logger.debug("@" * 70)
    logger.debug("@" * 70)
    logger.debug("@" * 70)
    logger.debug("@" * 70)
    print_hg_std_out_only(hg)
    logger.debug("@" * 70)
    logger.debug("@" * 70)
    logger.debug("@" * 70)
    print_hg_std_out_only(hg_rw_read)
    logger.debug("@" * 70)
    logger.debug("@" * 70)
    logger.debug("@" * 70)
    #     hg = hg_rw_read

    #print_hg(hg,'hyp.txt')

    #find start node (MAKE A FUNCTION FOR IT!!!!)
    """ INITIALISATION FOR RECURSIVE VERSION
    nodes = hg.get_node_set()
    start_nodes = []
    for node in nodes:
        if hg.get_node_attribute(node, 'source') == True:
            logger.debug("  ")
            logger.debug("$$$$$ Begin optimisation....$$$$$$$$$$$$$$$$$$$$$$$$")
            logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
            logger.debug("Found start node: {0}".format(print_node(node, hg)))
            logger.debug("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
            start_nodes.append(node)
    END """

    #===========================================================
    # ==================== INITIALISATION NON RECURSIVE VERSION ===========================================
    #===========================================================
    logger.debug("*" * 50)
    logger.info("*" * 50)
    logger.info("*** BEGIN ACO OPTIMISATION.... ***")
    logger.info("*" * 50)
    logger.debug("*" * 50)

    # Set ACO parameters
    tau = 0.6
    ANT_NUM = 3
    COL_NUM = 3
    W_UTILITY = {'cost': 1.0, 'avail': 0.0, 'qual': 0.0, 'time': 0.0}

    #===========================================================
    # =====================  call ACO algorithm (NON RECURSIVE)
    #===========================================================
    #p_opt = aco_algorithm(start_nodes, hg, ANT_NUM, COL_NUM, tau, W_UTILITY)
    start_time_aco = time()
    aco_result = aco_algorithm_norec(hg, ANT_NUM, COL_NUM, tau, W_UTILITY)
    p_opt = aco_result[0]
    utility = aco_result[1]
    end_time_aco = time()
    print("ACO optimisation took: {0}".format(end_time_aco - start_time_aco))
    print("ACO optimisation UTILITY: {0}".format(utility))

    # =================  highlight optimal path on pnet
    start_time_opt = time()
    show_opt_path_pnet(p_opt, tree, file_root, output_dir)

    # ================= reduce pnet to show only the optimal path
    reduce_opt_path_pnet(tree, file_root, output_dir)
    end_time_opt = time()
    print("Post processing pnet (show optimal path on pnet) took: {0}".format(
        end_time_opt - start_time_opt))
Esempio n. 8
0
def test_check_hyperedge_attributes_consistency():
    # make test hypergraph
    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')

    # This should not fail
    H._check_consistency()

    # The following consistency checks should fail
    # Check 1.1
    new_H = H.copy()
    del new_H._hyperedge_attributes["e1"]["weight"]
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.2
    new_H = H.copy()
    new_H._hyperedge_attributes["e1"]["tail"] = head1
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.3
    new_H = H.copy()
    new_H._hyperedge_attributes["e1"]["head"] = tail1
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.4
    new_H = H.copy()
    del new_H._successors[frozen_tail1]
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.5
    new_H = H.copy()
    del new_H._predecessors[frozen_head1]
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.6
    new_H = H.copy()
    new_H._forward_star["A"].pop()
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 1.7
    new_H = H.copy()
    new_H._backward_star["C"].pop()
    try:
        new_H._check_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e
Esempio n. 9
0
def test_check_node_consistency():
    # make test hypergraph
    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')

    # This should not fail
    H._check_consistency()

    # Check 5.1
    new_H = H.copy()
    new_H._forward_star["X"] = {}
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.2
    new_H = H.copy()
    new_H._backward_star["X"] = {}
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.3.1
    new_H = H.copy()
    new_H.add_hyperedge("X", "Y")
    del new_H._node_attributes["X"]
    del new_H._forward_star["X"]
    del new_H._forward_star["Y"]
    del new_H._backward_star["X"]
    del new_H._backward_star["Y"]
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.3.2
    new_H = H.copy()
    new_H.add_hyperedge("X", "Y")
    del new_H._node_attributes["Y"]
    del new_H._forward_star["X"]
    del new_H._forward_star["Y"]
    del new_H._backward_star["X"]
    del new_H._backward_star["Y"]
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.4
    new_H = H.copy()
    new_H._predecessors[frozenset("X")] = {}
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e

    # Check 5.5
    new_H = H.copy()
    new_H._successors[frozenset("X")] = {}
    new_H._predecessors[frozenset("X")] = {}
    try:
        new_H._check_node_consistency()
        assert False
    except ValueError:
        pass
    except BaseException as e:
        assert False, e