From 0189907767bf75ec2dc8a7c3828ee82170b991bc Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Thu, 1 Dec 2022 09:15:23 +0100 Subject: [PATCH 01/16] Create test.py --- test.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 test.py diff --git a/test.py b/test.py new file mode 100644 index 00000000..acfe18ae --- /dev/null +++ b/test.py @@ -0,0 +1,10 @@ +from BNReasoner import BNReasoner +from BayesNet import BayesNet + +if __name__ == "__main__": + print("begin") + net = "testing/dog_problem.BIFXML" + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + bn.draw_structure() From aad642deb99a089a9622393745dd3c88a22cf954 Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Fri, 2 Dec 2022 11:39:11 +0100 Subject: [PATCH 02/16] Update BNReasoner.py --- BNReasoner.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/BNReasoner.py b/BNReasoner.py index 34975ac6..634354c7 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -16,3 +16,31 @@ def __init__(self, net: Union[str, BayesNet]): self.bn = net # TODO: This is where your methods should go + def pruning(self, values: Dict[str, bool]) -> BayesNet: + """ Prune the network, will drop variables that are not needed anymore + + Args: + values (Dict): The given evedince to a node, must be True or False. Structure: {Node:Value} + + Returns: + p: BayesNet.object, returns the new pruned network + """ + print("pruning") + p = deepcopy(self.bn) + finished = True # Continue checking if the pruning can continue + all_cpts = p.get_all_cpts() # A dictionary of all cps in the network indexed by the variable they belong to + while finished: # Stop pruning when the network cannot be pruned further + finished = False + for a, b in values.items(): # Get node name and value + for variable in p.get_all_variables(): # Get all variables + cpt = all_cpts[variable] + if a in cpt.columns: # If variable from input matches a variable from a cpt column: + new_cpt = cpt.drop(cpt[cpt[a] != b].index) # If the same node exist with the opposite value, delete it + p.update_cpt(variable, new_cpt) # Update the cpt table without the opposite value + else: + continue + for child in p.get_children(a): # Check if the removed node has children, if yes delete edge + p.del_edge((a, child)) # Delete edge if input variable has child + finished = True + print(p.get_all_cpts()," dit is p") + return p From 73258f3497b276a299c70273a7b011e53c17efab Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Fri, 2 Dec 2022 11:40:36 +0100 Subject: [PATCH 03/16] Update test.py --- test.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index acfe18ae..635a04c9 100644 --- a/test.py +++ b/test.py @@ -3,8 +3,13 @@ if __name__ == "__main__": print("begin") - net = "testing/dog_problem.BIFXML" + net = 'testing/lecture_example.BIFXML' bn = BayesNet() bn.load_from_bifxml(net) + #bn.draw_structure() bnr = BNReasoner(bn) - bn.draw_structure() + outcome = bnr.pruning({'Rain?': False,'Winter?':True}) + #outcome.draw_structure() + + + #python3 test.py From 839286114e2b87d6eba2531c633eb1e7829048e9 Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Sat, 3 Dec 2022 09:48:46 +0100 Subject: [PATCH 04/16] Update BNReasoner.py --- BNReasoner.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/BNReasoner.py b/BNReasoner.py index 634354c7..70c66e16 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -1,6 +1,6 @@ -from typing import Union +from typing import Union, Dict, List from BayesNet import BayesNet - +from copy import deepcopy class BNReasoner: def __init__(self, net: Union[str, BayesNet]): @@ -16,12 +16,11 @@ def __init__(self, net: Union[str, BayesNet]): self.bn = net # TODO: This is where your methods should go - def pruning(self, values: Dict[str, bool]) -> BayesNet: + def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: """ Prune the network, will drop variables that are not needed anymore - Args: + query (List): Given query, used to check if nodes are part of it values (Dict): The given evedince to a node, must be True or False. Structure: {Node:Value} - Returns: p: BayesNet.object, returns the new pruned network """ @@ -31,6 +30,10 @@ def pruning(self, values: Dict[str, bool]) -> BayesNet: all_cpts = p.get_all_cpts() # A dictionary of all cps in the network indexed by the variable they belong to while finished: # Stop pruning when the network cannot be pruned further finished = False + for var in p.get_all_variables(): + if p.get_children(var) == [] and var not in query and var not in values: # Check if node is part of query + p.del_var(var) # Delete node if not part of query + finished = True for a, b in values.items(): # Get node name and value for variable in p.get_all_variables(): # Get all variables cpt = all_cpts[variable] @@ -44,3 +47,4 @@ def pruning(self, values: Dict[str, bool]) -> BayesNet: finished = True print(p.get_all_cpts()," dit is p") return p + From 4ae0110c8b4ec9333138a893ede9f7ca270d5d32 Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Sat, 3 Dec 2022 09:49:05 +0100 Subject: [PATCH 05/16] Update test.py --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 635a04c9..34064eb7 100644 --- a/test.py +++ b/test.py @@ -8,7 +8,7 @@ bn.load_from_bifxml(net) #bn.draw_structure() bnr = BNReasoner(bn) - outcome = bnr.pruning({'Rain?': False,'Winter?':True}) + outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) #outcome.draw_structure() From 29b1b80e3d1b3b5c5ddb0c36381c06892d279e36 Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Mon, 5 Dec 2022 09:31:48 +0100 Subject: [PATCH 06/16] Added d-seperation --- BNReasoner.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/BNReasoner.py b/BNReasoner.py index 70c66e16..f3394cfa 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -1,4 +1,5 @@ from typing import Union, Dict, List +from xmlrpc.client import Boolean from BayesNet import BayesNet from copy import deepcopy @@ -18,9 +19,11 @@ def __init__(self, net: Union[str, BayesNet]): # TODO: This is where your methods should go def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: """ Prune the network, will drop variables that are not needed anymore + Args: query (List): Given query, used to check if nodes are part of it values (Dict): The given evedince to a node, must be True or False. Structure: {Node:Value} + Returns: p: BayesNet.object, returns the new pruned network """ @@ -48,3 +51,38 @@ def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: print(p.get_all_cpts()," dit is p") return p + def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: + """ Check if variable x is d-seperated from y given z + + Args: + x (List): List of variables to check + y (list): List of variables to check if x is seperated from + z (list): List of given variables + + Returns: + bool: True is d-seperated, False if not + """ + p = deepcopy(self.bn) + reach_single = [] + iterated = [] + + for var in p.get_all_variables(): + if p.get_children(var) == [] and var not in x and var not in y and var not in z: + p.del_var(var) + for var in z: + for child in p.get_children(var): + p.del_edge([var, child]) + for var in x: + iterated.append(var) # Append variables to check + reach_single.extend(p.get_children(var)) # Append children + while list(set(reach_single) - set(iterated)) !=[]: # While loop makes sure children of children are checked + for a in list(set(reach_single) - set(iterated)): # Make sure all children are checked + reach_single.extend(p.get_children(a)) # Append children of children if there are any + iterated.append(a) # Append variable to prevent loop from checking again + for var_2 in y: + if var_2 in reach_single: # If y in x, not d-seperated + print(x, 'and', y, 'are not d-separated by', z) + return False + print(x, 'and', y, 'are d-separated by', z) # Else d-seperated + return True + From 4d45f59bcb9bb809fec04aeea278a31b91737e2c Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Mon, 5 Dec 2022 09:32:56 +0100 Subject: [PATCH 07/16] Update test.py --- test.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index 34064eb7..a8cc37f6 100644 --- a/test.py +++ b/test.py @@ -3,12 +3,17 @@ if __name__ == "__main__": print("begin") - net = 'testing/lecture_example.BIFXML' + net = 'testing/lecture_example.BIFXML' #'testing/dog_problem.BIFXML' bn = BayesNet() bn.load_from_bifxml(net) #bn.draw_structure() bnr = BNReasoner(bn) outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) + + ### D-seperation, use dog example + #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated + #outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated + #outcome.draw_structure() From c3d13cddf8c2df0080a6fd5ca1c9acaa1fa78724 Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Mon, 5 Dec 2022 18:15:02 +0100 Subject: [PATCH 08/16] min deg min fill --- BNReasoner.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/BNReasoner.py b/BNReasoner.py index f3394cfa..d89f88cb 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -85,4 +85,36 @@ def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: return False print(x, 'and', y, 'are d-separated by', z) # Else d-seperated return True + + def min_degree(self) -> List[str]: + """Sort the nodes by looking at the degree + + Returns: + List of variables sorted from small to big (degree in the interaction graph to the ordering) + """ + p = deepcopy(self.bn) + return [x[0] for x in sorted(p.get_interaction_graph().degree(), key = lambda x: x[1])] # Sort list and only return the variable name + + def min_fill(self) -> List[str]: + """ Minimum fill ordering + + Returns: + List of variables sorted from small to big (whose deletion would add the fewest new interaction to the ordering) + """ + p = deepcopy(self.bn) + i_graph = p.get_interaction_graph() + order_edges = [] + for node in i_graph: + i = 0 + neighbors = i_graph.neighbors(node) + for a in neighbors: + neigh_a = i_graph.neighbors(a) + for b in neighbors: + if a == b: # Do nothing + continue + if b not in neigh_a: # Count if b is not in neigh_a + i += 1 + order_edges.append((node, i)) + return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name + From b2020741226f9d4c28b685d699639f3fbfd8c47d Mon Sep 17 00:00:00 2001 From: kimjongng88 <84227372+kimjongng88@users.noreply.github.com> Date: Mon, 5 Dec 2022 18:15:28 +0100 Subject: [PATCH 09/16] Update test.py --- test.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/test.py b/test.py index a8cc37f6..c41ff03b 100644 --- a/test.py +++ b/test.py @@ -3,16 +3,26 @@ if __name__ == "__main__": print("begin") - net = 'testing/lecture_example.BIFXML' #'testing/dog_problem.BIFXML' + net = 'testing/dog_problem.BIFXML' bn = BayesNet() bn.load_from_bifxml(net) - #bn.draw_structure() + bn.draw_structure() bnr = BNReasoner(bn) - outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) - - ### D-seperation, use dog example + #outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) + + + ### D-seperation #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated - #outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated + #outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated + + + ### Order min-degree + #outcome_min_degree = bnr.min_degree() + #print(outcome_min_degree) + + ### Order min-degree + outcome_min_fill = bnr.min_fill() + print(outcome_min_fill) #outcome.draw_structure() From 7a2cd2affbc541533d5a6aae2d6885bad2681147 Mon Sep 17 00:00:00 2001 From: Jpayanshi Date: Tue, 6 Dec 2022 14:55:30 +0100 Subject: [PATCH 10/16] Sum out / Max Out --- BNReasoner.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ test.py | 15 +++++++---- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/BNReasoner.py b/BNReasoner.py index d89f88cb..96a3551f 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -2,6 +2,8 @@ from xmlrpc.client import Boolean from BayesNet import BayesNet from copy import deepcopy +import pandas as pd +from itertools import product, combinations class BNReasoner: def __init__(self, net: Union[str, BayesNet]): @@ -118,3 +120,74 @@ def min_fill(self) -> List[str]: return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name + def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + """ + :param factor: + :param subset: + :return: + """ + if isinstance(factor, str): + factor = self.bn.get_cpt(factor) + if isinstance(subset, str): + subset = [subset] + + # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get + # each possible instantiation. + ext = [c for c in factor.columns if c[:3] == 'ext'] + instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() + res_factor = pd.DataFrame(columns=factor.columns) + + if len(instantiations.columns) == 0: + try: + res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) + except IndexError: + print('w') + else: + for _, instantiation in instantiations.iterrows(): + cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) + res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) + + # For each maximized-out variable(s), rename them to ext(variable) + for v in subset: + x = res_factor.pop(v) + res_factor[f'ext({v})'] = x + + return res_factor.reset_index(drop=True) + + def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: + """ + Generate a default CPT. + :param variables: Column names + :param value: Which the default p-value should be + :return: A CPT + """ + print(variables) + truth_table = product([True, False], repeat=len(variables)) + factor = pd.DataFrame(truth_table, columns=variables) + factor['p'] = value + return factor + + def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + """ + Sum out some variable(s) in subset from a factor. + :param factor: factor over variables X + :param subset: a subset of variables X + :return: a factor corresponding to the factor with the subset summed out + """ + + if isinstance(factor, str): + factor = self.bn.get_cpt(factor) + if isinstance(subset, str): + subset = [subset] + + new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() + new_factor['p'] = 0 + subset_factor = self.init_factor(subset) + + for i, y in new_factor.iterrows(): + for _, z in subset_factor.iterrows(): + new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( + y[:-1].append(z[:-1]), factor)['p'].sum() + # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + return new_factor.reset_index(drop=True) \ No newline at end of file diff --git a/test.py b/test.py index c41ff03b..e7dc69cd 100644 --- a/test.py +++ b/test.py @@ -3,10 +3,10 @@ if __name__ == "__main__": print("begin") - net = 'testing/dog_problem.BIFXML' + net = 'testing/lecture_example.BIFXML' bn = BayesNet() bn.load_from_bifxml(net) - bn.draw_structure() + # bn.draw_structure() bnr = BNReasoner(bn) #outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) @@ -21,10 +21,15 @@ #print(outcome_min_degree) ### Order min-degree - outcome_min_fill = bnr.min_fill() - print(outcome_min_fill) + # outcome_min_fill = bnr.min_fill() + # print(outcome_min_fill) #outcome.draw_structure() - + X = "Wet Grass?" + Y = BayesNet.get_cpt(bnr.bn,X) + # f = bnr.multip_factors(Y) + print(Y) + outcome = bnr.sum_out_factors(Y,X) #bnr.maximise_out(Y,X) + print(outcome) #python3 test.py From d9bcc7d75291f508f46a63994e45a0af9003ecbd Mon Sep 17 00:00:00 2001 From: Jpayanshi Date: Thu, 8 Dec 2022 20:32:12 +0100 Subject: [PATCH 11/16] Independence Independence --- BNReasoner.py | 368 ++++++++++++++++++++++++++++++++++++++++++++++---- test.py | 58 ++++++-- 2 files changed, 387 insertions(+), 39 deletions(-) diff --git a/BNReasoner.py b/BNReasoner.py index 96a3551f..1a61f60e 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -2,7 +2,11 @@ from xmlrpc.client import Boolean from BayesNet import BayesNet from copy import deepcopy + +import numpy as np import pandas as pd +from typing import Dict, List, Optional, Tuple, Union + from itertools import product, combinations class BNReasoner: @@ -50,7 +54,7 @@ def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: for child in p.get_children(a): # Check if the removed node has children, if yes delete edge p.del_edge((a, child)) # Delete edge if input variable has child finished = True - print(p.get_all_cpts()," dit is p") + # print(p.get_all_cpts()," dit is p") return p def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: @@ -87,6 +91,15 @@ def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: return False print(x, 'and', y, 'are d-separated by', z) # Else d-seperated return True + + def random_order(self, network: BayesNet = None) -> List[str]: + """ + :return: a random ordering of all variables in self.bn + """ + if network is None: + return list(np.random.permutation(self.bn.get_all_variables())) + else: + return list(np.random.permutation(network.get_all_variables())) def min_degree(self) -> List[str]: """Sort the nodes by looking at the degree @@ -119,6 +132,41 @@ def min_fill(self) -> List[str]: order_edges.append((node, i)) return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name + def init_factor(self,variables: List[str], value=0) -> pd.DataFrame: + """ + Generate a default CPT. + :param variables: Column names + :param value: Which the default p-value should be + :return: A CPT + """ + truth_table = product([True, False], repeat=len(variables)) + factor = pd.DataFrame(truth_table, columns=variables) + factor['p'] = value + return factor + + def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + """ + Sum out some variable(s) in subset from a factor. + :param factor: factor over variables X + :param subset: a subset of variables X + :return: a factor corresponding to the factor with the subset summed out + """ + if isinstance(factor, str): + factor = self.bn.get_cpt(factor) + if isinstance(subset, str): + subset = [subset] + + new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() + new_factor['p'] = 0 + subset_factor = self.init_factor(subset) + + for i, y in new_factor.iterrows(): + for _, z in subset_factor.iterrows(): + new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( + y[:-1].append(z[:-1]), factor)['p'].sum() + # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + return new_factor.reset_index(drop=True) def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: """ @@ -154,40 +202,302 @@ def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list return res_factor.reset_index(drop=True) - def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: + def factor_multiplication(self,f,g): + ''' + Given two factors f and g, compute the multiplied factor h=fg + :param f: Factor f + :param g: Factor g + :returns: Multiplied factor h=f*g + ''' + + # check what the overlapping var(s) is + vars_f = [x for x in f.columns] + vars_g = [x for x in g.columns] + + for var in vars_f: + if var in vars_g and var != 'p': + join_var = var + + # merge two dataframes + merged = f.merge(g,left_on=join_var,right_on=join_var) + + # multiply probabilities + merged['p'] = merged['p_x']*merged['p_y'] + + # drop individual probability columns + h = merged.drop(['p_x','p_y'],axis=1) + + # return h + return h + + def factor_multiplication(self, factors: List[Union[str, pd.DataFrame]]) -> pd.DataFrame: """ - Generate a default CPT. - :param variables: Column names - :param value: Which the default p-value should be - :return: A CPT + Multiply multiple factors with each other. + :param factors: a list of factors + :return: a factor corresponding to the product of all given factors """ - print(variables) - truth_table = product([True, False], repeat=len(variables)) - factor = pd.DataFrame(truth_table, columns=variables) - factor['p'] = value - return factor + # If there are strings in the input-list of factors, replace them with the corresponding cpt + for x, y in enumerate(factors): + if isinstance(y, str): + factors[x] = self.bn.get_cpt(y) - def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + new_factor = factors[0].drop('p', axis=1) + for i, factor in enumerate(factors[1:]): + try: + new_factor = new_factor.merge(factor.drop('p', axis=1), how='outer') + except pd.errors.MergeError: + new_factor = new_factor.join(factor.drop('p', axis=1), how='outer') + new_factor['p'] = 1 + + for i, z in new_factor.iterrows(): + for _, f in enumerate(factors): + new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] * self.bn.get_compatible_instantiations_table( + z[:-1], f)['p'].sum() + # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + # Reordering new_factor, putting the extensions to the back + cols = new_factor.columns + ext = [c for c in cols if c[:3] == 'ext'] + if len(ext) > 0: + rest = list(np.setdiff1d(cols, ext)) + new_factor = new_factor[rest + ext] + + return new_factor.reset_index(drop=True) + + + def MPE(self, evidence: pd.Series, order_func: str = None) -> pd.DataFrame: """ - Sum out some variable(s) in subset from a factor. - :param factor: factor over variables X - :param subset: a subset of variables X - :return: a factor corresponding to the factor with the subset summed out + Compute the MPE instantiation for some given evidence. + :param evidence: + :param order_func: String describing which order function to use + :return: Dataframe describing the MPE instantiation """ + N = deepcopy(self.bn) + # Prune Edges + for var in evidence.keys(): + for child in N.get_children(var): + N.del_edge((var, child)) + + new = N.get_compatible_instantiations_table(evidence, N.get_cpt(child)).reset_index(drop=True) + new = new.drop([var], axis=1) + N.update_cpt(child, new) + u = N.get_compatible_instantiations_table(evidence, N.get_cpt(var)).reset_index(drop=True) + N.update_cpt(var, u) + + if order_func is None or order_func == "random": + order = self.random_order(N) + elif order_func == "min_degree": + order = self.min_degree(N) + elif order_func == "min_fill": + order = self.min_fill(N) + else: + raise Exception("Wrong order argument") + + S = N.get_all_cpts() + for var_pi in order: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.multiply_factors(func_k) if len(func_k) > 1 else func_k[0] + new_factor = self.maximise_out(new_factor, var_pi) + + # And replace them with the new factor + S[var_pi] = new_factor + + res_factor = self.multiply_factors(list(S.values())) if len(S) > 1 else S.popitem()[1] + return res_factor + + def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.DataFrame: + """ + Compute the MAP instantiation for some variables and some given evidence. + :param M: The MAP variables + :param evidence: + :param order_func: String describing which order function to use + :return: Dataframe describing the MAP instantiation + """ + if len(np.intersect1d(list(evidence.keys()), M)) > 0: + raise Exception("Evidence cannot intersect with M") + + N = deepcopy(self.bn) + N = self.pruning(M, evidence) + for e in evidence.items(): + N.update_cpt(e[0], self.bn.get_compatible_instantiations_table(evidence, + N.get_cpt(e[0])).reset_index(drop=True)) + + if order_func is None or order_func == "random": + order = self.random_order(N) + elif order_func == "min_degree": + order = self.min_degree(N) + elif order_func == "min_fill": + order = self.min_fill(N) + else: + raise Exception("Wrong order argument") + + S = N.get_all_cpts() + for var_pi in order: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.factor_multiplication(func_k) if len(func_k) > 1 else func_k[0] + if var_pi in M: + new_factor = self.maximise_out(new_factor, var_pi) + else: + new_factor = self.sum_out_factors(new_factor, var_pi) + # And replace them with the new factor + # print(new_factor) + S[var_pi] = new_factor + + + res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] + return res_factor + + # def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + # """ + # :param factor: + # :param subset: + # :return: + # """ + # if isinstance(factor, str): + # factor = self.bn.get_cpt(factor) + # if isinstance(subset, str): + # subset = [subset] + + # # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get + # # each possible instantiation. + # ext = [c for c in factor.columns if c[:3] == 'ext'] + # instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() + # res_factor = pd.DataFrame(columns=factor.columns) + + # if len(instantiations.columns) == 0: + # try: + # res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) + # except IndexError: + # print('w') + # else: + # for _, instantiation in instantiations.iterrows(): + # cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) + # res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) + + # # For each maximized-out variable(s), rename them to ext(variable) + # for v in subset: + # x = res_factor.pop(v) + # res_factor[f'ext({v})'] = x + + # return res_factor.reset_index(drop=True) + + # def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: + # """ + # Generate a default CPT. + # :param variables: Column names + # :param value: Which the default p-value should be + # :return: A CPT + # """ + # print(variables) + # truth_table = product([True, False], repeat=len(variables)) + # factor = pd.DataFrame(truth_table, columns=variables) + # factor['p'] = value + # return factor + + # def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + # """ + # Sum out some variable(s) in subset from a factor. + # :param factor: factor over variables X + # :param subset: a subset of variables X + # :return: a factor corresponding to the factor with the subset summed out + # """ - if isinstance(factor, str): - factor = self.bn.get_cpt(factor) - if isinstance(subset, str): - subset = [subset] + # if isinstance(factor, str): + # factor = self.bn.get_cpt(factor) + # if isinstance(subset, str): + # subset = [subset] - new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() - new_factor['p'] = 0 - subset_factor = self.init_factor(subset) + # new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() + # new_factor['p'] = 0 + # subset_factor = self.init_factor(subset) - for i, y in new_factor.iterrows(): - for _, z in subset_factor.iterrows(): - new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( - y[:-1].append(z[:-1]), factor)['p'].sum() - # sum() instead of float() here, since the compatible table can be empty at times, this works around it + # for i, y in new_factor.iterrows(): + # for _, z in subset_factor.iterrows(): + # new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( + # y[:-1].append(z[:-1]), factor)['p'].sum() + # # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + # return new_factor.reset_index(drop=True) + + def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: + """ Sum out a set of variables by using variable elimination + + Args: + data (pd.Dataframe): Dataframe of where elimination should take place + var (List): Variable to be summed out + + Returns: + pd.Dataframe: Dataframe after elimination + """ + print(data, "initial dataframe") + remaining = data.drop(columns=var) # Drop column thats need to be summed out + rem_list = list(remaining.columns.values)[:-1] # Get remaining dataframe + if len(rem_list) == 0: # If empty return empty frame + print("This was the only variable, thus no data could be returned") + return pd.DataFrame() + eliminated = remaining.groupby( # Else sum of matching values of variables + rem_list).aggregate({'p': 'sum'}) + eliminated.reset_index(inplace=True) + return eliminated + + def loop_over_children(self,bn, y, parent): + '''Checks for if y is a descendant of parent''' + + # print("parent: ", parent) + children = BayesNet.get_children(bn, parent) + # print("children: ", children) + if len(children) == 0: + return True + else: + for child in children: + if child == y: + return False + else: + if not self.loop_over_children(bn, y, child): + return False + return True + + def independence(self, bn, X, Y, Z): + ''' + Implementation of Markov Property and Symmetry in DAGS to determine independence + :param bn: Bayesian Network + :param X, Y, Z: sets of variable of which to decide whether X is independent of Y given Z + :returns: Bool, True if X and Y are independent given Z, False if X and Y are not independent given Z + ''' + Not_all_parents_of_X = False + for x in X: + for parent in BayesNet.get_all_variables(bn): + if x in BayesNet.get_children(bn, parent): + if parent not in Z: + Not_all_parents_of_X = True + break + if Not_all_parents_of_X: + break + + if Not_all_parents_of_X: + for y in Y: + for parent in BayesNet.get_all_variables(bn): + if y in BayesNet.get_children(bn, parent): + print(parent) + if parent not in Z: + return False + for y in Y: + # print(y) + for x in X: + # print(self.loop_over_children(bn, x, y)) + if not self.loop_over_children(bn, x, y): + # print(x, "is not a descendent of ", y) + return False + return True + + for x in X: + for y in Y: + if not self.loop_over_children(bn, y, x): + return False + + return True - return new_factor.reset_index(drop=True) \ No newline at end of file diff --git a/test.py b/test.py index e7dc69cd..86671ca8 100644 --- a/test.py +++ b/test.py @@ -1,21 +1,26 @@ from BNReasoner import BNReasoner from BayesNet import BayesNet +import pandas as pd if __name__ == "__main__": print("begin") + net = 'testing/lecture_example.BIFXML' + + #net = 'testing/lecture_example.BIFXML' + bn = BayesNet() bn.load_from_bifxml(net) # bn.draw_structure() bnr = BNReasoner(bn) - #outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) + ### Test pruning + #outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) ### D-seperation #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated #outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated - ### Order min-degree #outcome_min_degree = bnr.min_degree() #print(outcome_min_degree) @@ -24,12 +29,45 @@ # outcome_min_fill = bnr.min_fill() # print(outcome_min_fill) - #outcome.draw_structure() - X = "Wet Grass?" - Y = BayesNet.get_cpt(bnr.bn,X) - # f = bnr.multip_factors(Y) - print(Y) - outcome = bnr.sum_out_factors(Y,X) #bnr.maximise_out(Y,X) - print(outcome) - #python3 test.py + ### Factor Multiplication + # net = 'testing/lecture_example.BIFXML' + # outcome_factor = bnr.factor_multiplication(['Rain?', 'Wet Grass?']) + # print(outcome_factor) + + ### MPE + # net = 'testing/lecture_example2.BIFXML' + # mpe = bnr.MPE(pd.Series({'J': True, 'O': False})) + # print(mpe) + + + ### MAP + # map = bnr.MAP(['I', 'J'], pd.Series({'O': True})) + # print(map) + + + + # outcome.draw_structure() + + # X = "Wet Grass?" + # Y = BayesNet.get_cpt(bnr.bn,X) + # # f = bnr.multip_factors(Y) + # print(Y) + # outcome = bnr.sum_out_factors(Y,X) #bnr.maximise_out(Y,X) + # print(outcome) + + ### Elimination + # outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) + #outcome_elim = bnr.elimination(bn.get_cpt('Winter?'), ['Winter?']) # Empty Dataframe + # print(outcome_elim) + + ### Independence + Y = {"Winter?"} + X = {"Slippery Road?"} + Z = {} + if bnr.independence(bnr.bn, X,Y,Z): + print(X, "is independent from ", Y, "given ", Z) + else: + print(X, "is not independent from ", Y, "given ", Z) + + #python3 test.py \ No newline at end of file From fba3bfc67fa340f32f7af8c6bcb7dfd28fe2c508 Mon Sep 17 00:00:00 2001 From: Jpayanshi <113305815+Jpayanshi@users.noreply.github.com> Date: Fri, 16 Dec 2022 17:17:51 +0100 Subject: [PATCH 12/16] Final code --- .gitignore | 408 +++++++++---------- BNReasoner.py | 997 +++++++++++++++++++++++------------------------ BayesNet.py | 456 +++++++++++----------- MAP.jpg | Bin 0 -> 128843 bytes MPE.jpg | Bin 0 -> 120162 bytes Part2.py | 64 +++ README.md | 203 +++++----- generate_bn.py | 29 ++ requirements.txt | 6 +- test.py | 302 ++++++++++---- use_case.py | 65 +++ 11 files changed, 1429 insertions(+), 1101 deletions(-) create mode 100644 MAP.jpg create mode 100644 MPE.jpg create mode 100644 Part2.py create mode 100644 generate_bn.py create mode 100644 use_case.py diff --git a/.gitignore b/.gitignore index 13c103cd..4b8698de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,204 +1,204 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# AWS User-specific -.idea/**/aws.xml - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/artifacts -# .idea/compiler.xml -# .idea/jarRepositories.xml -# .idea/modules.xml -# .idea/*.iml -# .idea/modules -# *.iml -# *.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser diff --git a/BNReasoner.py b/BNReasoner.py index 1a61f60e..997060b7 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -1,503 +1,494 @@ -from typing import Union, Dict, List -from xmlrpc.client import Boolean -from BayesNet import BayesNet -from copy import deepcopy - -import numpy as np -import pandas as pd -from typing import Dict, List, Optional, Tuple, Union - -from itertools import product, combinations - -class BNReasoner: - def __init__(self, net: Union[str, BayesNet]): - """ - :param net: either file path of the bayesian network in BIFXML format or BayesNet object - """ - if type(net) == str: - # constructs a BN object - self.bn = BayesNet() - # Loads the BN from an BIFXML file - self.bn.load_from_bifxml(net) - else: - self.bn = net - - # TODO: This is where your methods should go - def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: - """ Prune the network, will drop variables that are not needed anymore - - Args: - query (List): Given query, used to check if nodes are part of it - values (Dict): The given evedince to a node, must be True or False. Structure: {Node:Value} - - Returns: - p: BayesNet.object, returns the new pruned network - """ - print("pruning") - p = deepcopy(self.bn) - finished = True # Continue checking if the pruning can continue - all_cpts = p.get_all_cpts() # A dictionary of all cps in the network indexed by the variable they belong to - while finished: # Stop pruning when the network cannot be pruned further - finished = False - for var in p.get_all_variables(): - if p.get_children(var) == [] and var not in query and var not in values: # Check if node is part of query - p.del_var(var) # Delete node if not part of query - finished = True - for a, b in values.items(): # Get node name and value - for variable in p.get_all_variables(): # Get all variables - cpt = all_cpts[variable] - if a in cpt.columns: # If variable from input matches a variable from a cpt column: - new_cpt = cpt.drop(cpt[cpt[a] != b].index) # If the same node exist with the opposite value, delete it - p.update_cpt(variable, new_cpt) # Update the cpt table without the opposite value - else: - continue - for child in p.get_children(a): # Check if the removed node has children, if yes delete edge - p.del_edge((a, child)) # Delete edge if input variable has child - finished = True - # print(p.get_all_cpts()," dit is p") - return p - - def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: - """ Check if variable x is d-seperated from y given z - - Args: - x (List): List of variables to check - y (list): List of variables to check if x is seperated from - z (list): List of given variables - - Returns: - bool: True is d-seperated, False if not - """ - p = deepcopy(self.bn) - reach_single = [] - iterated = [] - - for var in p.get_all_variables(): - if p.get_children(var) == [] and var not in x and var not in y and var not in z: - p.del_var(var) - for var in z: - for child in p.get_children(var): - p.del_edge([var, child]) - for var in x: - iterated.append(var) # Append variables to check - reach_single.extend(p.get_children(var)) # Append children - while list(set(reach_single) - set(iterated)) !=[]: # While loop makes sure children of children are checked - for a in list(set(reach_single) - set(iterated)): # Make sure all children are checked - reach_single.extend(p.get_children(a)) # Append children of children if there are any - iterated.append(a) # Append variable to prevent loop from checking again - for var_2 in y: - if var_2 in reach_single: # If y in x, not d-seperated - print(x, 'and', y, 'are not d-separated by', z) - return False - print(x, 'and', y, 'are d-separated by', z) # Else d-seperated - return True - - def random_order(self, network: BayesNet = None) -> List[str]: - """ - :return: a random ordering of all variables in self.bn - """ - if network is None: - return list(np.random.permutation(self.bn.get_all_variables())) - else: - return list(np.random.permutation(network.get_all_variables())) - - def min_degree(self) -> List[str]: - """Sort the nodes by looking at the degree - - Returns: - List of variables sorted from small to big (degree in the interaction graph to the ordering) - """ - p = deepcopy(self.bn) - return [x[0] for x in sorted(p.get_interaction_graph().degree(), key = lambda x: x[1])] # Sort list and only return the variable name - - def min_fill(self) -> List[str]: - """ Minimum fill ordering - - Returns: - List of variables sorted from small to big (whose deletion would add the fewest new interaction to the ordering) - """ - p = deepcopy(self.bn) - i_graph = p.get_interaction_graph() - order_edges = [] - for node in i_graph: - i = 0 - neighbors = i_graph.neighbors(node) - for a in neighbors: - neigh_a = i_graph.neighbors(a) - for b in neighbors: - if a == b: # Do nothing - continue - if b not in neigh_a: # Count if b is not in neigh_a - i += 1 - order_edges.append((node, i)) - return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name - - def init_factor(self,variables: List[str], value=0) -> pd.DataFrame: - """ - Generate a default CPT. - :param variables: Column names - :param value: Which the default p-value should be - :return: A CPT - """ - truth_table = product([True, False], repeat=len(variables)) - factor = pd.DataFrame(truth_table, columns=variables) - factor['p'] = value - return factor - - def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - """ - Sum out some variable(s) in subset from a factor. - :param factor: factor over variables X - :param subset: a subset of variables X - :return: a factor corresponding to the factor with the subset summed out - """ - if isinstance(factor, str): - factor = self.bn.get_cpt(factor) - if isinstance(subset, str): - subset = [subset] - - new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() - new_factor['p'] = 0 - subset_factor = self.init_factor(subset) - - for i, y in new_factor.iterrows(): - for _, z in subset_factor.iterrows(): - new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( - y[:-1].append(z[:-1]), factor)['p'].sum() - # sum() instead of float() here, since the compatible table can be empty at times, this works around it - - return new_factor.reset_index(drop=True) - - def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - """ - :param factor: - :param subset: - :return: - """ - if isinstance(factor, str): - factor = self.bn.get_cpt(factor) - if isinstance(subset, str): - subset = [subset] - - # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get - # each possible instantiation. - ext = [c for c in factor.columns if c[:3] == 'ext'] - instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() - res_factor = pd.DataFrame(columns=factor.columns) - - if len(instantiations.columns) == 0: - try: - res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) - except IndexError: - print('w') - else: - for _, instantiation in instantiations.iterrows(): - cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) - res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) - - # For each maximized-out variable(s), rename them to ext(variable) - for v in subset: - x = res_factor.pop(v) - res_factor[f'ext({v})'] = x - - return res_factor.reset_index(drop=True) - - def factor_multiplication(self,f,g): - ''' - Given two factors f and g, compute the multiplied factor h=fg - :param f: Factor f - :param g: Factor g - :returns: Multiplied factor h=f*g - ''' - - # check what the overlapping var(s) is - vars_f = [x for x in f.columns] - vars_g = [x for x in g.columns] - - for var in vars_f: - if var in vars_g and var != 'p': - join_var = var - - # merge two dataframes - merged = f.merge(g,left_on=join_var,right_on=join_var) - - # multiply probabilities - merged['p'] = merged['p_x']*merged['p_y'] - - # drop individual probability columns - h = merged.drop(['p_x','p_y'],axis=1) - - # return h - return h - - def factor_multiplication(self, factors: List[Union[str, pd.DataFrame]]) -> pd.DataFrame: - """ - Multiply multiple factors with each other. - :param factors: a list of factors - :return: a factor corresponding to the product of all given factors - """ - # If there are strings in the input-list of factors, replace them with the corresponding cpt - for x, y in enumerate(factors): - if isinstance(y, str): - factors[x] = self.bn.get_cpt(y) - - new_factor = factors[0].drop('p', axis=1) - for i, factor in enumerate(factors[1:]): - try: - new_factor = new_factor.merge(factor.drop('p', axis=1), how='outer') - except pd.errors.MergeError: - new_factor = new_factor.join(factor.drop('p', axis=1), how='outer') - new_factor['p'] = 1 - - for i, z in new_factor.iterrows(): - for _, f in enumerate(factors): - new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] * self.bn.get_compatible_instantiations_table( - z[:-1], f)['p'].sum() - # sum() instead of float() here, since the compatible table can be empty at times, this works around it - - # Reordering new_factor, putting the extensions to the back - cols = new_factor.columns - ext = [c for c in cols if c[:3] == 'ext'] - if len(ext) > 0: - rest = list(np.setdiff1d(cols, ext)) - new_factor = new_factor[rest + ext] - - return new_factor.reset_index(drop=True) - - - def MPE(self, evidence: pd.Series, order_func: str = None) -> pd.DataFrame: - """ - Compute the MPE instantiation for some given evidence. - :param evidence: - :param order_func: String describing which order function to use - :return: Dataframe describing the MPE instantiation - """ - N = deepcopy(self.bn) - # Prune Edges - for var in evidence.keys(): - for child in N.get_children(var): - N.del_edge((var, child)) - - new = N.get_compatible_instantiations_table(evidence, N.get_cpt(child)).reset_index(drop=True) - new = new.drop([var], axis=1) - N.update_cpt(child, new) - u = N.get_compatible_instantiations_table(evidence, N.get_cpt(var)).reset_index(drop=True) - N.update_cpt(var, u) - - if order_func is None or order_func == "random": - order = self.random_order(N) - elif order_func == "min_degree": - order = self.min_degree(N) - elif order_func == "min_fill": - order = self.min_fill(N) - else: - raise Exception("Wrong order argument") - - S = N.get_all_cpts() - for var_pi in order: - # Pop all functions from S, which mention var_pi... - func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] - - new_factor = self.multiply_factors(func_k) if len(func_k) > 1 else func_k[0] - new_factor = self.maximise_out(new_factor, var_pi) - - # And replace them with the new factor - S[var_pi] = new_factor - - res_factor = self.multiply_factors(list(S.values())) if len(S) > 1 else S.popitem()[1] - return res_factor - - def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.DataFrame: - """ - Compute the MAP instantiation for some variables and some given evidence. - :param M: The MAP variables - :param evidence: - :param order_func: String describing which order function to use - :return: Dataframe describing the MAP instantiation - """ - if len(np.intersect1d(list(evidence.keys()), M)) > 0: - raise Exception("Evidence cannot intersect with M") - - N = deepcopy(self.bn) - N = self.pruning(M, evidence) - for e in evidence.items(): - N.update_cpt(e[0], self.bn.get_compatible_instantiations_table(evidence, - N.get_cpt(e[0])).reset_index(drop=True)) - - if order_func is None or order_func == "random": - order = self.random_order(N) - elif order_func == "min_degree": - order = self.min_degree(N) - elif order_func == "min_fill": - order = self.min_fill(N) - else: - raise Exception("Wrong order argument") - - S = N.get_all_cpts() - for var_pi in order: - # Pop all functions from S, which mention var_pi... - func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] - - new_factor = self.factor_multiplication(func_k) if len(func_k) > 1 else func_k[0] - if var_pi in M: - new_factor = self.maximise_out(new_factor, var_pi) - else: - new_factor = self.sum_out_factors(new_factor, var_pi) - # And replace them with the new factor - # print(new_factor) - S[var_pi] = new_factor - - - res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] - return res_factor - - # def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - # """ - # :param factor: - # :param subset: - # :return: - # """ - # if isinstance(factor, str): - # factor = self.bn.get_cpt(factor) - # if isinstance(subset, str): - # subset = [subset] - - # # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get - # # each possible instantiation. - # ext = [c for c in factor.columns if c[:3] == 'ext'] - # instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() - # res_factor = pd.DataFrame(columns=factor.columns) - - # if len(instantiations.columns) == 0: - # try: - # res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) - # except IndexError: - # print('w') - # else: - # for _, instantiation in instantiations.iterrows(): - # cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) - # res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) - - # # For each maximized-out variable(s), rename them to ext(variable) - # for v in subset: - # x = res_factor.pop(v) - # res_factor[f'ext({v})'] = x - - # return res_factor.reset_index(drop=True) - - # def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: - # """ - # Generate a default CPT. - # :param variables: Column names - # :param value: Which the default p-value should be - # :return: A CPT - # """ - # print(variables) - # truth_table = product([True, False], repeat=len(variables)) - # factor = pd.DataFrame(truth_table, columns=variables) - # factor['p'] = value - # return factor - - # def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - # """ - # Sum out some variable(s) in subset from a factor. - # :param factor: factor over variables X - # :param subset: a subset of variables X - # :return: a factor corresponding to the factor with the subset summed out - # """ - - # if isinstance(factor, str): - # factor = self.bn.get_cpt(factor) - # if isinstance(subset, str): - # subset = [subset] - - # new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() - # new_factor['p'] = 0 - # subset_factor = self.init_factor(subset) - - # for i, y in new_factor.iterrows(): - # for _, z in subset_factor.iterrows(): - # new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( - # y[:-1].append(z[:-1]), factor)['p'].sum() - # # sum() instead of float() here, since the compatible table can be empty at times, this works around it - - # return new_factor.reset_index(drop=True) - - def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: - """ Sum out a set of variables by using variable elimination - - Args: - data (pd.Dataframe): Dataframe of where elimination should take place - var (List): Variable to be summed out - - Returns: - pd.Dataframe: Dataframe after elimination - """ - print(data, "initial dataframe") - remaining = data.drop(columns=var) # Drop column thats need to be summed out - rem_list = list(remaining.columns.values)[:-1] # Get remaining dataframe - if len(rem_list) == 0: # If empty return empty frame - print("This was the only variable, thus no data could be returned") - return pd.DataFrame() - eliminated = remaining.groupby( # Else sum of matching values of variables - rem_list).aggregate({'p': 'sum'}) - eliminated.reset_index(inplace=True) - return eliminated - - def loop_over_children(self,bn, y, parent): - '''Checks for if y is a descendant of parent''' - - # print("parent: ", parent) - children = BayesNet.get_children(bn, parent) - # print("children: ", children) - if len(children) == 0: - return True - else: - for child in children: - if child == y: - return False - else: - if not self.loop_over_children(bn, y, child): - return False - return True - - def independence(self, bn, X, Y, Z): - ''' - Implementation of Markov Property and Symmetry in DAGS to determine independence - :param bn: Bayesian Network - :param X, Y, Z: sets of variable of which to decide whether X is independent of Y given Z - :returns: Bool, True if X and Y are independent given Z, False if X and Y are not independent given Z - ''' - Not_all_parents_of_X = False - for x in X: - for parent in BayesNet.get_all_variables(bn): - if x in BayesNet.get_children(bn, parent): - if parent not in Z: - Not_all_parents_of_X = True - break - if Not_all_parents_of_X: - break - - if Not_all_parents_of_X: - for y in Y: - for parent in BayesNet.get_all_variables(bn): - if y in BayesNet.get_children(bn, parent): - print(parent) - if parent not in Z: - return False - for y in Y: - # print(y) - for x in X: - # print(self.loop_over_children(bn, x, y)) - if not self.loop_over_children(bn, x, y): - # print(x, "is not a descendent of ", y) - return False - return True - - for x in X: - for y in Y: - if not self.loop_over_children(bn, y, x): - return False - - return True - +from typing import Union, Dict, List +from xmlrpc.client import Boolean +from BayesNet import BayesNet +from copy import deepcopy + +import numpy as np +import pandas as pd +from typing import Dict, List, Optional, Tuple, Union + +from itertools import product, combinations + +class BNReasoner: + def __init__(self, net: Union[str, BayesNet]): + if type(net) == str: + # constructs a BN object + self.bn = BayesNet() + # Loads the BN from an BIFXML file + self.bn.load_from_bifxml(net) + else: + self.bn = net + + # TODO: This is where your methods should go + def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: + + bayes_net = deepcopy(self.bn) + finished = True # Continue checking if the pruning can continue + all_cpts = bayes_net.get_all_cpts() # A dictionary of all cps in the network indexed by the variable they belong to + while finished: # Stop pruning when the network cannot be pruned further + finished = False + for var in bayes_net.get_all_variables(): + if bayes_net.get_children(var) == [] and var not in query and var not in values: # Check if node is part of query + bayes_net.del_var(var) # Delete node if not part of query + finished = True + for a, b in values.items(): # Get node name and value + for variable in bayes_net.get_all_variables(): # Get all variables + cpt = all_cpts[variable] + if a in cpt.columns: # If variable from input matches a variable from a cpt column: + new_cpt = cpt.drop(cpt[cpt[a] != b].index) # If the same node exist with the opposite value, delete it + bayes_net.update_cpt(variable, new_cpt) # Update the cpt table without the opposite value + else: + continue + for child in bayes_net.get_children(a): # Check if the removed node has children, if yes delete edge + bayes_net.del_edge((a, child)) # Delete edge if input variable has child + finished = True +<<<<<<< Updated upstream + # print(p.get_all_cpts()," dit is p") + return p +======= + print(bayes_net.get_all_cpts()," dit is p") + return bayes_net +>>>>>>> Stashed changes + + def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: + bayes_net = deepcopy(self.bn) + reach_single = [] + iterated = [] + + for var in bayes_net.get_all_variables(): + if bayes_net.get_children(var) == [] and var not in x and var not in y and var not in z: + bayes_net.del_var(var) + for var in z: + for child in bayes_net.get_children(var): + bayes_net.del_edge([var, child]) + for var in x: + iterated.append(var) # Append variables to check + reach_single.extend(bayes_net.get_children(var)) # Append children + while list(set(reach_single) - set(iterated)) !=[]: # While loop makes sure children of children are checked + for a in list(set(reach_single) - set(iterated)): # Make sure all children are checked + reach_single.extend(bayes_net.get_children(a)) # Append children of children if there are any + iterated.append(a) # Append variable to prevent loop from checking again + for var_2 in y: + if var_2 in reach_single: # If y in x, not d-seperated + print(x, 'and', y, 'are not d-separated by', z) + return False + print(x, 'and', y, 'are d-separated by', z) # Else d-seperated + return True + + def random_order(self, network: BayesNet = None) -> List[str]: + if network is None: + return list(np.random.permutation(self.bn.get_all_variables())) + else: + return list(np.random.permutation(network.get_all_variables())) + + def min_degree(self, network: BayesNet = None) -> List[str]: + if network is None: + bayes_net = deepcopy(self.bn) + else: + bayes_net = deepcopy(network) + + return [x[0] for x in sorted(bayes_net.get_interaction_graph().degree(), key = lambda x: x[1])] # Sort list and only return the variable name + + def min_fill(self, network: BayesNet = None) -> List[str]: + if network is None: + bayes_net = deepcopy(self.bn) + else: + bayes_net = deepcopy(network) + + i_graph = bayes_net.get_interaction_graph() + order_edges = [] + for node in i_graph: + i = 0 + neighbors = i_graph.neighbors(node) + for a in neighbors: + neigh_a = i_graph.neighbors(a) + for b in neighbors: + if a == b: # Do nothing + continue + if b not in neigh_a: # Count if b is not in neigh_a + i += 1 + order_edges.append((node, i)) + return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name + +<<<<<<< Updated upstream + def init_factor(self,variables: List[str], value=0) -> pd.DataFrame: + """ + Generate a default CPT. + :param variables: Column names + :param value: Which the default p-value should be + :return: A CPT + """ +======= + def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: +>>>>>>> Stashed changes + truth_table = product([True, False], repeat=len(variables)) + factor = pd.DataFrame(truth_table, columns=variables) + factor['p'] = value + return factor + + def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + if isinstance(factor, str): + factor = self.bn.get_cpt(factor) + if isinstance(subset, str): + subset = [subset] + + new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() + new_factor['p'] = 0 + subset_factor = self.init_factor(subset) + + for i, y in new_factor.iterrows(): + for _, z in subset_factor.iterrows(): + new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( + y[:-1].append(z[:-1]), factor)['p'].sum() + # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + return new_factor.reset_index(drop=True) + + def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + if isinstance(factor, str): + factor = self.bn.get_cpt(factor) + if isinstance(subset, str): + subset = [subset] + + # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get + # each possible instantiation. + ext = [c for c in factor.columns if c[:3] == 'ext'] + instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() + res_factor = pd.DataFrame(columns=factor.columns) + + if len(instantiations.columns) == 0: + try: + res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) + except IndexError: + print('w') + else: + for _, instantiation in instantiations.iterrows(): + cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) + res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) + + # For each maximized-out variable(s), rename them to ext(variable) + for v in subset: + x = res_factor.pop(v) + res_factor[f'ext({v})'] = x + + return res_factor.reset_index(drop=True) + + def factor_multiplication(self,f,g): + ''' + Given two factors f and g, compute the multiplied factor h=fg + :param f: Factor f + :param g: Factor g + :returns: Multiplied factor h=f*g + ''' + + # check what the overlapping var(s) is + vars_f = [x for x in f.columns] + vars_g = [x for x in g.columns] + + for var in vars_f: + if var in vars_g and var != 'p': + join_var = var + + # merge two dataframes + merged = f.merge(g,left_on=join_var,right_on=join_var) + + # multiply probabilities + merged['p'] = merged['p_x']*merged['p_y'] + + # drop individual probability columns + h = merged.drop(['p_x','p_y'],axis=1) + + # return h + return h + + def factor_multiplication(self, factors: List[Union[str, pd.DataFrame]]) -> pd.DataFrame: + # If there are strings in the input-list of factors, replace them with the corresponding cpt + for x, y in enumerate(factors): + if isinstance(y, str): + factors[x] = self.bn.get_cpt(y) + + new_factor = factors[0].drop('p', axis=1) + for i, factor in enumerate(factors[1:]): + try: + new_factor = new_factor.merge(factor.drop('p', axis=1), how='outer') + except pd.errors.MergeError: + new_factor = new_factor.join(factor.drop('p', axis=1), how='outer') + new_factor['p'] = 1 + + for i, z in new_factor.iterrows(): + for _, f in enumerate(factors): + new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] * self.bn.get_compatible_instantiations_table( + z[:-1], f)['p'].sum() + # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + # Reordering new_factor, putting the extensions to the back + cols = new_factor.columns + ext = [c for c in cols if c[:3] == 'ext'] + if len(ext) > 0: + rest = list(np.setdiff1d(cols, ext)) + new_factor = new_factor[rest + ext] + + return new_factor.reset_index(drop=True) + + + def MPE(self, evidence: pd.Series, order_func: str = None) -> pd.DataFrame: + N = deepcopy(self.bn) + # Prune Edges + for var in evidence.keys(): + for child in N.get_children(var): + N.del_edge((var, child)) + + new = N.get_compatible_instantiations_table(evidence, N.get_cpt(child)).reset_index(drop=True) + new = new.drop([var], axis=1) + N.update_cpt(child, new) + u = N.get_compatible_instantiations_table(evidence, N.get_cpt(var)).reset_index(drop=True) + N.update_cpt(var, u) + + if order_func is None or order_func == "random": + order = self.random_order(N) + elif order_func == "min_degree": + order = self.min_degree(N) + elif order_func == "min_fill": + order = self.min_fill(N) + else: + raise Exception("Wrong order argument") + + S = N.get_all_cpts() + for var_pi in order: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.multiply_factors(func_k) if len(func_k) > 1 else func_k[0] + new_factor = self.maximise_out(new_factor, var_pi) + + # And replace them with the new factor + S[var_pi] = new_factor + + res_factor = self.multiply_factors(list(S.values())) if len(S) > 1 else S.popitem()[1] + return res_factor + + def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.DataFrame: + if len(np.intersect1d(list(evidence.keys()), M)) > 0: + raise Exception("Evidence cannot intersect with M") + + N = deepcopy(self.bn) + N = self.pruning(M, evidence) + for e in evidence.items(): + N.update_cpt(e[0], self.bn.get_compatible_instantiations_table(evidence, + N.get_cpt(e[0])).reset_index(drop=True)) + + if order_func is None or order_func == "random": + order = self.random_order(N) + elif order_func == "min_degree": + order = self.min_degree(N) + elif order_func == "min_fill": + order = self.min_fill(N) + else: + raise Exception("Wrong order argument") + + S = N.get_all_cpts() + for var_pi in order: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.factor_multiplication(func_k) if len(func_k) > 1 else func_k[0] + if var_pi in M: + new_factor = self.maximise_out(new_factor, var_pi) + else: + new_factor = self.sum_out_factors(new_factor, var_pi) + # And replace them with the new factor + # print(new_factor) + S[var_pi] = new_factor + + + res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] + return res_factor + +<<<<<<< Updated upstream + # def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + # """ + # :param factor: + # :param subset: + # :return: + # """ + # if isinstance(factor, str): + # factor = self.bn.get_cpt(factor) + # if isinstance(subset, str): + # subset = [subset] + + # # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get + # # each possible instantiation. + # ext = [c for c in factor.columns if c[:3] == 'ext'] + # instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() + # res_factor = pd.DataFrame(columns=factor.columns) + + # if len(instantiations.columns) == 0: + # try: + # res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) + # except IndexError: + # print('w') + # else: + # for _, instantiation in instantiations.iterrows(): + # cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) + # res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) + + # # For each maximized-out variable(s), rename them to ext(variable) + # for v in subset: + # x = res_factor.pop(v) + # res_factor[f'ext({v})'] = x + + # return res_factor.reset_index(drop=True) + + # def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: + # """ + # Generate a default CPT. + # :param variables: Column names + # :param value: Which the default p-value should be + # :return: A CPT + # """ + # print(variables) + # truth_table = product([True, False], repeat=len(variables)) + # factor = pd.DataFrame(truth_table, columns=variables) + # factor['p'] = value + # return factor + + # def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + # """ + # Sum out some variable(s) in subset from a factor. + # :param factor: factor over variables X + # :param subset: a subset of variables X + # :return: a factor corresponding to the factor with the subset summed out + # """ + + # if isinstance(factor, str): + # factor = self.bn.get_cpt(factor) + # if isinstance(subset, str): + # subset = [subset] + + # new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() + # new_factor['p'] = 0 + # subset_factor = self.init_factor(subset) + + # for i, y in new_factor.iterrows(): + # for _, z in subset_factor.iterrows(): + # new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( + # y[:-1].append(z[:-1]), factor)['p'].sum() + # # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + # return new_factor.reset_index(drop=True) + + def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: + """ Sum out a set of variables by using variable elimination + + Args: + data (pd.Dataframe): Dataframe of where elimination should take place + var (List): Variable to be summed out + + Returns: + pd.Dataframe: Dataframe after elimination + """ +======= + def compute_marginal(self, query: List[str], evidence: pd.Series = None, order: List[str] = None) -> pd.DataFrame: + if order is None: + order = self.random_order() + + S = self.bn.get_all_cpts() + + if evidence is not None: # If there's evidence, reduce all CPTs using the evidence + for var in self.bn.get_all_variables(): + var_cpt = self.bn.get_cpt(var) + if any(evidence.keys().intersection(var_cpt.columns)): # If the evidence occurs in the cpt + new_cpt = self.bn.get_compatible_instantiations_table(evidence, var_cpt) + S[var] = new_cpt + + pi = [nv for nv in order if nv not in query] + for var_pi in pi: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.factor_multiplication(func_k) + new_factor = self.sum_out_factors(new_factor, var_pi) + # And replace them with the new factor + S[var_pi] = new_factor + + res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] + + if evidence is not None: # Normalizing over pr_evidence + cpt_e = self.compute_marginal(list(evidence.keys()), order=order) + pr_evidence = float(self.bn.get_compatible_instantiations_table(evidence, cpt_e)['p']) + res_factor['p'] = res_factor['p'] / pr_evidence + + return res_factor + + def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: +>>>>>>> Stashed changes + print(data, "initial dataframe") + remaining = data.drop(columns=var) # Drop column thats need to be summed out + rem_list = list(remaining.columns.values)[:-1] # Get remaining dataframe + if len(rem_list) == 0: # If empty return empty frame + print("This was the only variable, thus no data could be returned") + return pd.DataFrame() + eliminated = remaining.groupby( # Else sum of matching values of variables + rem_list).aggregate({'p': 'sum'}) + eliminated.reset_index(inplace=True) + return eliminated + + def loop_over_children(self,bn, y, parent): + # print("parent: ", parent) + children = BayesNet.get_children(bn, parent) + # print("children: ", children) + if len(children) == 0: + return True + else: + for child in children: + if child == y: + return False + else: + if not self.loop_over_children(bn, y, child): + return False + return True +<<<<<<< Updated upstream + + def independence(self, bn, X, Y, Z): + ''' + Implementation of Markov Property and Symmetry in DAGS to determine independence + :param bn: Bayesian Network + :param X, Y, Z: sets of variable of which to decide whether X is independent of Y given Z + :returns: Bool, True if X and Y are independent given Z, False if X and Y are not independent given Z + ''' +======= + + def check_independence(self, bn, X, Y, Z): +>>>>>>> Stashed changes + Not_all_parents_of_X = False + for x in X: + for parent in BayesNet.get_all_variables(bn): + if x in BayesNet.get_children(bn, parent): + if parent not in Z: + Not_all_parents_of_X = True + break + if Not_all_parents_of_X: + break + + if Not_all_parents_of_X: + for y in Y: + for parent in BayesNet.get_all_variables(bn): + if y in BayesNet.get_children(bn, parent): + if parent not in Z: + return False + for y in Y: + # print(y) + for x in X: + # print(self.loop_over_children(bn, x, y)) + if not self.loop_over_children(bn, x, y): + # print(x, "is not a descendent of ", y) + return False + return True + + for x in X: + for y in Y: + if not self.loop_over_children(bn, y, x): + return False + + return True + diff --git a/BayesNet.py b/BayesNet.py index 845d7e32..0f4023d8 100644 --- a/BayesNet.py +++ b/BayesNet.py @@ -1,228 +1,228 @@ -from typing import List, Tuple, Dict -import networkx as nx -import matplotlib.pyplot as plt -from pgmpy.readwrite import XMLBIFReader -import math -import itertools -import pandas as pd -from copy import deepcopy - - -class BayesNet: - - def __init__(self) -> None: - # initialize graph structure - self.structure = nx.DiGraph() - - # LOADING FUNCTIONS ------------------------------------------------------------------------------------------------ - def create_bn(self, variables: List[str], edges: List[Tuple[str, str]], cpts: Dict[str, pd.DataFrame]) -> None: - """ - Creates the BN according to the python objects passed in. - - :param variables: List of names of the variables. - :param edges: List of the directed edges. - :param cpts: Dictionary of conditional probability tables. - """ - # add nodes - [self.add_var(v, cpt=cpts[v]) for v in variables] - - # add edges - [self.add_edge(e) for e in edges] - - # check for cycles - if not nx.is_directed_acyclic_graph(self.structure): - raise Exception('The provided graph is not acyclic.') - - def load_from_bifxml(self, file_path: str) -> None: - """ - Load a BayesNet from a file in BIFXML file format. See description of BIFXML here: - http://www.cs.cmu.edu/afs/cs/user/fgcozman/www/Research/InterchangeFormat/ - - :param file_path: Path to the BIFXML file. - """ - # Read and parse the bifxml file - with open(file_path) as f: - bn_file = f.read() - bif_reader = XMLBIFReader(string=bn_file) - - # load cpts - cpts = {} - # iterating through vars - for key, values in bif_reader.get_values().items(): - values = values.transpose().flatten() - n_vars = int(math.log2(len(values))) - worlds = [list(i) for i in itertools.product([False, True], repeat=n_vars)] - # create empty array - cpt = [] - # iterating through worlds within a variable - for i in range(len(values)): - # add the probability to each possible world - worlds[i].append(values[i]) - cpt.append(worlds[i]) - - # determine column names - columns = bif_reader.get_parents()[key] - columns.reverse() - columns.append(key) - columns.append('p') - cpts[key] = pd.DataFrame(cpt, columns=columns) - - # load vars - variables = bif_reader.get_variables() - - # load edges - edges = bif_reader.get_edges() - - self.create_bn(variables, edges, cpts) - - # METHODS THAT MIGHT ME USEFUL ------------------------------------------------------------------------------------- - - def get_children(self, variable: str) -> List[str]: - """ - Returns the children of the variable in the graph. - :param variable: Variable to get the children from - :return: List of children - """ - return [c for c in self.structure.successors(variable)] - - def get_cpt(self, variable: str) -> pd.DataFrame: - """ - Returns the conditional probability table of a variable in the BN. - :param variable: Variable of which the CPT should be returned. - :return: Conditional probability table of 'variable' as a pandas DataFrame. - """ - try: - return self.structure.nodes[variable]['cpt'] - except KeyError: - raise Exception('Variable not in the BN') - - def get_all_variables(self) -> List[str]: - """ - Returns a list of all variables in the structure. - :return: list of all variables. - """ - return [n for n in self.structure.nodes] - - def get_all_cpts(self) -> Dict[str, pd.DataFrame]: - """ - Returns a dictionary of all cps in the network indexed by the variable they belong to. - :return: Dictionary of all CPTs - """ - cpts = {} - for var in self.get_all_variables(): - cpts[var] = self.get_cpt(var) - - return cpts - - def get_interaction_graph(self): - """ - Returns a networkx.Graph as interaction graph of the current BN. - :return: The interaction graph based on the factors of the current BN. - """ - # Create the graph and add all variables - int_graph = nx.Graph() - [int_graph.add_node(var) for var in self.get_all_variables()] - - # connect all variables with an edge which are mentioned in a CPT together - for var in self.get_all_variables(): - involved_vars = list(self.get_cpt(var).columns)[:-1] - for i in range(len(involved_vars)-1): - for j in range(i+1, len(involved_vars)): - if not int_graph.has_edge(involved_vars[i], involved_vars[j]): - int_graph.add_edge(involved_vars[i], involved_vars[j]) - return int_graph - - @staticmethod - def get_compatible_instantiations_table(instantiation: pd.Series, cpt: pd.DataFrame): - """ - Get all the entries of a CPT which are compatible with the instantiation. - - :param instantiation: a series of assignments as tuples. E.g.: pd.Series({"A": True, "B": False}) - :param cpt: cpt to be filtered - :return: table with compatible instantiations and their probability value - """ - var_names = instantiation.index.values - var_names = [v for v in var_names if v in cpt.columns] # get rid of excess variables names - compat_indices = cpt[var_names] == instantiation[var_names].values - compat_indices = [all(x[1]) for x in compat_indices.iterrows()] - compat_instances = cpt.loc[compat_indices] - return compat_instances - - def update_cpt(self, variable: str, cpt: pd.DataFrame) -> None: - """ - Replace the conditional probability table of a variable. - :param variable: Variable to be modified - :param cpt: new CPT - """ - self.structure.nodes[variable]["cpt"] = cpt - - @staticmethod - def reduce_factor(instantiation: pd.Series, cpt: pd.DataFrame) -> pd.DataFrame: - """ - Creates and returns a new factor in which all probabilities which are incompatible with the instantiation - passed to the method to 0. - - :param instantiation: a series of assignments as tuples. E.g.: pd.Series({"A": True, "B": False}) - :param cpt: cpt to be reduced - :return: cpt with their original probability value and zero probability for incompatible instantiations - """ - var_names = instantiation.index.values - var_names = [v for v in var_names if v in cpt.columns] # get rid of excess variables names - if len(var_names) > 0: # only reduce the factor if the evidence appears in it - new_cpt = deepcopy(cpt) - incompat_indices = cpt[var_names] != instantiation[var_names].values - incompat_indices = [any(x[1]) for x in incompat_indices.iterrows()] - new_cpt.loc[incompat_indices, 'p'] = 0.0 - return new_cpt - else: - return cpt - - def draw_structure(self) -> None: - """ - Visualize structure of the BN. - """ - nx.draw(self.structure, with_labels=True, node_size=3000) - plt.show() - - # BASIC HOUSEKEEPING METHODS --------------------------------------------------------------------------------------- - - def add_var(self, variable: str, cpt: pd.DataFrame) -> None: - """ - Add a variable to the BN. - :param variable: variable to be added. - :param cpt: conditional probability table of the variable. - """ - if variable in self.structure.nodes: - raise Exception('Variable already exists.') - else: - self.structure.add_node(variable, cpt=cpt) - - def add_edge(self, edge: Tuple[str, str]) -> None: - """ - Add a directed edge to the BN. - :param edge: Tuple of the directed edge to be added (e.g. ('A', 'B')). - :raises Exception: If added edge introduces a cycle in the structure. - """ - if edge in self.structure.edges: - raise Exception('Edge already exists.') - else: - self.structure.add_edge(edge[0], edge[1]) - - # check for cycles - if not nx.is_directed_acyclic_graph(self.structure): - self.structure.remove_edge(edge[0], edge[1]) - raise ValueError('Edge would make graph cyclic.') - - def del_var(self, variable: str) -> None: - """ - Delete a variable from the BN. - :param variable: Variable to be deleted. - """ - self.structure.remove_node(variable) - - def del_edge(self, edge: Tuple[str, str]) -> None: - """ - Delete an edge form the structure of the BN. - :param edge: Edge to be deleted (e.g. ('A', 'B')). - """ - self.structure.remove_edge(edge[0], edge[1]) +from typing import List, Tuple, Dict +import networkx as nx +import matplotlib.pyplot as plt +from pgmpy.readwrite import XMLBIFReader +import math +import itertools +import pandas as pd +from copy import deepcopy + + +class BayesNet: + + def __init__(self) -> None: + # initialize graph structure + self.structure = nx.DiGraph() + + # LOADING FUNCTIONS ------------------------------------------------------------------------------------------------ + def create_bn(self, variables: List[str], edges: List[Tuple[str, str]], cpts: Dict[str, pd.DataFrame]) -> None: + """ + Creates the BN according to the python objects passed in. + + :param variables: List of names of the variables. + :param edges: List of the directed edges. + :param cpts: Dictionary of conditional probability tables. + """ + # add nodes + [self.add_var(v, cpt=cpts[v]) for v in variables] + + # add edges + [self.add_edge(e) for e in edges] + + # check for cycles + if not nx.is_directed_acyclic_graph(self.structure): + raise Exception('The provided graph is not acyclic.') + + def load_from_bifxml(self, file_path: str) -> None: + """ + Load a BayesNet from a file in BIFXML file format. See description of BIFXML here: + http://www.cs.cmu.edu/afs/cs/user/fgcozman/www/Research/InterchangeFormat/ + + :param file_path: Path to the BIFXML file. + """ + # Read and parse the bifxml file + with open(file_path) as f: + bn_file = f.read() + bif_reader = XMLBIFReader(string=bn_file) + + # load cpts + cpts = {} + # iterating through vars + for key, values in bif_reader.get_values().items(): + values = values.transpose().flatten() + n_vars = int(math.log2(len(values))) + worlds = [list(i) for i in itertools.product([False, True], repeat=n_vars)] + # create empty array + cpt = [] + # iterating through worlds within a variable + for i in range(len(values)): + # add the probability to each possible world + worlds[i].append(values[i]) + cpt.append(worlds[i]) + + # determine column names + columns = bif_reader.get_parents()[key] + columns.reverse() + columns.append(key) + columns.append('p') + cpts[key] = pd.DataFrame(cpt, columns=columns) + + # load vars + variables = bif_reader.get_variables() + + # load edges + edges = bif_reader.get_edges() + + self.create_bn(variables, edges, cpts) + + # METHODS THAT MIGHT ME USEFUL ------------------------------------------------------------------------------------- + + def get_children(self, variable: str) -> List[str]: + """ + Returns the children of the variable in the graph. + :param variable: Variable to get the children from + :return: List of children + """ + return [c for c in self.structure.successors(variable)] + + def get_cpt(self, variable: str) -> pd.DataFrame: + """ + Returns the conditional probability table of a variable in the BN. + :param variable: Variable of which the CPT should be returned. + :return: Conditional probability table of 'variable' as a pandas DataFrame. + """ + try: + return self.structure.nodes[variable]['cpt'] + except KeyError: + raise Exception('Variable not in the BN') + + def get_all_variables(self) -> List[str]: + """ + Returns a list of all variables in the structure. + :return: list of all variables. + """ + return [n for n in self.structure.nodes] + + def get_all_cpts(self) -> Dict[str, pd.DataFrame]: + """ + Returns a dictionary of all cps in the network indexed by the variable they belong to. + :return: Dictionary of all CPTs + """ + cpts = {} + for var in self.get_all_variables(): + cpts[var] = self.get_cpt(var) + + return cpts + + def get_interaction_graph(self): + """ + Returns a networkx.Graph as interaction graph of the current BN. + :return: The interaction graph based on the factors of the current BN. + """ + # Create the graph and add all variables + int_graph = nx.Graph() + [int_graph.add_node(var) for var in self.get_all_variables()] + + # connect all variables with an edge which are mentioned in a CPT together + for var in self.get_all_variables(): + involved_vars = list(self.get_cpt(var).columns)[:-1] + for i in range(len(involved_vars)-1): + for j in range(i+1, len(involved_vars)): + if not int_graph.has_edge(involved_vars[i], involved_vars[j]): + int_graph.add_edge(involved_vars[i], involved_vars[j]) + return int_graph + + @staticmethod + def get_compatible_instantiations_table(instantiation: pd.Series, cpt: pd.DataFrame): + """ + Get all the entries of a CPT which are compatible with the instantiation. + + :param instantiation: a series of assignments as tuples. E.g.: pd.Series({"A": True, "B": False}) + :param cpt: cpt to be filtered + :return: table with compatible instantiations and their probability value + """ + var_names = instantiation.index.values + var_names = [v for v in var_names if v in cpt.columns] # get rid of excess variables names + compat_indices = cpt[var_names] == instantiation[var_names].values + compat_indices = [all(x[1]) for x in compat_indices.iterrows()] + compat_instances = cpt.loc[compat_indices] + return compat_instances + + def update_cpt(self, variable: str, cpt: pd.DataFrame) -> None: + """ + Replace the conditional probability table of a variable. + :param variable: Variable to be modified + :param cpt: new CPT + """ + self.structure.nodes[variable]["cpt"] = cpt + + @staticmethod + def reduce_factor(instantiation: pd.Series, cpt: pd.DataFrame) -> pd.DataFrame: + """ + Creates and returns a new factor in which all probabilities which are incompatible with the instantiation + passed to the method to 0. + + :param instantiation: a series of assignments as tuples. E.g.: pd.Series({"A": True, "B": False}) + :param cpt: cpt to be reduced + :return: cpt with their original probability value and zero probability for incompatible instantiations + """ + var_names = instantiation.index.values + var_names = [v for v in var_names if v in cpt.columns] # get rid of excess variables names + if len(var_names) > 0: # only reduce the factor if the evidence appears in it + new_cpt = deepcopy(cpt) + incompat_indices = cpt[var_names] != instantiation[var_names].values + incompat_indices = [any(x[1]) for x in incompat_indices.iterrows()] + new_cpt.loc[incompat_indices, 'p'] = 0.0 + return new_cpt + else: + return cpt + + def draw_structure(self) -> None: + """ + Visualize structure of the BN. + """ + nx.draw(self.structure, with_labels=True, node_size=3000) + plt.show() + + # BASIC HOUSEKEEPING METHODS --------------------------------------------------------------------------------------- + + def add_var(self, variable: str, cpt: pd.DataFrame) -> None: + """ + Add a variable to the BN. + :param variable: variable to be added. + :param cpt: conditional probability table of the variable. + """ + if variable in self.structure.nodes: + raise Exception('Variable already exists.') + else: + self.structure.add_node(variable, cpt=cpt) + + def add_edge(self, edge: Tuple[str, str]) -> None: + """ + Add a directed edge to the BN. + :param edge: Tuple of the directed edge to be added (e.g. ('A', 'B')). + :raises Exception: If added edge introduces a cycle in the structure. + """ + if edge in self.structure.edges: + raise Exception('Edge already exists.') + else: + self.structure.add_edge(edge[0], edge[1]) + + # check for cycles + if not nx.is_directed_acyclic_graph(self.structure): + self.structure.remove_edge(edge[0], edge[1]) + raise ValueError('Edge would make graph cyclic.') + + def del_var(self, variable: str) -> None: + """ + Delete a variable from the BN. + :param variable: Variable to be deleted. + """ + self.structure.remove_node(variable) + + def del_edge(self, edge: Tuple[str, str]) -> None: + """ + Delete an edge form the structure of the BN. + :param edge: Edge to be deleted (e.g. ('A', 'B')). + """ + self.structure.remove_edge(edge[0], edge[1]) diff --git a/MAP.jpg b/MAP.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9232eb497b1f13442a75de8f8abcf33ddb849190 GIT binary patch literal 128843 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

0fP~2^-Vv-68lMNygEBE&jb%dDly;pCzR2 zzQLg;oG5DOX4u{U022>W@?&R>qpi>$J#x@N+Z2XzV~g_>y$lY{(?YrM^J=cQv(v`b zVnp>`-*!CoP55KR_C0+&>+_GIxwMiTu!i)aqO!palai8;(pDDQ+;1B|NIU~cehb-U z^y2#|=RG@f@ipQ+sLh(M#iiX5struqd`ET0RJ&1G_F@B_*Xn$=`#4caztNN^<2-_y z7WbodaN!CQV}AN18A6kMtooD;JY6YQB_|{9RYh*#V)d`OkB){^#WfNaJSBTgbZm32 zO9Z6yM1rKsBFygqEERg_i$f&qEi{~?YN{Z+ivvf^b@!l=m4$JWo4 zL-KmNChktU$owT5J^`jM0V^o{N%)}}&j=4gFmLi-welh3b;QUures;tN<%kJ<|qOd|Wh%R?g2;<^f&`fTw3TG}*oe z$SFI6W|6ZA$X}{eY9Lem1RyFG`djf7f2U$WSgU$bSwUgQ`51h^pk2NS-)RUn_b0;8 z9SQ$k^f`m7%a7yC)9bko!r2l|oi2KQw&@y+BsJ@iv#j-5Mk2>bVs6- z{;!J#c?S~rME&5Hn;byh?ckctBgHSykbSI?yIjWmIRxax?PCoU8FA*>g3zDx zA{;96*5t*>bI|h4Rg5qSJzkQOZDO6RfAfs>CRWds+d=x-g~+?ih<{Xj3w+D^*YcRC z{{k!U9~pxG{r`V6>i<`={eLs+|5n)i-}LvtSEQYDgQ1^Uy1pqeQeRXayhK+J&Z_Om z-ckm~-WY%{fzs$zIN{03Va8zKwdfZK>Y&I2kh?a76CR0$9}tfqZR(VZR3!>8z+)z9 z$le*seIzKOGMwe2cmRtH2GG2KSZh41#r_a+ RugFd$0lEiN1Jp<3{|6=dmtz0` literal 0 HcmV?d00001 diff --git a/MPE.jpg b/MPE.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c5044db135b6b37b64104828921d3a0cce6d208e GIT binary patch literal 120162 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 -tag. - -Be aware of the order of the values in the probability table tag. They should be ordered in a way that corresponds to -boolean counting where the "For" variable is the least significant bit followed by the "Given" variables from bottom -to top. Here an example of what this is supposed to mean. Let's assume we have the following CPT table in the BIFXML file: -``` - - dog-out - bowel-problem - family-out - 0.99 0.01 0.97 0.03 0.9 0.1 0.3 0.7
-
-``` -Then the order of the variables in the table (from left to right) is: "bowel-problem", "family-out", "dog-out". Filling -in the values, this leads to the following table: - -| bowel-problem | family-out | dog-out | p | -|---------------|---------------|-----------|------| -| False | False | False | 0.99 | -| False | False | True | 0.01 | -| False | True | False | 0.97 | -| False | True | True | 0.03 | -| True | False | False | 0.9 | -| True | False | True | 0.1 | -| True | True | False | 0.3 | -| True | True | True | 0.7 | -##### Table 1: CPT of the "dog-out" node of the "dog_problem.BIFXML" example - -# The BayesNet Class -Among the files of this project you can find the BayesNet class. We provided you with this class, so you don't need to -worry much about the data structure in which the BN can be represented. This class provides you with (hopefully) useful -functions for BNs such as loading them from a file and retrieving the CPT of a variable. We *highly* recommend using it. -Of course, you are also free to implement your own methods and change the existing ones if they don't fit your purpose. -For this class to work you will need to install (either with pip or anaconda) the following packages: networkx, -matplotlib, pgmpy, pandas (see also requirements.txt). - -Internally, the graphical structure of the BN is represented as a DiGraph object from the networkx package. The CPTs -are modelled with DataFrames form the Pandas package. Each CPT is a DataFrame which corresponds to the form as is shown -in Table 1. - -We want to point out some methods which we deem especially useful here, but all methods come with their documentation -in the comments fo the methods. - -+ `get_compatible_instantiations_table(instantiation, cpt)`: This method takes an instantiation as a pandas series and - a CPT as a pandas DataFrame. It checks which rows of the provided CPT are compatible with the instantiation and - returns only those rows. - -+ `reduce_factor(instantiation, cpt)`: This method takes an instantiation as a pandas series and - a CPT as a pandas DataFrame. It returns a new CPT in which all the rows that are incompatible with the instantiation - are set to 0. - -+ `get_interaction_graph()`: Returns a new, undirected Graph object which corresponds to the interaction graph of the -current BN. - -+ `draw_structure()`: Plots the graph structure of the current BN. - -# Other useful methods -There are also a few other methods which might turn out useful during the implementation of this project. Note that -they are completely optional to use, and it might well be the case that your implementation will work well even without -them. We also provide them as some are used int the BayesNet class. - -## Pandas methods -+ `dog_out_CPT['p']` returns the 'p' column of the dog_out_CPT DataFrame as a pandas Series. (0.99 0.01 0.97 0.03 0.9 - 0.1 0.3 0.7) -+ `dog_out_CPT['p'].max()` returns the maximum of the probability values. (0.99) -+ `dog_out_CPT['family-out'] == dog_out_CPT['bowel-problem']` creates a pandas Series which is true for every index in - which "bowel-problem" and "family-out" is the same in the dog_out_CPT. (True, True, False, False, False, False, True, - True). The arguments in the brackets can also be lists of column names in which case multiple columns are compared. -+ `dog_out_CPT.iloc[2]` returns the third row of the DataFrame. (False, True, False, 0.97) -+ `dog_out_CPT.loc[dog_out_CPT['family-out'] == dog_out_CPT['bowel-problem']]` returns all rows of the CPT in which - 'bowel-problem' == 'family-out'. (rows 0, 1, 6 and 7) -+ `dog_out_CPT.loc[dog_out_CPT['family-out'] == dog_out_CPT['bowel-problem'], 'p'] = 0.0` sets the 'p' value of the - above mentioned rows to 0.0. This usage of loc[row(s), column(s)] corresponds to direct access to a cell or - subtable. -+ `pd.Series({'Winter?': True, 'Sprinkler?': False})` creates a pandas Series in which 'Winter?' is set to True and - 'Sprinkler?' is set to False. This is a useful format for passing evidence to some methods of this assignment - -+ `dog_out_CPT.iterrows()` provides an iterator through all the rows of a DataFrame. This is useful for using in loops. -Beware that the returned value is always a tuple of (row_number, row_content). - -## Networkx methods -It is likely, that you will not have to use this package at all. One possible methods that could be useful is -`networkx.neighbors(G, var)` which provides a list of all neighbors of the variable 'var' in the graph 'G'. + +######### How to run the code ############ + +# PART 1 + +1. Run "python test.py" +2. For all methods the condition is True. If you want to run for specific helper method then make the other varibles false. + + +# Part 2 + +1. generate_bn.py is used to create random baysian networks. +2. folder testing->Part_2 consists of random baysian network part 2 was tested on. +3. to run the script to get the runtime of MAP and MPE for 3 different heuristics, run "python Part2.py" which will dump 2 excel in output folder. + +# Part 3 + +1. run "python use_case.py" + + + + + +# Useful Pointers for Assignment 2 of KR21 +## BIFXML file format +The BIFXML file format is meant to provide an easy means of exchanging Bayesian networks. It works with standard XML +tags. The detailed description of the format can be found at +http://www.cs.cmu.edu/afs/cs/user/fgcozman/www/Research/InterchangeFormat/. Please read this carefully. +Note that for our purposes it will be enough to only have nodes of type "nature", and we will not need the `` +tag. + +Be aware of the order of the values in the probability table tag. They should be ordered in a way that corresponds to +boolean counting where the "For" variable is the least significant bit followed by the "Given" variables from bottom +to top. Here an example of what this is supposed to mean. Let's assume we have the following CPT table in the BIFXML file: +``` + + dog-out + bowel-problem + family-out + 0.99 0.01 0.97 0.03 0.9 0.1 0.3 0.7
+
+``` +Then the order of the variables in the table (from left to right) is: "bowel-problem", "family-out", "dog-out". Filling +in the values, this leads to the following table: + +| bowel-problem | family-out | dog-out | p | +|---------------|---------------|-----------|------| +| False | False | False | 0.99 | +| False | False | True | 0.01 | +| False | True | False | 0.97 | +| False | True | True | 0.03 | +| True | False | False | 0.9 | +| True | False | True | 0.1 | +| True | True | False | 0.3 | +| True | True | True | 0.7 | +##### Table 1: CPT of the "dog-out" node of the "dog_problem.BIFXML" example + +# The BayesNet Class +Among the files of this project you can find the BayesNet class. We provided you with this class, so you don't need to +worry much about the data structure in which the BN can be represented. This class provides you with (hopefully) useful +functions for BNs such as loading them from a file and retrieving the CPT of a variable. We *highly* recommend using it. +Of course, you are also free to implement your own methods and change the existing ones if they don't fit your purpose. +For this class to work you will need to install (either with pip or anaconda) the following packages: networkx, +matplotlib, pgmpy, pandas (see also requirements.txt). + +Internally, the graphical structure of the BN is represented as a DiGraph object from the networkx package. The CPTs +are modelled with DataFrames form the Pandas package. Each CPT is a DataFrame which corresponds to the form as is shown +in Table 1. + +We want to point out some methods which we deem especially useful here, but all methods come with their documentation +in the comments fo the methods. + ++ `get_compatible_instantiations_table(instantiation, cpt)`: This method takes an instantiation as a pandas series and + a CPT as a pandas DataFrame. It checks which rows of the provided CPT are compatible with the instantiation and + returns only those rows. + ++ `reduce_factor(instantiation, cpt)`: This method takes an instantiation as a pandas series and + a CPT as a pandas DataFrame. It returns a new CPT in which all the rows that are incompatible with the instantiation + are set to 0. + ++ `get_interaction_graph()`: Returns a new, undirected Graph object which corresponds to the interaction graph of the +current BN. + ++ `draw_structure()`: Plots the graph structure of the current BN. + +# Other useful methods +There are also a few other methods which might turn out useful during the implementation of this project. Note that +they are completely optional to use, and it might well be the case that your implementation will work well even without +them. We also provide them as some are used int the BayesNet class. + +## Pandas methods ++ `dog_out_CPT['p']` returns the 'p' column of the dog_out_CPT DataFrame as a pandas Series. (0.99 0.01 0.97 0.03 0.9 + 0.1 0.3 0.7) ++ `dog_out_CPT['p'].max()` returns the maximum of the probability values. (0.99) ++ `dog_out_CPT['family-out'] == dog_out_CPT['bowel-problem']` creates a pandas Series which is true for every index in + which "bowel-problem" and "family-out" is the same in the dog_out_CPT. (True, True, False, False, False, False, True, + True). The arguments in the brackets can also be lists of column names in which case multiple columns are compared. ++ `dog_out_CPT.iloc[2]` returns the third row of the DataFrame. (False, True, False, 0.97) ++ `dog_out_CPT.loc[dog_out_CPT['family-out'] == dog_out_CPT['bowel-problem']]` returns all rows of the CPT in which + 'bowel-problem' == 'family-out'. (rows 0, 1, 6 and 7) ++ `dog_out_CPT.loc[dog_out_CPT['family-out'] == dog_out_CPT['bowel-problem'], 'p'] = 0.0` sets the 'p' value of the + above mentioned rows to 0.0. This usage of loc[row(s), column(s)] corresponds to direct access to a cell or + subtable. ++ `pd.Series({'Winter?': True, 'Sprinkler?': False})` creates a pandas Series in which 'Winter?' is set to True and + 'Sprinkler?' is set to False. This is a useful format for passing evidence to some methods of this assignment + ++ `dog_out_CPT.iterrows()` provides an iterator through all the rows of a DataFrame. This is useful for using in loops. +Beware that the returned value is always a tuple of (row_number, row_content). + +## Networkx methods +It is likely, that you will not have to use this package at all. One possible methods that could be useful is +`networkx.neighbors(G, var)` which provides a list of all neighbors of the variable 'var' in the graph 'G'. + diff --git a/generate_bn.py b/generate_bn.py new file mode 100644 index 00000000..13f97d4d --- /dev/null +++ b/generate_bn.py @@ -0,0 +1,29 @@ +# import networkx as nx +import numpy as np +from pgmpy.models import BayesianNetwork + + +# Set random seed for reproducibility +np.random.seed(123) + +# Set the range of node numbers to generate networks for +start = 10 +end = 50 +skip = 3 +node_counts = range(start, end+1, skip) + +# Set the number of networks to generate for each node number +n_networks = 1 + +# Set the probability of an edge between any two nodes +edge_prob1 = 0.03 + +# Iterate over the range of node numbers +for n_node in node_counts: + + # Iterate over the number of networks + for i in range(n_networks): + + G = BayesianNetwork.get_random(n_nodes=n_node, edge_prob=edge_prob1, n_states=2) + + G.save(f'testing/Part_2/network_{n_node}.XMLBIF', filetype='XMLBIF') diff --git a/requirements.txt b/requirements.txt index f60dda17..7fe177fb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -networkx~=2.6.3 -matplotlib~=3.4.3 -pgmpy~=0.1.16 +networkx~=2.6.3 +matplotlib~=3.4.3 +pgmpy~=0.1.16 pandas~=1.3.4 \ No newline at end of file diff --git a/test.py b/test.py index 86671ca8..f0369cef 100644 --- a/test.py +++ b/test.py @@ -1,73 +1,229 @@ -from BNReasoner import BNReasoner -from BayesNet import BayesNet -import pandas as pd - -if __name__ == "__main__": - print("begin") - - net = 'testing/lecture_example.BIFXML' - - #net = 'testing/lecture_example.BIFXML' - - bn = BayesNet() - bn.load_from_bifxml(net) - # bn.draw_structure() - bnr = BNReasoner(bn) - - ### Test pruning - #outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) - - ### D-seperation - #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated - #outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated - - ### Order min-degree - #outcome_min_degree = bnr.min_degree() - #print(outcome_min_degree) - - ### Order min-degree - # outcome_min_fill = bnr.min_fill() - # print(outcome_min_fill) - - - ### Factor Multiplication - # net = 'testing/lecture_example.BIFXML' - # outcome_factor = bnr.factor_multiplication(['Rain?', 'Wet Grass?']) - # print(outcome_factor) - - ### MPE - # net = 'testing/lecture_example2.BIFXML' - # mpe = bnr.MPE(pd.Series({'J': True, 'O': False})) - # print(mpe) - - - ### MAP - # map = bnr.MAP(['I', 'J'], pd.Series({'O': True})) - # print(map) - - - - # outcome.draw_structure() - - # X = "Wet Grass?" - # Y = BayesNet.get_cpt(bnr.bn,X) - # # f = bnr.multip_factors(Y) - # print(Y) - # outcome = bnr.sum_out_factors(Y,X) #bnr.maximise_out(Y,X) - # print(outcome) - - ### Elimination - # outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) - #outcome_elim = bnr.elimination(bn.get_cpt('Winter?'), ['Winter?']) # Empty Dataframe - # print(outcome_elim) - - ### Independence - Y = {"Winter?"} - X = {"Slippery Road?"} - Z = {} - if bnr.independence(bnr.bn, X,Y,Z): - print(X, "is independent from ", Y, "given ", Z) - else: - print(X, "is not independent from ", Y, "given ", Z) - - #python3 test.py \ No newline at end of file +from BNReasoner import BNReasoner +from BayesNet import BayesNet +import pandas as pd +import networkx as nx +import matplotlib.pyplot as plt +import numpy as np +import warnings +warnings.filterwarnings("ignore") + +if __name__ == "__main__": +<<<<<<< Updated upstream + print("begin") + + net = 'testing/lecture_example.BIFXML' + + #net = 'testing/lecture_example.BIFXML' + + bn = BayesNet() + bn.load_from_bifxml(net) + # bn.draw_structure() + bnr = BNReasoner(bn) + + ### Test pruning + #outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) + + ### D-seperation + #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated + #outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated + + ### Order min-degree + #outcome_min_degree = bnr.min_degree() + #print(outcome_min_degree) + + ### Order min-degree + # outcome_min_fill = bnr.min_fill() + # print(outcome_min_fill) + +======= + + Pruning = True + check_d_separation = True + Independence = True + Marginalization = True + MaxingOut = True + FactorMultiplication = True + Ordering_min_degree = True + Ordering_min_fill = True + Elimination = True + Marginal_distribution = True + checkMAP = True + checkMEP = True + + ### Test pruning + if Pruning: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + print("#----------------------------------------Pruning---------------------------------------#") + outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) + print(outcome) + + ### D-seperation + if check_d_separation: + net = 'testing/dog_problem.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated + print("#-----------------------------------------D-seperation---------------------------------#") + outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated + print(outcome_d) + + ## Test independence + if Independence: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + Y = {"Winter?"} + X = {"Slippery Road?"} + Z = {} + if bnr.check_independence(bnr.bn, X,Y,Z): + print("#--------------------------------Independence--------------------------------------#") + print(X, "is independent from ", Y, "given ", Z) + else: + print("#--------------------------------Independence--------------------------------------#") + print(X, "is not independent from ", Y, "given ", Z) + + ### Test marginalization + if Marginalization: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + X = "Wet Grass?" + Y = BayesNet.get_cpt(bnr.bn,X) + outcome_marg = bnr.sum_out_factors(Y,X) + print("#-------------------------------Marginalization--------------------------------------#") + print(outcome_marg) + + ### Test maxing out + if MaxingOut: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + X = "Wet Grass?" + Y = BayesNet.get_cpt(bnr.bn,X) + outcome_max = bnr.maximise_out(Y,X) + print("#-------------------------------Maxing out-------------------------------------------#") + print(outcome_max) + + ### Test factor multiplication + if FactorMultiplication: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_factor = bnr.factor_multiplication(['Rain?', 'Wet Grass?']) + print("#-------------------------------Factor multiplication-------------------------------#") + print(outcome_factor) + + ### Test ordering min + if Ordering_min_degree: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_min_degree = bnr.min_degree() + print("#-------------------------------Ordering min degree----------------------------------#") + print(outcome_min_degree) + + + ### Test ordering min fill + if Ordering_min_fill: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_min_fill = bnr.min_fill() + print("#--------------------------------Ordering min fill----------------------------------#") + print(outcome_min_fill) + + ### Elimination + if Elimination: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) + print("#-------------------------------Elimination---------------------------------------#") + print(outcome_elim) + + ### Marginal distribution + if Marginal_distribution: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_md = bnr.compute_marginal(['Wet Grass?', 'Slippery Road?'], order=bnr.min_degree()) + print("#-------------------------------Marginal distribution-----------------------------#") + print(outcome_md) + + ### MAP + if checkMAP: + net = 'testing/lecture_example2.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_map = bnr.MAP(['I', 'J'], pd.Series({'O': True})) + print("#-------------------------------------MAP-----------------------------------------#") + print(outcome_map) +>>>>>>> Stashed changes + + ### Factor Multiplication + # net = 'testing/lecture_example.BIFXML' + # outcome_factor = bnr.factor_multiplication(['Rain?', 'Wet Grass?']) + # print(outcome_factor) + +<<<<<<< Updated upstream + ### MPE + # net = 'testing/lecture_example2.BIFXML' + # mpe = bnr.MPE(pd.Series({'J': True, 'O': False})) + # print(mpe) + + + ### MAP + # map = bnr.MAP(['I', 'J'], pd.Series({'O': True})) + # print(map) + + + + # outcome.draw_structure() + + # X = "Wet Grass?" + # Y = BayesNet.get_cpt(bnr.bn,X) + # # f = bnr.multip_factors(Y) + # print(Y) + # outcome = bnr.sum_out_factors(Y,X) #bnr.maximise_out(Y,X) + # print(outcome) + + ### Elimination + # outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) + #outcome_elim = bnr.elimination(bn.get_cpt('Winter?'), ['Winter?']) # Empty Dataframe + # print(outcome_elim) + + ### Independence + Y = {"Winter?"} + X = {"Slippery Road?"} + Z = {} + if bnr.independence(bnr.bn, X,Y,Z): + print(X, "is independent from ", Y, "given ", Z) + else: + print(X, "is not independent from ", Y, "given ", Z) + + #python3 test.py +======= + ## MPE + if checkMEP: + net = 'testing/lecture_example2.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(net) + outcome_mpe = bnr.MPE(pd.Series({'J': True, 'O': False})) + print("#-------------------------------------MPE-----------------------------------------#") + print(outcome_mpe) + +>>>>>>> Stashed changes diff --git a/use_case.py b/use_case.py new file mode 100644 index 00000000..02ad3f7b --- /dev/null +++ b/use_case.py @@ -0,0 +1,65 @@ +from BNReasoner import BNReasoner +from BayesNet import BayesNet +import pandas as pd +import warnings +warnings.filterwarnings("ignore") + +if __name__ == "__main__": + print("begin") + + net = 'testing/use_case.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + + + Marginal_distribution = True + checkMAP = False + checkMEP = False + + + ### Marginal distribution, a-priori for stroke or bleed + if Marginal_distribution: + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + #outcome_md = bnr.compute_marginal(['Stroke'], order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Stroke history': True, "High blood pressure": True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Anticoagulant': True, "High blood pressure": True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Diabetes': True, "70+": True, "Liver/kidney disease":True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Diabetes': True, "70+": True, "Anticoagulant":True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Smoking': True, "70+": True, "Hyperlipidemia":True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Smoking': True, "70+": True, "Diabetes":True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Smoking': True, "Blood thick": True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Stroke history': True, "Hyperlipidemia": True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Liver/kidney disease': True, "Stroke history": True}), order=bnr.min_degree()) + outcome_md = bnr.compute_marginal(['Internal Bleeding'], order=bnr.min_degree()) + print(outcome_md) + ''' + + ### Marginal distribution, apostpriori for stroke or bleed + if Marginal_distribution: + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Stroke history': True, "High blood pressure": True}), order=bnr.min_degree()) + outcome_md = bnr.compute_marginal(['Internal Bleeding'], pd.Series({'Anticoagulant':True, "Diabetes":True}), order=bnr.min_degree()) + print(outcome_md) +''' + + ### MAP + if checkMAP: + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_map = bnr.MAP(["70+", "Smoker"], pd.Series({'Stroke history': True, "High blood pressure": True, "Hyperlipidemie":True})) + print(outcome_map) + + + ### MPE + if checkMEP: + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_mpe = bnr.MPE(pd.Series({'Stroke': True, "High blood pressure":True})) + print(outcome_mpe.to_string()) From cbe6a1930a9595812e3214dfc242095bd2eb8f84 Mon Sep 17 00:00:00 2001 From: tkaintura <40258112+tkaintura@users.noreply.github.com> Date: Fri, 16 Dec 2022 17:22:58 +0100 Subject: [PATCH 13/16] Add files via upload --- BNReasoner.py | 156 +++++--------------------------------------------- 1 file changed, 15 insertions(+), 141 deletions(-) diff --git a/BNReasoner.py b/BNReasoner.py index 997060b7..4ff5ff94 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -42,13 +42,8 @@ def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: for child in bayes_net.get_children(a): # Check if the removed node has children, if yes delete edge bayes_net.del_edge((a, child)) # Delete edge if input variable has child finished = True -<<<<<<< Updated upstream - # print(p.get_all_cpts()," dit is p") - return p -======= print(bayes_net.get_all_cpts()," dit is p") return bayes_net ->>>>>>> Stashed changes def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: bayes_net = deepcopy(self.bn) @@ -110,17 +105,7 @@ def min_fill(self, network: BayesNet = None) -> List[str]: order_edges.append((node, i)) return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name -<<<<<<< Updated upstream - def init_factor(self,variables: List[str], value=0) -> pd.DataFrame: - """ - Generate a default CPT. - :param variables: Column names - :param value: Which the default p-value should be - :return: A CPT - """ -======= def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: ->>>>>>> Stashed changes truth_table = product([True, False], repeat=len(variables)) factor = pd.DataFrame(truth_table, columns=variables) factor['p'] = value @@ -173,33 +158,6 @@ def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list return res_factor.reset_index(drop=True) - def factor_multiplication(self,f,g): - ''' - Given two factors f and g, compute the multiplied factor h=fg - :param f: Factor f - :param g: Factor g - :returns: Multiplied factor h=f*g - ''' - - # check what the overlapping var(s) is - vars_f = [x for x in f.columns] - vars_g = [x for x in g.columns] - - for var in vars_f: - if var in vars_g and var != 'p': - join_var = var - - # merge two dataframes - merged = f.merge(g,left_on=join_var,right_on=join_var) - - # multiply probabilities - merged['p'] = merged['p_x']*merged['p_y'] - - # drop individual probability columns - h = merged.drop(['p_x','p_y'],axis=1) - - # return h - return h def factor_multiplication(self, factors: List[Union[str, pd.DataFrame]]) -> pd.DataFrame: # If there are strings in the input-list of factors, replace them with the corresponding cpt @@ -258,13 +216,13 @@ def MPE(self, evidence: pd.Series, order_func: str = None) -> pd.DataFrame: # Pop all functions from S, which mention var_pi... func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] - new_factor = self.multiply_factors(func_k) if len(func_k) > 1 else func_k[0] + new_factor = self.factor_multiplication(func_k) if len(func_k) > 1 else func_k[0] new_factor = self.maximise_out(new_factor, var_pi) # And replace them with the new factor S[var_pi] = new_factor - res_factor = self.multiply_factors(list(S.values())) if len(S) > 1 else S.popitem()[1] + res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] return res_factor def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.DataFrame: @@ -304,90 +262,6 @@ def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.D res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] return res_factor -<<<<<<< Updated upstream - # def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - # """ - # :param factor: - # :param subset: - # :return: - # """ - # if isinstance(factor, str): - # factor = self.bn.get_cpt(factor) - # if isinstance(subset, str): - # subset = [subset] - - # # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get - # # each possible instantiation. - # ext = [c for c in factor.columns if c[:3] == 'ext'] - # instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() - # res_factor = pd.DataFrame(columns=factor.columns) - - # if len(instantiations.columns) == 0: - # try: - # res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) - # except IndexError: - # print('w') - # else: - # for _, instantiation in instantiations.iterrows(): - # cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) - # res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) - - # # For each maximized-out variable(s), rename them to ext(variable) - # for v in subset: - # x = res_factor.pop(v) - # res_factor[f'ext({v})'] = x - - # return res_factor.reset_index(drop=True) - - # def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: - # """ - # Generate a default CPT. - # :param variables: Column names - # :param value: Which the default p-value should be - # :return: A CPT - # """ - # print(variables) - # truth_table = product([True, False], repeat=len(variables)) - # factor = pd.DataFrame(truth_table, columns=variables) - # factor['p'] = value - # return factor - - # def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - # """ - # Sum out some variable(s) in subset from a factor. - # :param factor: factor over variables X - # :param subset: a subset of variables X - # :return: a factor corresponding to the factor with the subset summed out - # """ - - # if isinstance(factor, str): - # factor = self.bn.get_cpt(factor) - # if isinstance(subset, str): - # subset = [subset] - - # new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() - # new_factor['p'] = 0 - # subset_factor = self.init_factor(subset) - - # for i, y in new_factor.iterrows(): - # for _, z in subset_factor.iterrows(): - # new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( - # y[:-1].append(z[:-1]), factor)['p'].sum() - # # sum() instead of float() here, since the compatible table can be empty at times, this works around it - - # return new_factor.reset_index(drop=True) - - def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: - """ Sum out a set of variables by using variable elimination - - Args: - data (pd.Dataframe): Dataframe of where elimination should take place - var (List): Variable to be summed out - - Returns: - pd.Dataframe: Dataframe after elimination - """ -======= def compute_marginal(self, query: List[str], evidence: pd.Series = None, order: List[str] = None) -> pd.DataFrame: if order is None: order = self.random_order() @@ -421,8 +295,19 @@ def compute_marginal(self, query: List[str], evidence: pd.Series = None, order: return res_factor def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: ->>>>>>> Stashed changes +<<<<<<< Updated upstream + """ Sum out a set of variables by using variable elimination + + Args: + data (pd.Dataframe): Dataframe of where elimination should take place + var (List): Variable to be summed out + + Returns: + pd.Dataframe: Dataframe after elimination + """ +======= print(data, "initial dataframe") +>>>>>>> Stashed changes remaining = data.drop(columns=var) # Drop column thats need to be summed out rem_list = list(remaining.columns.values)[:-1] # Get remaining dataframe if len(rem_list) == 0: # If empty return empty frame @@ -433,6 +318,7 @@ def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: eliminated.reset_index(inplace=True) return eliminated + def loop_over_children(self,bn, y, parent): # print("parent: ", parent) children = BayesNet.get_children(bn, parent) @@ -447,19 +333,8 @@ def loop_over_children(self,bn, y, parent): if not self.loop_over_children(bn, y, child): return False return True -<<<<<<< Updated upstream - - def independence(self, bn, X, Y, Z): - ''' - Implementation of Markov Property and Symmetry in DAGS to determine independence - :param bn: Bayesian Network - :param X, Y, Z: sets of variable of which to decide whether X is independent of Y given Z - :returns: Bool, True if X and Y are independent given Z, False if X and Y are not independent given Z - ''' -======= def check_independence(self, bn, X, Y, Z): ->>>>>>> Stashed changes Not_all_parents_of_X = False for x in X: for parent in BayesNet.get_all_variables(bn): @@ -491,4 +366,3 @@ def check_independence(self, bn, X, Y, Z): return False return True - From 99dd64a87767b49881deda75c85442c8260dbd34 Mon Sep 17 00:00:00 2001 From: Jpayanshi Date: Fri, 16 Dec 2022 17:23:39 +0100 Subject: [PATCH 14/16] Final Code --- BNReasoner.py | 171 +++--- MAP.jpg | Bin 0 -> 128843 bytes MPE.jpg | Bin 0 -> 120162 bytes Part2.py | 64 +++ README.md | 25 +- generate_bn.py | 29 + test.py | 187 +++++-- testing/Part_2/network_10.XMLBIF | 108 ++++ testing/Part_2/network_12.XMLBIF | 130 +++++ testing/Part_2/network_14.XMLBIF | 148 +++++ testing/Part_2/network_16.XMLBIF | 169 ++++++ testing/Part_2/network_18.XMLBIF | 189 +++++++ testing/Part_2/network_20.XMLBIF | 214 ++++++++ testing/Part_2/network_22.XMLBIF | 234 ++++++++ testing/Part_2/network_24.XMLBIF | 255 +++++++++ testing/Part_2/network_26.XMLBIF | 272 +++++++++ testing/Part_2/network_28.XMLBIF | 297 ++++++++++ testing/Part_2/network_30.XMLBIF | 320 +++++++++++ testing/Part_2/network_32.XMLBIF | 338 ++++++++++++ testing/Part_2/network_34.XMLBIF | 364 +++++++++++++ testing/Part_2/network_36.XMLBIF | 393 +++++++++++++ testing/Part_2/network_38.XMLBIF | 409 ++++++++++++++ testing/Part_2/network_40.XMLBIF | 431 +++++++++++++++ testing/Part_2/network_42.XMLBIF | 459 ++++++++++++++++ testing/Part_2/network_44.XMLBIF | 480 ++++++++++++++++ testing/Part_2/network_46.XMLBIF | 504 +++++++++++++++++ testing/Part_2/network_48.XMLBIF | 525 ++++++++++++++++++ testing/Part_2/network_50.XMLBIF | 548 +++++++++++++++++++ testing/Part_2/network_52.XMLBIF | 558 +++++++++++++++++++ testing/Part_2/network_54.XMLBIF | 588 ++++++++++++++++++++ testing/Part_2/network_56.XMLBIF | 617 +++++++++++++++++++++ testing/Part_2/network_58.XMLBIF | 643 ++++++++++++++++++++++ testing/Part_2/network_60.XMLBIF | 654 ++++++++++++++++++++++ testing/Part_2/network_62.XMLBIF | 690 +++++++++++++++++++++++ testing/Part_2/network_64.XMLBIF | 698 ++++++++++++++++++++++++ testing/Part_2/network_66.XMLBIF | 722 ++++++++++++++++++++++++ testing/Part_2/network_68.XMLBIF | 754 +++++++++++++++++++++++++ testing/Part_2/network_70.XMLBIF | 770 ++++++++++++++++++++++++++ testing/Part_2/network_72.XMLBIF | 799 +++++++++++++++++++++++++++ testing/Part_2/network_74.XMLBIF | 831 ++++++++++++++++++++++++++++ testing/Part_2/network_76.XMLBIF | 853 +++++++++++++++++++++++++++++ testing/Part_2/network_78.XMLBIF | 890 ++++++++++++++++++++++++++++++ testing/Part_2/network_80.XMLBIF | 907 +++++++++++++++++++++++++++++++ use_case.py | 65 +++ 44 files changed, 18166 insertions(+), 136 deletions(-) create mode 100644 MAP.jpg create mode 100644 MPE.jpg create mode 100644 Part2.py create mode 100644 generate_bn.py create mode 100644 testing/Part_2/network_10.XMLBIF create mode 100644 testing/Part_2/network_12.XMLBIF create mode 100644 testing/Part_2/network_14.XMLBIF create mode 100644 testing/Part_2/network_16.XMLBIF create mode 100644 testing/Part_2/network_18.XMLBIF create mode 100644 testing/Part_2/network_20.XMLBIF create mode 100644 testing/Part_2/network_22.XMLBIF create mode 100644 testing/Part_2/network_24.XMLBIF create mode 100644 testing/Part_2/network_26.XMLBIF create mode 100644 testing/Part_2/network_28.XMLBIF create mode 100644 testing/Part_2/network_30.XMLBIF create mode 100644 testing/Part_2/network_32.XMLBIF create mode 100644 testing/Part_2/network_34.XMLBIF create mode 100644 testing/Part_2/network_36.XMLBIF create mode 100644 testing/Part_2/network_38.XMLBIF create mode 100644 testing/Part_2/network_40.XMLBIF create mode 100644 testing/Part_2/network_42.XMLBIF create mode 100644 testing/Part_2/network_44.XMLBIF create mode 100644 testing/Part_2/network_46.XMLBIF create mode 100644 testing/Part_2/network_48.XMLBIF create mode 100644 testing/Part_2/network_50.XMLBIF create mode 100644 testing/Part_2/network_52.XMLBIF create mode 100644 testing/Part_2/network_54.XMLBIF create mode 100644 testing/Part_2/network_56.XMLBIF create mode 100644 testing/Part_2/network_58.XMLBIF create mode 100644 testing/Part_2/network_60.XMLBIF create mode 100644 testing/Part_2/network_62.XMLBIF create mode 100644 testing/Part_2/network_64.XMLBIF create mode 100644 testing/Part_2/network_66.XMLBIF create mode 100644 testing/Part_2/network_68.XMLBIF create mode 100644 testing/Part_2/network_70.XMLBIF create mode 100644 testing/Part_2/network_72.XMLBIF create mode 100644 testing/Part_2/network_74.XMLBIF create mode 100644 testing/Part_2/network_76.XMLBIF create mode 100644 testing/Part_2/network_78.XMLBIF create mode 100644 testing/Part_2/network_80.XMLBIF create mode 100644 use_case.py diff --git a/BNReasoner.py b/BNReasoner.py index 1a61f60e..d8a75e71 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -11,9 +11,6 @@ class BNReasoner: def __init__(self, net: Union[str, BayesNet]): - """ - :param net: either file path of the bayesian network in BIFXML format or BayesNet object - """ if type(net) == str: # constructs a BN object self.bn = BayesNet() @@ -24,66 +21,52 @@ def __init__(self, net: Union[str, BayesNet]): # TODO: This is where your methods should go def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: - """ Prune the network, will drop variables that are not needed anymore - Args: - query (List): Given query, used to check if nodes are part of it - values (Dict): The given evedince to a node, must be True or False. Structure: {Node:Value} - - Returns: - p: BayesNet.object, returns the new pruned network - """ - print("pruning") - p = deepcopy(self.bn) + bayes_net = deepcopy(self.bn) finished = True # Continue checking if the pruning can continue - all_cpts = p.get_all_cpts() # A dictionary of all cps in the network indexed by the variable they belong to + all_cpts = bayes_net.get_all_cpts() # A dictionary of all cps in the network indexed by the variable they belong to while finished: # Stop pruning when the network cannot be pruned further finished = False - for var in p.get_all_variables(): - if p.get_children(var) == [] and var not in query and var not in values: # Check if node is part of query - p.del_var(var) # Delete node if not part of query + for var in bayes_net.get_all_variables(): + if bayes_net.get_children(var) == [] and var not in query and var not in values: # Check if node is part of query + bayes_net.del_var(var) # Delete node if not part of query finished = True for a, b in values.items(): # Get node name and value - for variable in p.get_all_variables(): # Get all variables + for variable in bayes_net.get_all_variables(): # Get all variables cpt = all_cpts[variable] if a in cpt.columns: # If variable from input matches a variable from a cpt column: new_cpt = cpt.drop(cpt[cpt[a] != b].index) # If the same node exist with the opposite value, delete it - p.update_cpt(variable, new_cpt) # Update the cpt table without the opposite value + bayes_net.update_cpt(variable, new_cpt) # Update the cpt table without the opposite value else: continue - for child in p.get_children(a): # Check if the removed node has children, if yes delete edge - p.del_edge((a, child)) # Delete edge if input variable has child + for child in bayes_net.get_children(a): # Check if the removed node has children, if yes delete edge + bayes_net.del_edge((a, child)) # Delete edge if input variable has child finished = True +<<<<<<< Updated upstream # print(p.get_all_cpts()," dit is p") return p +======= + print(bayes_net.get_all_cpts()," dit is p") + return bayes_net +>>>>>>> Stashed changes def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: - """ Check if variable x is d-seperated from y given z - - Args: - x (List): List of variables to check - y (list): List of variables to check if x is seperated from - z (list): List of given variables - - Returns: - bool: True is d-seperated, False if not - """ - p = deepcopy(self.bn) + bayes_net = deepcopy(self.bn) reach_single = [] iterated = [] - for var in p.get_all_variables(): - if p.get_children(var) == [] and var not in x and var not in y and var not in z: - p.del_var(var) + for var in bayes_net.get_all_variables(): + if bayes_net.get_children(var) == [] and var not in x and var not in y and var not in z: + bayes_net.del_var(var) for var in z: - for child in p.get_children(var): - p.del_edge([var, child]) + for child in bayes_net.get_children(var): + bayes_net.del_edge([var, child]) for var in x: iterated.append(var) # Append variables to check - reach_single.extend(p.get_children(var)) # Append children + reach_single.extend(bayes_net.get_children(var)) # Append children while list(set(reach_single) - set(iterated)) !=[]: # While loop makes sure children of children are checked for a in list(set(reach_single) - set(iterated)): # Make sure all children are checked - reach_single.extend(p.get_children(a)) # Append children of children if there are any + reach_single.extend(bayes_net.get_children(a)) # Append children of children if there are any iterated.append(a) # Append variable to prevent loop from checking again for var_2 in y: if var_2 in reach_single: # If y in x, not d-seperated @@ -93,31 +76,26 @@ def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: return True def random_order(self, network: BayesNet = None) -> List[str]: - """ - :return: a random ordering of all variables in self.bn - """ if network is None: return list(np.random.permutation(self.bn.get_all_variables())) else: return list(np.random.permutation(network.get_all_variables())) - def min_degree(self) -> List[str]: - """Sort the nodes by looking at the degree + def min_degree(self, network: BayesNet = None) -> List[str]: + if network is None: + bayes_net = deepcopy(self.bn) + else: + bayes_net = deepcopy(network) + + return [x[0] for x in sorted(bayes_net.get_interaction_graph().degree(), key = lambda x: x[1])] # Sort list and only return the variable name - Returns: - List of variables sorted from small to big (degree in the interaction graph to the ordering) - """ - p = deepcopy(self.bn) - return [x[0] for x in sorted(p.get_interaction_graph().degree(), key = lambda x: x[1])] # Sort list and only return the variable name + def min_fill(self, network: BayesNet = None) -> List[str]: + if network is None: + bayes_net = deepcopy(self.bn) + else: + bayes_net = deepcopy(network) - def min_fill(self) -> List[str]: - """ Minimum fill ordering - - Returns: - List of variables sorted from small to big (whose deletion would add the fewest new interaction to the ordering) - """ - p = deepcopy(self.bn) - i_graph = p.get_interaction_graph() + i_graph = bayes_net.get_interaction_graph() order_edges = [] for node in i_graph: i = 0 @@ -132,6 +110,7 @@ def min_fill(self) -> List[str]: order_edges.append((node, i)) return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name +<<<<<<< Updated upstream def init_factor(self,variables: List[str], value=0) -> pd.DataFrame: """ Generate a default CPT. @@ -139,18 +118,15 @@ def init_factor(self,variables: List[str], value=0) -> pd.DataFrame: :param value: Which the default p-value should be :return: A CPT """ +======= + def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: +>>>>>>> Stashed changes truth_table = product([True, False], repeat=len(variables)) factor = pd.DataFrame(truth_table, columns=variables) factor['p'] = value return factor def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - """ - Sum out some variable(s) in subset from a factor. - :param factor: factor over variables X - :param subset: a subset of variables X - :return: a factor corresponding to the factor with the subset summed out - """ if isinstance(factor, str): factor = self.bn.get_cpt(factor) if isinstance(subset, str): @@ -169,11 +145,6 @@ def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, l return new_factor.reset_index(drop=True) def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - """ - :param factor: - :param subset: - :return: - """ if isinstance(factor, str): factor = self.bn.get_cpt(factor) if isinstance(subset, str): @@ -231,11 +202,6 @@ def factor_multiplication(self,f,g): return h def factor_multiplication(self, factors: List[Union[str, pd.DataFrame]]) -> pd.DataFrame: - """ - Multiply multiple factors with each other. - :param factors: a list of factors - :return: a factor corresponding to the product of all given factors - """ # If there are strings in the input-list of factors, replace them with the corresponding cpt for x, y in enumerate(factors): if isinstance(y, str): @@ -266,12 +232,6 @@ def factor_multiplication(self, factors: List[Union[str, pd.DataFrame]]) -> pd.D def MPE(self, evidence: pd.Series, order_func: str = None) -> pd.DataFrame: - """ - Compute the MPE instantiation for some given evidence. - :param evidence: - :param order_func: String describing which order function to use - :return: Dataframe describing the MPE instantiation - """ N = deepcopy(self.bn) # Prune Edges for var in evidence.keys(): @@ -308,13 +268,6 @@ def MPE(self, evidence: pd.Series, order_func: str = None) -> pd.DataFrame: return res_factor def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.DataFrame: - """ - Compute the MAP instantiation for some variables and some given evidence. - :param M: The MAP variables - :param evidence: - :param order_func: String describing which order function to use - :return: Dataframe describing the MAP instantiation - """ if len(np.intersect1d(list(evidence.keys()), M)) > 0: raise Exception("Evidence cannot intersect with M") @@ -351,6 +304,7 @@ def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.D res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] return res_factor +<<<<<<< Updated upstream # def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: # """ # :param factor: @@ -433,6 +387,41 @@ def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: Returns: pd.Dataframe: Dataframe after elimination """ +======= + def compute_marginal(self, query: List[str], evidence: pd.Series = None, order: List[str] = None) -> pd.DataFrame: + if order is None: + order = self.random_order() + + S = self.bn.get_all_cpts() + + if evidence is not None: # If there's evidence, reduce all CPTs using the evidence + for var in self.bn.get_all_variables(): + var_cpt = self.bn.get_cpt(var) + if any(evidence.keys().intersection(var_cpt.columns)): # If the evidence occurs in the cpt + new_cpt = self.bn.get_compatible_instantiations_table(evidence, var_cpt) + S[var] = new_cpt + + pi = [nv for nv in order if nv not in query] + for var_pi in pi: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.factor_multiplication(func_k) + new_factor = self.sum_out_factors(new_factor, var_pi) + # And replace them with the new factor + S[var_pi] = new_factor + + res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] + + if evidence is not None: # Normalizing over pr_evidence + cpt_e = self.compute_marginal(list(evidence.keys()), order=order) + pr_evidence = float(self.bn.get_compatible_instantiations_table(evidence, cpt_e)['p']) + res_factor['p'] = res_factor['p'] / pr_evidence + + return res_factor + + def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: +>>>>>>> Stashed changes print(data, "initial dataframe") remaining = data.drop(columns=var) # Drop column thats need to be summed out rem_list = list(remaining.columns.values)[:-1] # Get remaining dataframe @@ -445,9 +434,7 @@ def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: return eliminated def loop_over_children(self,bn, y, parent): - '''Checks for if y is a descendant of parent''' - - # print("parent: ", parent) + # print("parent: ", parent) children = BayesNet.get_children(bn, parent) # print("children: ", children) if len(children) == 0: @@ -460,6 +447,7 @@ def loop_over_children(self,bn, y, parent): if not self.loop_over_children(bn, y, child): return False return True +<<<<<<< Updated upstream def independence(self, bn, X, Y, Z): ''' @@ -468,6 +456,10 @@ def independence(self, bn, X, Y, Z): :param X, Y, Z: sets of variable of which to decide whether X is independent of Y given Z :returns: Bool, True if X and Y are independent given Z, False if X and Y are not independent given Z ''' +======= + + def check_independence(self, bn, X, Y, Z): +>>>>>>> Stashed changes Not_all_parents_of_X = False for x in X: for parent in BayesNet.get_all_variables(bn): @@ -482,7 +474,6 @@ def independence(self, bn, X, Y, Z): for y in Y: for parent in BayesNet.get_all_variables(bn): if y in BayesNet.get_children(bn, parent): - print(parent) if parent not in Z: return False for y in Y: diff --git a/MAP.jpg b/MAP.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9232eb497b1f13442a75de8f8abcf33ddb849190 GIT binary patch literal 128843 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

0fP~2^-Vv-68lMNygEBE&jb%dDly;pCzR2 zzQLg;oG5DOX4u{U022>W@?&R>qpi>$J#x@N+Z2XzV~g_>y$lY{(?YrM^J=cQv(v`b zVnp>`-*!CoP55KR_C0+&>+_GIxwMiTu!i)aqO!palai8;(pDDQ+;1B|NIU~cehb-U z^y2#|=RG@f@ipQ+sLh(M#iiX5struqd`ET0RJ&1G_F@B_*Xn$=`#4caztNN^<2-_y z7WbodaN!CQV}AN18A6kMtooD;JY6YQB_|{9RYh*#V)d`OkB){^#WfNaJSBTgbZm32 zO9Z6yM1rKsBFygqEERg_i$f&qEi{~?YN{Z+ivvf^b@!l=m4$JWo4 zL-KmNChktU$owT5J^`jM0V^o{N%)}}&j=4gFmLi-welh3b;QUures;tN<%kJ<|qOd|Wh%R?g2;<^f&`fTw3TG}*oe z$SFI6W|6ZA$X}{eY9Lem1RyFG`djf7f2U$WSgU$bSwUgQ`51h^pk2NS-)RUn_b0;8 z9SQ$k^f`m7%a7yC)9bko!r2l|oi2KQw&@y+BsJ@iv#j-5Mk2>bVs6- z{;!J#c?S~rME&5Hn;byh?ckctBgHSykbSI?yIjWmIRxax?PCoU8FA*>g3zDx zA{;96*5t*>bI|h4Rg5qSJzkQOZDO6RfAfs>CRWds+d=x-g~+?ih<{Xj3w+D^*YcRC z{{k!U9~pxG{r`V6>i<`={eLs+|5n)i-}LvtSEQYDgQ1^Uy1pqeQeRXayhK+J&Z_Om z-ckm~-WY%{fzs$zIN{03Va8zKwdfZK>Y&I2kh?a76CR0$9}tfqZR(VZR3!>8z+)z9 z$le*seIzKOGMwe2cmRtH2GG2KSZh41#r_a+ RugFd$0lEiN1Jp<3{|6=dmtz0` literal 0 HcmV?d00001 diff --git a/MPE.jpg b/MPE.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c5044db135b6b37b64104828921d3a0cce6d208e GIT binary patch literal 120162 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 consists of random baysian network part 2 was tested on. +3. to run the script to get the runtime of MAP and MPE for 3 different heuristics, run "python Part2.py" which will dump 2 excel in output folder. + +# Part 3 + +1. run "python use_case.py" + + + + + +# Useful Pointers for Assignment 2 of KR21 ## BIFXML file format The BIFXML file format is meant to provide an easy means of exchanging Bayesian networks. It works with standard XML tags. The detailed description of the format can be found at @@ -88,3 +110,4 @@ Beware that the returned value is always a tuple of (row_number, row_content). ## Networkx methods It is likely, that you will not have to use this package at all. One possible methods that could be useful is `networkx.neighbors(G, var)` which provides a list of all neighbors of the variable 'var' in the graph 'G'. + diff --git a/generate_bn.py b/generate_bn.py new file mode 100644 index 00000000..a811ab19 --- /dev/null +++ b/generate_bn.py @@ -0,0 +1,29 @@ +# import networkx as nx +import numpy as np +from pgmpy.models import BayesianNetwork + + +# Set random seed for reproducibility +np.random.seed(123) + +# Set the range of node numbers to generate networks for +start = 10 +end = 50 +skip = 3 +node_counts = range(start, end+1, skip) + +# Set the number of networks to generate for each node number +n_networks = 1 + +# Set the probability of an edge between any two nodes +edge_prob1 = 0.03 + +# Iterate over the range of node numbers +for n_node in node_counts: + + # Iterate over the number of networks + for i in range(n_networks): + + G = BayesianNetwork.get_random(n_nodes=n_node, edge_prob=edge_prob1, n_states=2) + + G.save(f'testing/Part_2/network_{n_node}.XMLBIF', filetype='XMLBIF') diff --git a/test.py b/test.py index 86671ca8..c71f3e78 100644 --- a/test.py +++ b/test.py @@ -1,73 +1,170 @@ from BNReasoner import BNReasoner from BayesNet import BayesNet import pandas as pd +import networkx as nx +import matplotlib.pyplot as plt +import numpy as np +import warnings +warnings.filterwarnings("ignore") if __name__ == "__main__": print("begin") - net = 'testing/lecture_example.BIFXML' - - #net = 'testing/lecture_example.BIFXML' + # net = 'testing/lecture_example2.BIFXML' + net = 'testing/lecture_example.BIFXML' bn = BayesNet() bn.load_from_bifxml(net) - # bn.draw_structure() bnr = BNReasoner(bn) + Pruning = True + check_d_separation = False + Independence = False + Marginalization = False + MaxingOut = False + FactorMultiplication = False + Ordering_min_degree = False + Ordering_min_fill = False + Elimination = False + Marginal_distribution = False + checkMAP = False + checkMEP = False + ### Test pruning - #outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) + if Pruning: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) + print(outcome) ### D-seperation - #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated - #outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated - - ### Order min-degree - #outcome_min_degree = bnr.min_degree() - #print(outcome_min_degree) + if check_d_separation: + net = 'testing/dog_problem.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated + outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated + print(outcome_d) + + ### Test independence + if Independence: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + Y = {"Winter?"} + X = {"Slippery Road?"} + Z = {} + if bnr.independence(bnr.bn, X,Y,Z): + print(X, "is independent from ", Y, "given ", Z) + else: + print(X, "is not independent from ", Y, "given ", Z) + + ### Test marginalization + if Marginalization: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + X = "Wet Grass?" + Y = BayesNet.get_cpt(bnr.bn,X) + outcome_marg = bnr.sum_out_factors(Y,X) + print(outcome_marg) + + ### Test maxing out + if MaxingOut: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + X = "Wet Grass?" + Y = BayesNet.get_cpt(bnr.bn,X) + outcome_max = bnr.maximise_out(Y,X) + print(outcome_max) + + ### Test factor multiplication + if FactorMultiplication: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_factor = bnr.factor_multiplication(['Rain?', 'Wet Grass?']) + print(outcome_factor) + + ### Test ordering min + if Ordering_min_degree: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_min_degree = bnr.min_degree() + print(outcome_min_degree) + + ### Test ordering min fill + if Ordering_min_fill: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_min_fill = bnr.min_fill() + print(outcome_min_fill) - ### Order min-degree - # outcome_min_fill = bnr.min_fill() - # print(outcome_min_fill) + ### Elimination + if Elimination: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) + print(outcome_elim) + + ### Marginal distribution + if Marginal_distribution: + net = 'testing/lecture_example.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_md = bnr.compute_marginal(['Wet Grass?', 'Slippery Road?'], order=bnr.min_degree()) + print(outcome_md) + ### MAP + if checkMAP: + net = 'testing/lecture_example2.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_map = bnr.MAP(['I', 'J'], pd.Series({'O': True})) + print(outcome_map) - ### Factor Multiplication - # net = 'testing/lecture_example.BIFXML' - # outcome_factor = bnr.factor_multiplication(['Rain?', 'Wet Grass?']) - # print(outcome_factor) ### MPE - # net = 'testing/lecture_example2.BIFXML' - # mpe = bnr.MPE(pd.Series({'J': True, 'O': False})) - # print(mpe) - - - ### MAP - # map = bnr.MAP(['I', 'J'], pd.Series({'O': True})) - # print(map) + if checkMEP: + net = 'testing/lecture_example2.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_mpe = bnr.MPE(pd.Series({'J': True, 'O': False})) + print(outcome_mpe) + # print(outcome) # outcome.draw_structure() - # X = "Wet Grass?" - # Y = BayesNet.get_cpt(bnr.bn,X) - # # f = bnr.multip_factors(Y) - # print(Y) - # outcome = bnr.sum_out_factors(Y,X) #bnr.maximise_out(Y,X) - # print(outcome) + X = "Wet Grass?" + Y = BayesNet.get_cpt(bnr.bn,X) + # f = bnr.multip_factors(Y) + print(Y) + outcome = bnr.sum_out_factors(Y,X) #bnr.maximise_out(Y,X) + print(outcome) ### Elimination - # outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) + outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) #outcome_elim = bnr.elimination(bn.get_cpt('Winter?'), ['Winter?']) # Empty Dataframe - # print(outcome_elim) - - ### Independence - Y = {"Winter?"} - X = {"Slippery Road?"} - Z = {} - if bnr.independence(bnr.bn, X,Y,Z): - print(X, "is independent from ", Y, "given ", Z) - else: - print(X, "is not independent from ", Y, "given ", Z) - - #python3 test.py \ No newline at end of file + print(outcome_elim) + + + #python3 test.py diff --git a/testing/Part_2/network_10.XMLBIF b/testing/Part_2/network_10.XMLBIF new file mode 100644 index 00000000..4682195f --- /dev/null +++ b/testing/Part_2/network_10.XMLBIF @@ -0,0 +1,108 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.4349455206174165 0.5650544793825836
+
+ + 1 + 0.1710485664667887 0.8289514335332113
+
+ + 2 + 0.380084503251582 0.6199154967484181
+
+ + 3 + 0.5259154670781337 0.47408453292186625
+
+ + 4 + 0.6047494329559816 0.39525056704401834
+
+ + 5 + 0.002712385220183117 0.9972876147798169
+
+ + 6 + 0 + 0.24751387019314983 0.7524861298068501 0.16517561565218833 0.8348243843478117
+
+ + 7 + 4 + 0.7295278567303077 0.27047214326969227 0.5206826091288514 0.47931739087114855
+
+ + 8 + 0.8134410866562535 0.18655891334374652
+
+ + 9 + 0.3599871619390577 0.6400128380609423
+
+
+
diff --git a/testing/Part_2/network_12.XMLBIF b/testing/Part_2/network_12.XMLBIF new file mode 100644 index 00000000..d7f2ede0 --- /dev/null +++ b/testing/Part_2/network_12.XMLBIF @@ -0,0 +1,130 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.3214901479417498 0.6785098520582502
+
+ + 1 + 0 + 0.9793060350022791 0.020693964997720887 0.49763572500015885 0.5023642749998412
+
+ + 2 + 0.3299423460590487 0.6700576539409513
+
+ + 3 + 0.27685444908908063 0.7231455509109194
+
+ + 4 + 0.13664285881182187 0.8633571411881782
+
+ + 5 + 0.49602726023044585 0.5039727397695541
+
+ + 6 + 0.14042158326700857 0.8595784167329914
+
+ + 7 + 6 + 0.0451306569224957 0.9548693430775043 0.4492367141842686 0.5507632858157315
+
+ + 8 + 0.17201735914804012 0.8279826408519598
+
+ + 9 + 0.42558508147769747 0.5744149185223026
+
+ + 10 + 0 + 9 + 0.457903146920101 0.5420968530798992 0.8608136373423361 0.13918636265766388 0.4023046596612852 0.5976953403387147 0.9478818729818037 0.052118127018196334
+
+ + 11 + 0.02222477690865484 0.9777752230913451
+
+
+
diff --git a/testing/Part_2/network_14.XMLBIF b/testing/Part_2/network_14.XMLBIF new file mode 100644 index 00000000..0eb4c06d --- /dev/null +++ b/testing/Part_2/network_14.XMLBIF @@ -0,0 +1,148 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.6391540776112048 0.36084592238879526
+
+ + 1 + 0.4838640777799347 0.5161359222200653
+
+ + 2 + 0.752496435201447 0.24750356479855282
+
+ + 3 + 0.36347887926447964 0.6365211207355204
+
+ + 4 + 0.32115764827591586 0.6788423517240842
+
+ + 5 + 0.4541813442190619 0.5458186557809381
+
+ + 6 + 0.6039442635917242 0.3960557364082759
+
+ + 7 + 0.9094212475812189 0.09057875241878126
+
+ + 8 + 0.35815597036478514 0.6418440296352148
+
+ + 9 + 0.4060743431443279 0.5939256568556721
+
+ + 10 + 0.34199688130656875 0.6580031186934312
+
+ + 11 + 8 + 0.1999582748258198 0.8000417251741803 0.7545523666575823 0.2454476333424177
+
+ + 12 + 8 + 0.6771907292196654 0.32280927078033456 0.618968114921538 0.38103188507846203
+
+ + 13 + 0.598435584790387 0.40156441520961306
+
+
+
diff --git a/testing/Part_2/network_16.XMLBIF b/testing/Part_2/network_16.XMLBIF new file mode 100644 index 00000000..e6b0cf5d --- /dev/null +++ b/testing/Part_2/network_16.XMLBIF @@ -0,0 +1,169 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.5297465339299979 0.47025346607000207
+
+ + 1 + 0 + 0.3918757664620914 0.6081242335379087 0.671583784178159 0.328416215821841
+
+ + 2 + 0.6261130375039516 0.3738869624960483
+
+ + 3 + 0.21300930798309178 0.7869906920169082
+
+ + 4 + 0.35584736487797186 0.6441526351220281
+
+ + 5 + 0.5848525986079398 0.4151474013920603
+
+ + 6 + 0.5574305458764298 0.4425694541235702
+
+ + 7 + 0.6136939480451078 0.3863060519548922
+
+ + 8 + 0.17084305142270648 0.8291569485772934
+
+ + 9 + 0.11604626237129015 0.8839537376287099
+
+ + 10 + 5 + 0.37359977716956616 0.6264002228304338 0.2240733130154565 0.7759266869845435
+
+ + 11 + 6 + 0.9647584579958011 0.0352415420041989 0.39605057259970905 0.6039494274002909
+
+ + 12 + 0.4288491029632107 0.5711508970367892
+
+ + 13 + 0.69286858323428 0.30713141676572
+
+ + 14 + 0.29803719484596247 0.7019628051540375
+
+ + 15 + 0.4682553346336004 0.5317446653663995
+
+
+
diff --git a/testing/Part_2/network_18.XMLBIF b/testing/Part_2/network_18.XMLBIF new file mode 100644 index 00000000..6064680f --- /dev/null +++ b/testing/Part_2/network_18.XMLBIF @@ -0,0 +1,189 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.9941750987683369 0.0058249012316631075
+
+ + 1 + 0.08887350841971366 0.9111264915802864
+
+ + 2 + 1 + 0.9395014685652059 0.0604985314347941 0.16372454268295025 0.8362754573170498
+
+ + 3 + 0.42367414745501736 0.5763258525449826
+
+ + 4 + 0.7151548477218808 0.2848451522781193
+
+ + 5 + 0.12927491582753298 0.8707250841724671
+
+ + 6 + 0.8723650817923445 0.12763491820765555
+
+ + 7 + 0.12968008711177692 0.8703199128882231
+
+ + 8 + 0.42361169744016086 0.5763883025598392
+
+ + 9 + 0.7153944614305361 0.2846055385694639
+
+ + 10 + 0.2482784249282073 0.7517215750717927
+
+ + 11 + 0.9672815785428696 0.03271842145713044
+
+ + 12 + 0.6345115001562573 0.3654884998437426
+
+ + 13 + 0.4740023740006389 0.5259976259993612
+
+ + 14 + 5 + 0.17664394504113556 0.8233560549588644 0.48984141503876216 0.5101585849612378
+
+ + 15 + 0.04894284974071541 0.9510571502592846
+
+ + 16 + 0.7311724353266932 0.26882756467330676
+
+ + 17 + 13 + 0.5960658124639883 0.40393418753601174 0.9380067159270794 0.06199328407292063
+
+
+
diff --git a/testing/Part_2/network_20.XMLBIF b/testing/Part_2/network_20.XMLBIF new file mode 100644 index 00000000..9c761310 --- /dev/null +++ b/testing/Part_2/network_20.XMLBIF @@ -0,0 +1,214 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.5798761221226439 0.420123877877356
+
+ + 1 + 0.07606955200564293 0.9239304479943571
+
+ + 2 + 0.790698303695997 0.209301696304003
+
+ + 3 + 2 + 0.08243965046968499 0.917560349530315 0.4184183157557029 0.581581684244297
+
+ + 4 + 0.4405636887386731 0.559436311261327
+
+ + 5 + 2 + 4 + 0.48858776279309873 0.5114122372069013 0.7377887963475378 0.26221120365246214 0.9222465464126872 0.07775345358731278 0.9775775523149264 0.022422447685073652
+
+ + 6 + 0.4744059964126312 0.5255940035873689
+
+ + 7 + 0.19538303889164674 0.8046169611083532
+
+ + 8 + 0 + 0.6567331913855603 0.3432668086144397 0.5669676695550846 0.43303233044491535
+
+ + 9 + 4 + 0.3304575924609459 0.669542407539054 0.9335096358083215 0.0664903641916785
+
+ + 10 + 0.5587932196679424 0.4412067803320576
+
+ + 11 + 0.6411958146797949 0.3588041853202052
+
+ + 12 + 0.34138863753701704 0.658611362462983
+
+ + 13 + 0.3111816229090857 0.6888183770909143
+
+ + 14 + 0.8625584457799806 0.13744155422001933
+
+ + 15 + 0.4159300802770767 0.5840699197229233
+
+ + 16 + 3 + 0.25175226285652397 0.748247737143476 0.6180212354396711 0.38197876456032887
+
+ + 17 + 16 + 0.6009880381135172 0.39901196188648297 0.8612558281607495 0.1387441718392505
+
+ + 18 + 0.46360813284435204 0.5363918671556479
+
+ + 19 + 0 + 0.46394250224765343 0.5360574977523467 0.16398524835980258 0.8360147516401975
+
+
+
diff --git a/testing/Part_2/network_22.XMLBIF b/testing/Part_2/network_22.XMLBIF new file mode 100644 index 00000000..909ce44c --- /dev/null +++ b/testing/Part_2/network_22.XMLBIF @@ -0,0 +1,234 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.3892336649294168 0.6107663350705833
+
+ + 1 + 0.44605978401460483 0.5539402159853952
+
+ + 2 + 0.16687832388296 0.83312167611704
+
+ + 3 + 0.6526750267554237 0.3473249732445764
+
+ + 4 + 0.2416944899305309 0.7583055100694692
+
+ + 5 + 0.5871208972277241 0.412879102772276
+
+ + 6 + 0.6601023479689504 0.33989765203104966
+
+ + 7 + 0.3040976636941735 0.6959023363058265
+
+ + 8 + 2 + 0.9350200022759331 0.06497999772406697 0.8904159257020209 0.10958407429797923
+
+ + 9 + 0.4388041497472942 0.5611958502527059
+
+ + 10 + 0.9646771528304883 0.035322847169511715
+
+ + 11 + 0.583010539014032 0.41698946098596806
+
+ + 12 + 0.08655409819730109 0.9134459018026989
+
+ + 13 + 0.35980481425040306 0.640195185749597
+
+ + 14 + 12 + 0.47608653912372106 0.5239134608762789 0.3394709027513823 0.6605290972486177
+
+ + 15 + 0.5973585304830139 0.40264146951698615
+
+ + 16 + 0 + 0.5275527265994849 0.4724472734005151 0.4053471638123696 0.5946528361876304
+
+ + 17 + 0.5985311998607626 0.40146880013923736
+
+ + 18 + 11 + 0.4439973379768275 0.5560026620231725 0.567168936226603 0.43283106377339703
+
+ + 19 + 6 + 12 + 0.393133657312434 0.6068663426875661 0.260002433362573 0.739997566637427 0.37938692264341173 0.6206130773565882 0.3589670676285248 0.6410329323714752
+
+ + 20 + 11 + 0.20101872435005178 0.7989812756499483 0.7283500363633278 0.27164996363667215
+
+ + 21 + 0 + 0.31055837019119475 0.6894416298088053 0.6420101354370041 0.3579898645629959
+
+
+
diff --git a/testing/Part_2/network_24.XMLBIF b/testing/Part_2/network_24.XMLBIF new file mode 100644 index 00000000..359aafe1 --- /dev/null +++ b/testing/Part_2/network_24.XMLBIF @@ -0,0 +1,255 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.837887716110821 0.1621122838891791
+
+ + 1 + 0.47992504835102173 0.5200749516489782
+
+ + 2 + 0.5040718698387632 0.49592813016123677
+
+ + 3 + 0.3837646504714514 0.6162353495285486
+
+ + 4 + 0.3798811333525368 0.6201188666474631
+
+ + 5 + 0.8446198265594693 0.1553801734405307
+
+ + 6 + 0.541778822294822 0.45822117770517806
+
+ + 7 + 0.816103692502395 0.18389630749760502
+
+ + 8 + 5 + 0.5534693750766887 0.4465306249233114 0.1803468628352105 0.8196531371647894
+
+ + 9 + 0.16509812378552818 0.8349018762144718
+
+ + 10 + 9 + 0.6030405144513664 0.3969594855486337 0.7049605237515182 0.2950394762484818
+
+ + 11 + 0.4104881826393078 0.5895118173606922
+
+ + 12 + 0.32303890665749446 0.6769610933425055
+
+ + 13 + 3 + 11 + 0.2574097873453695 0.7425902126546304 0.7281535757694488 0.27184642423055116 0.40209922674481935 0.5979007732551807 0.5528332771358562 0.44716672286414383
+
+ + 14 + 0.6400611696816814 0.3599388303183186
+
+ + 15 + 8 + 0.7645031641791943 0.23549683582080572 0.5402015529149293 0.4597984470850707
+
+ + 16 + 0.6928204375245968 0.30717956247540323
+
+ + 17 + 0.9215666131889082 0.07843338681109178
+
+ + 18 + 0.48852113970073946 0.5114788602992605
+
+ + 19 + 0.6863499326588793 0.3136500673411206
+
+ + 20 + 0.4722583572477778 0.5277416427522222
+
+ + 21 + 14 + 0.4810185509070517 0.5189814490929483 0.3059660396850662 0.6940339603149338
+
+ + 22 + 4 + 19 + 0.24542205878646295 0.7545779412135372 0.8093825042747947 0.19061749572520534 0.3442862011896508 0.6557137988103492 0.21674393913822862 0.7832560608617714
+
+ + 23 + 2 + 0.4438008337071333 0.5561991662928668 0.6046821859223391 0.3953178140776608
+
+
+
diff --git a/testing/Part_2/network_26.XMLBIF b/testing/Part_2/network_26.XMLBIF new file mode 100644 index 00000000..566b17ea --- /dev/null +++ b/testing/Part_2/network_26.XMLBIF @@ -0,0 +1,272 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.4994866781633081 0.5005133218366918
+
+ + 1 + 0.6694968600577342 0.33050313994226577
+
+ + 2 + 0.9057565021356545 0.0942434978643454
+
+ + 3 + 0.3620053194676714 0.6379946805323286
+
+ + 4 + 0.61893000197716 0.38106999802284003
+
+ + 5 + 0.4912268978880608 0.5087731021119393
+
+ + 6 + 0.4880110981745616 0.5119889018254383
+
+ + 7 + 0.747917812125556 0.25208218787444414
+
+ + 8 + 0.8425520672639683 0.15744793273603175
+
+ + 9 + 0.0548714396677681 0.9451285603322319
+
+ + 10 + 0.6099402093379771 0.3900597906620229
+
+ + 11 + 7 + 0.4698889856450053 0.5301110143549947 0.6585126309967532 0.3414873690032469
+
+ + 12 + 0.9644450220876079 0.035554977912392094
+
+ + 13 + 0.6238446570580117 0.37615534294198827
+
+ + 14 + 0.38874736884611916 0.6112526311538808
+
+ + 15 + 0.7507727250090476 0.24922727499095249
+
+ + 16 + 0.1407979045170728 0.8592020954829271
+
+ + 17 + 0.45311799954815596 0.5468820004518441
+
+ + 18 + 1 + 15 + 0.6402832180088107 0.3597167819911893 0.4592216614127824 0.5407783385872176 0.2512443601672139 0.7487556398327861 0.09651356917813077 0.9034864308218692
+
+ + 19 + 0.48695639616680725 0.5130436038331927
+
+ + 20 + 6 + 0.2109449087086231 0.789055091291377 0.6916424424620761 0.30835755753792393
+
+ + 21 + 0.4629096546321997 0.5370903453678003
+
+ + 22 + 0.5022313049026068 0.49776869509739313
+
+ + 23 + 8 + 0.45080213829027516 0.5491978617097248 0.34322307058718754 0.6567769294128125
+
+ + 24 + 9 + 0.9777886182264409 0.022211381773559052 0.2293760572103606 0.7706239427896394
+
+ + 25 + 0.6131768656986143 0.38682313430138576
+
+
+
diff --git a/testing/Part_2/network_28.XMLBIF b/testing/Part_2/network_28.XMLBIF new file mode 100644 index 00000000..331e427c --- /dev/null +++ b/testing/Part_2/network_28.XMLBIF @@ -0,0 +1,297 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.1712979922106368 0.8287020077893633
+
+ + 1 + 0.25718080224274864 0.7428191977572514
+
+ + 2 + 0.8688645223451646 0.13113547765483533
+
+ + 3 + 0.17963864436035382 0.8203613556396461
+
+ + 4 + 0.39544403017177926 0.6045559698282207
+
+ + 5 + 0.4268789995416128 0.5731210004583872
+
+ + 6 + 0.6569685648923269 0.3430314351076731
+
+ + 7 + 0.11384774441709171 0.8861522555829083
+
+ + 8 + 0.2867270393603852 0.7132729606396149
+
+ + 9 + 0.5605014197181934 0.4394985802818066
+
+ + 10 + 0.5815261283100926 0.41847387168990735
+
+ + 11 + 0.3148269696597371 0.6851730303402629
+
+ + 12 + 0.4035519993194107 0.5964480006805895
+
+ + 13 + 0.9890171386396505 0.01098286136034959
+
+ + 14 + 0.5108869314282616 0.4891130685717384
+
+ + 15 + 0.3404258870100451 0.6595741129899549
+
+ + 16 + 0.25549302690125625 0.7445069730987438
+
+ + 17 + 11 + 0.438536881666975 0.561463118333025 0.3867152817959186 0.6132847182040815
+
+ + 18 + 0.03832692621343529 0.9616730737865647
+
+ + 19 + 10 + 0.4052998281675743 0.5947001718324257 0.7014692559380334 0.29853074406196667
+
+ + 20 + 0.06209441609580767 0.9379055839041923
+
+ + 21 + 8 + 19 + 0.34449787067446686 0.6555021293255333 0.5748253695631024 0.42517463043689746 0.38769883221416934 0.6123011677858307 0.42477394363108684 0.5752260563689132
+
+ + 22 + 19 + 20 + 0.9686419619222726 0.03135803807772741 0.7511848017412626 0.2488151982587375 0.5403955654240307 0.45960443457596933 0.727088996183004 0.2729110038169959
+
+ + 23 + 3 + 20 + 0.3431199591004866 0.6568800408995134 0.2973723716220402 0.7026276283779598 0.7796037718390144 0.22039622816098553 0.43925590439229917 0.5607440956077008
+
+ + 24 + 16 + 0.8661058035557999 0.13389419644420014 0.20013986327588548 0.7998601367241145
+
+ + 25 + 0.6839847221900625 0.3160152778099375
+
+ + 26 + 9 + 17 + 0.2635720305168574 0.7364279694831426 0.7536160581659149 0.2463839418340851 0.18590082291695265 0.8140991770830474 0.019317741117807846 0.9806822588821922
+
+ + 27 + 0.8204030011641453 0.17959699883585462
+
+
+
diff --git a/testing/Part_2/network_30.XMLBIF b/testing/Part_2/network_30.XMLBIF new file mode 100644 index 00000000..2adbe171 --- /dev/null +++ b/testing/Part_2/network_30.XMLBIF @@ -0,0 +1,320 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.37022780433206726 0.6297721956679327
+
+ + 1 + 0.5284925110383819 0.47150748896161815
+
+ + 2 + 0.6839964179208604 0.3160035820791396
+
+ + 3 + 0.5256806233596582 0.47431937664034185
+
+ + 4 + 0.8770269601404832 0.12297303985951678
+
+ + 5 + 0.3507079634984438 0.6492920365015561
+
+ + 6 + 0.9366600530929148 0.0633399469070852
+
+ + 7 + 0.6606616334552341 0.3393383665447659
+
+ + 8 + 5 + 0.5095789598929462 0.4904210401070538 0.6184988604225337 0.3815011395774664
+
+ + 9 + 0.19881649775075602 0.801183502249244
+
+ + 10 + 0.7042071849998817 0.29579281500011834
+
+ + 11 + 3 + 0.5440708149885336 0.4559291850114664 0.21138739001433013 0.7886126099856698
+
+ + 12 + 0.5016343476193725 0.49836565238062747
+
+ + 13 + 5 + 0.5028176763866334 0.49718232361336645 0.47153840825010895 0.528461591749891
+
+ + 14 + 0.5190078761825277 0.48099212381747225
+
+ + 15 + 14 + 0.6393161509878702 0.36068384901212974 0.40548419834825705 0.5945158016517431
+
+ + 16 + 0.6367484468449676 0.36325155315503227
+
+ + 17 + 0.8107396382551288 0.18926036174487118
+
+ + 18 + 0.5110393677874012 0.4889606322125987
+
+ + 19 + 8 + 10 + 0.28079297270660336 0.7192070272933967 0.4008720560883833 0.5991279439116166 0.34809317255500166 0.6519068274449984 0.40594238671274513 0.5940576132872548
+
+ + 20 + 0.3773420918791358 0.6226579081208642
+
+ + 21 + 1 + 0.39147774667113777 0.6085222533288622 0.7102319219421191 0.2897680780578809
+
+ + 22 + 4 + 0.44762623856192474 0.5523737614380753 0.42213775524694125 0.5778622447530587
+
+ + 23 + 0 + 6 + 0.6192372644779515 0.3807627355220485 0.38525700071446756 0.6147429992855324 0.4033927866945057 0.5966072133054944 0.466678119618944 0.533321880381056
+
+ + 24 + 0.28257613177638985 0.71742386822361
+
+ + 25 + 0.534373502616407 0.46562649738359296
+
+ + 26 + 21 + 0.3699812935919531 0.6300187064080469 0.03938862482429999 0.9606113751757
+
+ + 27 + 12 + 25 + 0.1588859906721131 0.8411140093278869 0.40708077159107375 0.5929192284089263 0.5011382062500785 0.49886179374992146 0.19461565304127093 0.8053843469587291
+
+ + 28 + 0.3290197153889425 0.6709802846110574
+
+ + 29 + 17 + 0.6711887098059346 0.32881129019406546 0.4966067725713562 0.5033932274286439
+
+
+
diff --git a/testing/Part_2/network_32.XMLBIF b/testing/Part_2/network_32.XMLBIF new file mode 100644 index 00000000..05a52b78 --- /dev/null +++ b/testing/Part_2/network_32.XMLBIF @@ -0,0 +1,338 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.02167897079810445 0.9783210292018956
+
+ + 1 + 0.9249007215267574 0.07509927847324263
+
+ + 2 + 0.558892509413249 0.441107490586751
+
+ + 3 + 0.06589098026618029 0.9341090197338197
+
+ + 4 + 0.013582973945594948 0.9864170260544051
+
+ + 5 + 0.5986008264251698 0.40139917357483024
+
+ + 6 + 0.7075104441227874 0.2924895558772126
+
+ + 7 + 0.44142987500431524 0.5585701249956848
+
+ + 8 + 0.5187316472608485 0.4812683527391514
+
+ + 9 + 0.40677911828262076 0.5932208817173792
+
+ + 10 + 0.27537408516950873 0.7246259148304912
+
+ + 11 + 0.6694038681734233 0.3305961318265766
+
+ + 12 + 1 + 7 + 0.5113110365553325 0.4886889634446675 0.7037258819728405 0.29627411802715947 0.40445199249894237 0.5955480075010577 0.9536028946246696 0.04639710537533033
+
+ + 13 + 0.24255739935893644 0.7574426006410635
+
+ + 14 + 6 + 0.60049286983148 0.39950713016852 0.8145834342264779 0.18541656577352203
+
+ + 15 + 0.9544349175065162 0.0455650824934838
+
+ + 16 + 0.3055678022592247 0.6944321977407754
+
+ + 17 + 16 + 0.37235113695383587 0.6276488630461641 0.6844521004445672 0.3155478995554328
+
+ + 18 + 15 + 0.21452783832337183 0.7854721616766281 0.4908100338375432 0.5091899661624568
+
+ + 19 + 0.4979516170612241 0.502048382938776
+
+ + 20 + 0.6913747720136962 0.3086252279863037
+
+ + 21 + 10 + 0.40840850768447473 0.5915914923155253 0.2691970737989794 0.7308029262010206
+
+ + 22 + 0.6445437722121814 0.35545622778781866
+
+ + 23 + 0.04175114114118891 0.9582488588588111
+
+ + 24 + 0.41811086997476427 0.5818891300252357
+
+ + 25 + 0.32153507343619114 0.6784649265638089
+
+ + 26 + 0.22833161181518044 0.7716683881848194
+
+ + 27 + 0.23288132142873366 0.7671186785712664
+
+ + 28 + 5 + 8 + 21 + 19 + 0.8103393085564536 0.1896606914435464 0.3902431835548887 0.6097568164451113 0.5646043291712478 0.4353956708287522 0.6183927413213811 0.3816072586786189 0.14379507043765374 0.8562049295623463 0.16831669030544294 0.8316833096945571 0.7793812632449497 0.2206187367550504 0.46163886286557765 0.5383611371344224 0.4799079364354748 0.5200920635645252 0.707984089062958 0.2920159109370421 0.8604916026811354 0.13950839731886452 0.25304716808150723 0.7469528319184927 0.055704429510710314 0.9442955704892897 0.952268628142588 0.04773137185741202 0.8067527363126202 0.19324726368737977 0.4559048336033172 0.5440951663966828
+
+ + 29 + 2 + 0.42774236574719393 0.5722576342528062 0.6418150895332938 0.3581849104667062
+
+ + 30 + 11 + 0.8440353576646382 0.15596464233536186 0.5805652954403676 0.41943470455963233
+
+ + 31 + 0.12217022347392907 0.877829776526071
+
+
+
diff --git a/testing/Part_2/network_34.XMLBIF b/testing/Part_2/network_34.XMLBIF new file mode 100644 index 00000000..b43309ac --- /dev/null +++ b/testing/Part_2/network_34.XMLBIF @@ -0,0 +1,364 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.3660387046308733 0.6339612953691267
+
+ + 1 + 0.5084774587571477 0.4915225412428524
+
+ + 2 + 0.9985728152882067 0.001427184711793218
+
+ + 3 + 0.09563068697706481 0.9043693130229352
+
+ + 4 + 0.316487061378661 0.683512938621339
+
+ + 5 + 0 + 0.3949263849732558 0.6050736150267442 0.8248289574963703 0.17517104250362972
+
+ + 6 + 0 + 0.3397755269409813 0.6602244730590188 0.03770511839432872 0.9622948816056712
+
+ + 7 + 0.7055354767162159 0.29446452328378414
+
+ + 8 + 0.22597788956337844 0.7740221104366215
+
+ + 9 + 0.8766964403212231 0.12330355967877707
+
+ + 10 + 0.44121903426804204 0.5587809657319579
+
+ + 11 + 0.7260197991349034 0.27398020086509645
+
+ + 12 + 0.7120650796587669 0.2879349203412332
+
+ + 13 + 4 + 0.3719338795357831 0.6280661204642168 0.6685749308911256 0.33142506910887437
+
+ + 14 + 11 + 0.7427761479965099 0.25722385200349007 0.3758399324107202 0.6241600675892798
+
+ + 15 + 0.11577959288009874 0.8842204071199012
+
+ + 16 + 4 + 0.5228158270368976 0.4771841729631024 0.03561764465689719 0.9643823553431028
+
+ + 17 + 0.11127235715217645 0.8887276428478236
+
+ + 18 + 6 + 0.37558075156927345 0.6244192484307266 0.5743966708606942 0.42560332913930576
+
+ + 19 + 0.7592322896005379 0.2407677103994622
+
+ + 20 + 0.4705997295239286 0.5294002704760714
+
+ + 21 + 6 + 10 + 19 + 0.4649216005501474 0.5350783994498526 0.8791835492013962 0.12081645079860381 0.7376569060558374 0.26234309394416266 0.315132938131037 0.6848670618689631 0.5890565505855389 0.41094344941446115 0.9258336966730564 0.07416630332694359 0.9665803347300508 0.0334196652699492 0.8856535761491816 0.11434642385081838
+
+ + 22 + 0.5871177536994843 0.41288224630051573
+
+ + 23 + 0.3945499412767983 0.6054500587232017
+
+ + 24 + 0 + 16 + 0.7678999507467994 0.23210004925320057 0.29870611273850706 0.7012938872614929 0.23863962916078335 0.7613603708392167 0.4446288805149847 0.5553711194850153
+
+ + 25 + 0.010460849684903949 0.9895391503150961
+
+ + 26 + 0.45823305760724686 0.5417669423927531
+
+ + 27 + 13 + 0.41330526932593353 0.5866947306740664 0.13040922416391026 0.8695907758360897
+
+ + 28 + 14 + 0.3211989568829569 0.678801043117043 0.7267375976797403 0.27326240232025967
+
+ + 29 + 0.3763103151425898 0.6236896848574103
+
+ + 30 + 22 + 0.2914119224325085 0.7085880775674914 0.9818263031482765 0.01817369685172352
+
+ + 31 + 10 + 0.321562434120846 0.678437565879154 0.6571044472639909 0.3428955527360092
+
+ + 32 + 0.5200014499619645 0.47999855003803554
+
+ + 33 + 4 + 13 + 22 + 0.30767030880354757 0.6923296911964525 0.20323636067241824 0.7967636393275818 0.053674576067609885 0.9463254239323902 0.4713502186025894 0.5286497813974106 0.6819745115531975 0.3180254884468025 0.4129571949491559 0.5870428050508442 0.4714573052435968 0.5285426947564033 0.10001397438452599 0.8999860256154741
+
+
+
diff --git a/testing/Part_2/network_36.XMLBIF b/testing/Part_2/network_36.XMLBIF new file mode 100644 index 00000000..429aa8b3 --- /dev/null +++ b/testing/Part_2/network_36.XMLBIF @@ -0,0 +1,393 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.3690806102127743 0.6309193897872256
+
+ + 1 + 0.4539949773034237 0.5460050226965762
+
+ + 2 + 0.5826533278766639 0.4173466721233361
+
+ + 3 + 0 + 0.6337204989444623 0.3662795010555377 0.4250159655973043 0.5749840344026957
+
+ + 4 + 3 + 0.6710425347875858 0.32895746521241437 0.4646266317098663 0.5353733682901337
+
+ + 5 + 0.28017879796537704 0.7198212020346229
+
+ + 6 + 0.8623269524278474 0.13767304757215257
+
+ + 7 + 0 + 0.4165259848182047 0.5834740151817953 0.5917349953585708 0.4082650046414292
+
+ + 8 + 0.5980144857120469 0.4019855142879531
+
+ + 9 + 6 + 0.9735950682555796 0.02640493174442033 0.47387341251351217 0.5261265874864879
+
+ + 10 + 0.833643997272085 0.16635600272791498
+
+ + 11 + 0.45476847177309526 0.5452315282269047
+
+ + 12 + 9 + 0.27640148501197076 0.7235985149880293 0.474248282002746 0.5257517179972541
+
+ + 13 + 0.46992194404858234 0.5300780559514178
+
+ + 14 + 0 + 0.34626192067917616 0.6537380793208237 0.47838171160466014 0.5216182883953399
+
+ + 15 + 0 + 8 + 0.7076489083950014 0.2923510916049986 0.6976363398084844 0.30236366019151556 0.5223441761802022 0.4776558238197977 0.4685859794273757 0.5314140205726243
+
+ + 16 + 1 + 8 + 0.29335808189785073 0.7066419181021492 0.32979448727360317 0.670205512726397 0.428899651641259 0.571100348358741 0.8210278169682036 0.17897218303179632
+
+ + 17 + 7 + 0.47130676449772785 0.5286932355022721 0.33440557760933226 0.6655944223906677
+
+ + 18 + 0.9289219426714705 0.07107805732852947
+
+ + 19 + 0.07323901544045028 0.9267609845595497
+
+ + 20 + 0.790159787184789 0.20984021281521117
+
+ + 21 + 17 + 10 + 0.4641286774060253 0.5358713225939747 0.9323694493030188 0.06763055069698122 0.10215998797867934 0.8978400120213206 0.18988414220886768 0.8101158577911324
+
+ + 22 + 14 + 0.7137794606677764 0.2862205393322235 0.39282310456920944 0.6071768954307905
+
+ + 23 + 3 + 16 + 0.3626751714360977 0.6373248285639024 0.40071627833546763 0.5992837216645324 0.2899701687412195 0.7100298312587805 0.5863415041307977 0.41365849586920234
+
+ + 24 + 0.527883917907438 0.47211608209256195
+
+ + 25 + 19 + 0.6494002742990166 0.35059972570098336 0.698359780921186 0.30164021907881394
+
+ + 26 + 3 + 0.5619534152907093 0.43804658470929064 0.8739849489622131 0.12601505103778682
+
+ + 27 + 4 + 0.3822028395113094 0.6177971604886906 0.3575343177514513 0.6424656822485487
+
+ + 28 + 0.4662823135957536 0.5337176864042464
+
+ + 29 + 25 + 0.23931481364593638 0.7606851863540637 0.4810258457040042 0.5189741542959958
+
+ + 30 + 0.6199397332075044 0.3800602667924956
+
+ + 31 + 29 + 0.9024429588604564 0.09755704113954348 0.4699722521517334 0.5300277478482667
+
+ + 32 + 22 + 0.07989022660306287 0.9201097733969371 0.25216582896154077 0.7478341710384593
+
+ + 33 + 10 + 0.6950102081524918 0.3049897918475083 0.5156111008123833 0.48438889918761674
+
+ + 34 + 2 + 30 + 0.44059532604342655 0.5594046739565735 0.17161721010938094 0.8283827898906191 0.18736741587341274 0.8126325841265872 0.20415722655973492 0.7958427734402651
+
+ + 35 + 8 + 11 + 0.7105314646672202 0.2894685353327799 0.33449351472793465 0.6655064852720652 0.601093990845479 0.39890600915452107 0.4365175380166408 0.5634824619833593
+
+
+
diff --git a/testing/Part_2/network_38.XMLBIF b/testing/Part_2/network_38.XMLBIF new file mode 100644 index 00000000..b01c888a --- /dev/null +++ b/testing/Part_2/network_38.XMLBIF @@ -0,0 +1,409 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.6930653027512272 0.3069346972487727
+
+ + 1 + 0.7461161866311955 0.25388381336880456
+
+ + 2 + 0.41303205646724933 0.5869679435327507
+
+ + 3 + 0.3793019625042375 0.6206980374957626
+
+ + 4 + 0.19125765554114088 0.8087423444588592
+
+ + 5 + 0.509644332003952 0.490355667996048
+
+ + 6 + 0.907308537054738 0.09269146294526201
+
+ + 7 + 0.7853186502389204 0.21468134976107958
+
+ + 8 + 0.5602089385898684 0.4397910614101316
+
+ + 9 + 0.26271606795176883 0.7372839320482312
+
+ + 10 + 0.4685182046635435 0.5314817953364566
+
+ + 11 + 0.594370405076979 0.4056295949230211
+
+ + 12 + 0.334668365600021 0.6653316343999791
+
+ + 13 + 0.4891328949070992 0.5108671050929008
+
+ + 14 + 5 + 0.8231209865456666 0.17687901345433352 0.18909959222698705 0.810900407773013
+
+ + 15 + 12 + 0.7572309471826486 0.24276905281735137 0.36603419169239193 0.6339658083076081
+
+ + 16 + 14 + 0.42513018159486893 0.5748698184051311 0.453123399062073 0.5468766009379271
+
+ + 17 + 0 + 0.4780329641931054 0.5219670358068946 0.4999816759144466 0.5000183240855534
+
+ + 18 + 10 + 15 + 0.608294095832291 0.39170590416770906 0.22851093168242656 0.7714890683175735 0.6235150956723833 0.3764849043276167 0.7706263283293585 0.2293736716706415
+
+ + 19 + 18 + 0.5259663077795875 0.47403369222041253 0.7920226521638017 0.20797734783619828
+
+ + 20 + 7 + 0.4758870188241655 0.5241129811758345 0.24596140674746952 0.7540385932525304
+
+ + 21 + 0.6227883356057912 0.3772116643942088
+
+ + 22 + 1 + 0.7300613630276527 0.26993863697234743 0.4745078031578788 0.5254921968421211
+
+ + 23 + 13 + 0.38020614369438177 0.6197938563056183 0.4966850737982605 0.5033149262017397
+
+ + 24 + 0.6046859776141696 0.39531402238583024
+
+ + 25 + 1 + 0.605473530702952 0.3945264692970481 0.397136978821438 0.6028630211785618
+
+ + 26 + 9 + 0.693287636601619 0.30671236339838104 0.8318980824553344 0.16810191754466564
+
+ + 27 + 0.26004383076307175 0.7399561692369282
+
+ + 28 + 19 + 0.009404094446253045 0.990595905553747 0.09673113438017314 0.9032688656198269
+
+ + 29 + 25 + 0.9956544864422333 0.004345513557766741 0.09962060529700303 0.900379394702997
+
+ + 30 + 0.1257933871369424 0.8742066128630577
+
+ + 31 + 0.48617784145667226 0.5138221585433278
+
+ + 32 + 5 + 16 + 0.5553498839063913 0.44465011609360866 0.7869259559523049 0.21307404404769514 0.7965771343721647 0.20342286562783535 0.40109853176857124 0.5989014682314288
+
+ + 33 + 0 + 0.42883911292888033 0.5711608870711197 0.731188708889643 0.26881129111035695
+
+ + 34 + 20 + 0.18870749552934452 0.8112925044706555 0.16424619043338895 0.835753809566611
+
+ + 35 + 8 + 0.6482464769922305 0.3517535230077695 0.6744403116082494 0.32555968839175065
+
+ + 36 + 17 + 20 + 35 + 9 + 0.7687868794732525 0.23121312052674742 0.5891805763684916 0.41081942363150836 0.7666190067227111 0.23338099327728895 0.9376669378571346 0.062333062142865346 0.7196690043762394 0.2803309956237606 0.7935414374076022 0.20645856259239784 0.7836280176367324 0.2163719823632676 0.5653091114679935 0.4346908885320065 0.7781835816652668 0.2218164183347332 0.210595036719187 0.7894049632808131 0.812716730558145 0.18728326944185503 0.25551393305750764 0.7444860669424923 0.7115305591962845 0.2884694408037156 0.3517296035469178 0.6482703964530822 0.43612367583305645 0.5638763241669436 0.5743307792723561 0.42566922072764396
+
+ + 37 + 0.26613342205501256 0.7338665779449874
+
+
+
diff --git a/testing/Part_2/network_40.XMLBIF b/testing/Part_2/network_40.XMLBIF new file mode 100644 index 00000000..d69d1717 --- /dev/null +++ b/testing/Part_2/network_40.XMLBIF @@ -0,0 +1,431 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.45361388718484685 0.546386112815153
+
+ + 1 + 0.46849526170326367 0.5315047382967364
+
+ + 2 + 0.0720821806952355 0.9279178193047645
+
+ + 3 + 1 + 0.637334579854177 0.36266542014582304 0.1329636984363169 0.8670363015636832
+
+ + 4 + 0.34480846471970084 0.655191535280299
+
+ + 5 + 0.783201571109171 0.21679842889082898
+
+ + 6 + 0.4349667911604285 0.5650332088395714
+
+ + 7 + 0.3712239965416617 0.6287760034583383
+
+ + 8 + 7 + 0.6905322302295088 0.3094677697704912 0.48311147909522245 0.5168885209047774
+
+ + 9 + 0.15078932055336883 0.8492106794466312
+
+ + 10 + 9 + 0.35504922267616434 0.6449507773238355 0.7090400768820383 0.2909599231179617
+
+ + 11 + 6 + 0.018668747884397055 0.9813312521156029 0.671261883332537 0.328738116667463
+
+ + 12 + 11 + 0.3815280229776423 0.6184719770223578 0.820655130048488 0.17934486995151197
+
+ + 13 + 0.5211465290759837 0.47885347092401637
+
+ + 14 + 0.44423333451667735 0.5557666654833227
+
+ + 15 + 0 + 1 + 0.40771396960156625 0.5922860303984336 0.4882914574044187 0.5117085425955812 0.5122121572540923 0.48778784274590775 0.5400810308255132 0.4599189691744867
+
+ + 16 + 0.6541264674372815 0.34587353256271847
+
+ + 17 + 0.6866229554441139 0.31337704455588605
+
+ + 18 + 0.03274102892552781 0.9672589710744722
+
+ + 19 + 0.4957907201683973 0.5042092798316027
+
+ + 20 + 0.47262385094453857 0.5273761490554615
+
+ + 21 + 0.5108012516162889 0.48919874838371125
+
+ + 22 + 6 + 0.5527915158247059 0.44720848417529424 0.06430974436198589 0.9356902556380141
+
+ + 23 + 0.28481553319972613 0.7151844668002738
+
+ + 24 + 17 + 0.9451307543240944 0.05486924567590555 0.39721340346088985 0.60278659653911
+
+ + 25 + 0.3276453077129497 0.6723546922870502
+
+ + 26 + 0.43047511770359553 0.5695248822964044
+
+ + 27 + 13 + 14 + 18 + 0.6845665711387938 0.3154334288612061 0.7702534083393809 0.22974659166061903 0.46006941056108597 0.539930589438914 0.32812728751438236 0.6718727124856176 0.3583942865747686 0.6416057134252314 0.9757801420959639 0.02421985790403618 0.4677518441877553 0.5322481558122447 0.7084449285539006 0.2915550714460995
+
+ + 28 + 18 + 21 + 0.7088941919445335 0.29110580805546643 0.5820958524966677 0.4179041475033323 0.5596366384734748 0.44036336152652517 0.45465850485126036 0.5453414951487395
+
+ + 29 + 14 + 18 + 0.07161263861265511 0.9283873613873448 0.44066823031031327 0.5593317696896868 0.33478754225006957 0.6652124577499304 0.50105877612141 0.49894122387859
+
+ + 30 + 8 + 0.790655784156727 0.209344215843273 0.7815331687530936 0.21846683124690638
+
+ + 31 + 17 + 0.21581391308439504 0.784186086915605 0.4774424596700585 0.5225575403299415
+
+ + 32 + 0.13253378125069837 0.8674662187493016
+
+ + 33 + 0.13693181559318238 0.8630681844068178
+
+ + 34 + 0.5201885017034913 0.4798114982965086
+
+ + 35 + 0.6619189538782272 0.3380810461217728
+
+ + 36 + 17 + 33 + 0.3360353903872661 0.6639646096127338 0.671633742190619 0.32836625780938095 0.4107518842451576 0.5892481157548424 0.43996103036260553 0.5600389696373945
+
+ + 37 + 6 + 17 + 0.4994552564043033 0.5005447435956967 0.6391998747394392 0.3608001252605609 0.49891494700393935 0.5010850529960605 0.32618263970917316 0.6738173602908268
+
+ + 38 + 0.7527922574463668 0.24720774255363315
+
+ + 39 + 6 + 11 + 9 + 0.7611241826245911 0.23887581737540883 0.2656623625853285 0.7343376374146715 0.8649457250753629 0.13505427492463704 0.5631257681664203 0.4368742318335796 0.35317522193181844 0.6468247780681815 0.29399044048466466 0.7060095595153354 0.49890930876878103 0.501090691231219 0.5819678483836712 0.41803215161632873
+
+
+
diff --git a/testing/Part_2/network_42.XMLBIF b/testing/Part_2/network_42.XMLBIF new file mode 100644 index 00000000..f6d88f1c --- /dev/null +++ b/testing/Part_2/network_42.XMLBIF @@ -0,0 +1,459 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.4529475501930912 0.5470524498069088
+
+ + 1 + 0.9505344555388903 0.049465544461109776
+
+ + 2 + 0.42017718387306363 0.5798228161269363
+
+ + 3 + 0.19564028842882372 0.8043597115711763
+
+ + 4 + 0.9644135523824998 0.035586447617500176
+
+ + 5 + 0.2234786402140535 0.7765213597859465
+
+ + 6 + 0.08529014595831869 0.9147098540416814
+
+ + 7 + 6 + 0.2842125112537555 0.7157874887462444 0.5174068432351551 0.482593156764845
+
+ + 8 + 0.563612933956606 0.43638706604339383
+
+ + 9 + 0.3665394774259422 0.6334605225740578
+
+ + 10 + 0.535857710449075 0.4641422895509249
+
+ + 11 + 0.6029512734827227 0.39704872651727724
+
+ + 12 + 0 + 0.5077849047863052 0.49221509521369483 0.5448357661702377 0.4551642338297624
+
+ + 13 + 0.8851449445946682 0.11485505540533196
+
+ + 14 + 4 + 6 + 0.5087425466761865 0.49125745332381354 0.30236703947862204 0.6976329605213779 0.4776149299625836 0.5223850700374164 0.3993191450368892 0.6006808549631109
+
+ + 15 + 0.30237712328596766 0.6976228767140324
+
+ + 16 + 0.8975010345957467 0.10249896540425331
+
+ + 17 + 11 + 0.7853595847674794 0.21464041523252061 0.5341842952330769 0.46581570476692313
+
+ + 18 + 6 + 0.6091913455104266 0.3908086544895733 0.9382127724187188 0.061787227581281204
+
+ + 19 + 2 + 0.5403215643034689 0.45967843569653116 0.15391110420046494 0.846088895799535
+
+ + 20 + 12 + 0.07030434630146115 0.9296956536985388 0.3928444655402258 0.6071555344597742
+
+ + 21 + 16 + 0.4768664653200942 0.5231335346799059 0.7207199383960977 0.27928006160390223
+
+ + 22 + 19 + 14 + 10 + 21 + 0.33646639191191574 0.6635336080880843 0.5992680518729839 0.4007319481270162 0.4616001343905054 0.5383998656094947 0.8195985272001572 0.1804014727998427 0.35096811245528337 0.6490318875447165 0.826536392357625 0.1734636076423751 0.4222290819875344 0.5777709180124655 0.8460829565394103 0.15391704346058968 0.5172082564558617 0.48279174354413834 0.1051688919143521 0.894831108085648 0.788803594467627 0.21119640553237295 0.7278075687032062 0.27219243129679366 0.32840262739306153 0.6715973726069385 0.8461328667255105 0.1538671332744896 0.40824420946238466 0.5917557905376154 0.8422302903892849 0.15776970961071513
+
+ + 23 + 0.27695487700336996 0.72304512299663
+
+ + 24 + 8 + 0.585204713362402 0.41479528663759796 0.3691531248894087 0.6308468751105912
+
+ + 25 + 0.7073019864208726 0.2926980135791275
+
+ + 26 + 15 + 0.48202561492785706 0.5179743850721429 0.565202956142969 0.434797043857031
+
+ + 27 + 18 + 22 + 0.005717696921649904 0.9942823030783501 0.5685173444145216 0.4314826555854784 0.4240966640241158 0.5759033359758843 0.9785657595410746 0.021434240458925356
+
+ + 28 + 26 + 0.7435281904418114 0.2564718095581886 0.6025707733029826 0.39742922669701747
+
+ + 29 + 9 + 21 + 0.5396772106286191 0.460322789371381 0.5006705379405131 0.4993294620594869 0.3105084590887807 0.6894915409112193 0.6561729140173784 0.34382708598262157
+
+ + 30 + 6 + 0.7410401786195151 0.258959821380485 0.391379645268639 0.6086203547313611
+
+ + 31 + 2 + 30 + 0.4829249874459798 0.5170750125540202 0.9258555297668515 0.0741444702331485 0.6021719513181472 0.39782804868185284 0.1607617768353487 0.8392382231646512
+
+ + 32 + 27 + 0.2357906084836741 0.7642093915163259 0.9029414461358505 0.09705855386414956
+
+ + 33 + 4 + 0.1491960309068093 0.8508039690931906 0.46800736418005606 0.5319926358199439
+
+ + 34 + 1 + 25 + 0.8728558580188189 0.1271441419811811 0.5253085890686451 0.4746914109313549 0.4728128358045144 0.5271871641954855 0.7175277037945095 0.2824722962054906
+
+ + 35 + 8 + 0.7588966326038213 0.2411033673961787 0.4702047769985925 0.5297952230014076
+
+ + 36 + 0.5150628555715014 0.4849371444284985
+
+ + 37 + 0.451967688901894 0.548032311098106
+
+ + 38 + 25 + 0.23870921839320777 0.7612907816067923 0.46489927432397166 0.5351007256760284
+
+ + 39 + 0.3569594791760675 0.6430405208239325
+
+ + 40 + 24 + 27 + 0.51887316436345 0.48112683563655007 0.5254081548935748 0.47459184510642505 0.45168553753095025 0.5483144624690497 0.5774215581078687 0.42257844189213134
+
+ + 41 + 11 + 36 + 0.8032205917524221 0.19677940824757795 0.803983338103189 0.1960166618968111 0.41039720430291227 0.5896027956970877 0.4070557844207969 0.5929442155792032
+
+
+
diff --git a/testing/Part_2/network_44.XMLBIF b/testing/Part_2/network_44.XMLBIF new file mode 100644 index 00000000..8e91efa1 --- /dev/null +++ b/testing/Part_2/network_44.XMLBIF @@ -0,0 +1,480 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.6357778688747615 0.36422213112523855
+
+ + 1 + 0.2407820727311802 0.7592179272688199
+
+ + 2 + 0.7511576465182255 0.24884235348177453
+
+ + 3 + 0.39451344161915464 0.6054865583808452
+
+ + 4 + 0.6192925886285414 0.3807074113714586
+
+ + 5 + 0.4402282959138855 0.5597717040861145
+
+ + 6 + 0.8350329213850513 0.16496707861494875
+
+ + 7 + 0.9779789389712474 0.022021061028752613
+
+ + 8 + 0.801554396215985 0.19844560378401502
+
+ + 9 + 0 + 0.5102977115912835 0.48970228840871655 0.33601047328806755 0.6639895267119325
+
+ + 10 + 0.6809950546307889 0.31900494536921115
+
+ + 11 + 0.5066758846315516 0.49332411536844833
+
+ + 12 + 2 + 0.7085512896677706 0.29144871033222935 0.29696634658741494 0.7030336534125851
+
+ + 13 + 0.7791458446535657 0.22085415534643413
+
+ + 14 + 0.579561006677913 0.420438993322087
+
+ + 15 + 12 + 0.3225551651630663 0.6774448348369337 0.726085811100194 0.273914188899806
+
+ + 16 + 0.49211695962277324 0.5078830403772268
+
+ + 17 + 0.572900071689945 0.42709992831005505
+
+ + 18 + 12 + 0.3074336963926203 0.6925663036073797 0.8635125038944643 0.13648749610553573
+
+ + 19 + 0.2583919139967263 0.7416080860032737
+
+ + 20 + 9 + 0.4526001250539381 0.5473998749460619 0.5955764536395439 0.404423546360456
+
+ + 21 + 0.8537723760374415 0.1462276239625585
+
+ + 22 + 0.2724548872273027 0.7275451127726973
+
+ + 23 + 9 + 10 + 0.5331691521193397 0.46683084788066026 0.5746927469348241 0.4253072530651758 0.172303468258942 0.827696531741058 0.42125306868780094 0.5787469313121991
+
+ + 24 + 0.8422585548164025 0.15774144518359753
+
+ + 25 + 21 + 0.932383330894841 0.06761666910515901 0.6065500267943974 0.39344997320560254
+
+ + 26 + 17 + 0.09703282383281088 0.9029671761671891 0.2044775397336755 0.7955224602663244
+
+ + 27 + 18 + 0.5466592984486153 0.45334070155138473 0.23764646075983398 0.762353539240166
+
+ + 28 + 0 + 11 + 0.4588629454143503 0.5411370545856496 0.023945661528935857 0.9760543384710642 0.7678087733284417 0.23219122667155837 0.5667364754319146 0.43326352456808537
+
+ + 29 + 2 + 0.8487323352870766 0.15126766471292338 0.4776992428923697 0.5223007571076304
+
+ + 30 + 0.4200228417285843 0.5799771582714157
+
+ + 31 + 14 + 0.5197804087409151 0.4802195912590849 0.46512189123903236 0.5348781087609676
+
+ + 32 + 1 + 4 + 17 + 0.120256212835143 0.879743787164857 0.9246633511249978 0.07533664887500224 0.13602559783894191 0.8639744021610581 0.7974210875259752 0.2025789124740247 0.8076076091067631 0.19239239089323681 0.7091197344443005 0.2908802655556995 0.49913565450498887 0.5008643454950111 0.4723106562986632 0.5276893437013369
+
+ + 33 + 28 + 0.5719944701222893 0.4280055298777107 0.38786945438366044 0.6121305456163395
+
+ + 34 + 0.5735509159503253 0.42644908404967474
+
+ + 35 + 2 + 20 + 0.5710554024371969 0.4289445975628031 0.7825271355353974 0.2174728644646026 0.4464769460523134 0.5535230539476866 0.3375282460115335 0.6624717539884666
+
+ + 36 + 9 + 11 + 26 + 25 + 0.19402810593733774 0.8059718940626622 0.5909061016316108 0.40909389836838916 0.43056696332063277 0.5694330366793673 0.18986766297428923 0.8101323370257107 0.8498581093293148 0.15014189067068517 0.9567001807419119 0.04329981925808815 0.6975415606169414 0.30245843938305855 0.030361457137204506 0.9696385428627955 0.31273146334204815 0.6872685366579518 0.756417699894306 0.24358230010569404 0.4829895939263417 0.5170104060736582 0.5136878425131197 0.48631215748688017 0.41118406423730675 0.5888159357626932 0.40976617476488214 0.590233825235118 0.8144724680164492 0.18552753198355085 0.581274713641616 0.41872528635838413
+
+ + 37 + 30 + 0.30313620966311594 0.6968637903368841 0.5512978819067296 0.4487021180932704
+
+ + 38 + 3 + 18 + 0.5943513752319319 0.40564862476806796 0.35525755294911704 0.6447424470508829 0.4176731709191116 0.5823268290808885 0.27681483021526526 0.7231851697847347
+
+ + 39 + 0.36932895632144824 0.6306710436785518
+
+ + 40 + 0.23089196287927358 0.7691080371207265
+
+ + 41 + 38 + 7 + 0.4906341298726429 0.5093658701273571 0.4616458556104417 0.5383541443895583 0.1855003938384425 0.8144996061615575 0.9475712549448413 0.05242874505515868
+
+ + 42 + 14 + 25 + 0.4817929062011921 0.5182070937988079 0.6961057585834659 0.30389424141653426 0.8147228641360766 0.18527713586392333 0.5933355320657735 0.4066644679342265
+
+ + 43 + 0 + 17 + 40 + 0.6235891193477747 0.37641088065222533 0.4436526572068117 0.5563473427931883 0.26879611994096414 0.7312038800590359 0.49167154574673183 0.5083284542532682 0.4127595395948911 0.5872404604051088 0.9780209746273002 0.021979025372699825 0.09869114405589414 0.9013088559441058 0.6665681246821581 0.33343187531784185
+
+
+
diff --git a/testing/Part_2/network_46.XMLBIF b/testing/Part_2/network_46.XMLBIF new file mode 100644 index 00000000..779c29d2 --- /dev/null +++ b/testing/Part_2/network_46.XMLBIF @@ -0,0 +1,504 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.36324564416364225 0.6367543558363578
+
+ + 1 + 0.89045271162017 0.10954728837983002
+
+ + 2 + 0.48977246890294207 0.510227531097058
+
+ + 3 + 0.4598770153147102 0.5401229846852899
+
+ + 4 + 0.48251652898532416 0.5174834710146758
+
+ + 5 + 0.8937235227644185 0.10627647723558159
+
+ + 6 + 0.5862672409045159 0.4137327590954841
+
+ + 7 + 6 + 0.2569703738640148 0.7430296261359852 0.6170773594332667 0.38292264056673336
+
+ + 8 + 0.36760162299432164 0.6323983770056784
+
+ + 9 + 0 + 0.6163184118097889 0.3836815881902112 0.525810219731149 0.474189780268851
+
+ + 10 + 0.42877368876877014 0.5712263112312298
+
+ + 11 + 0.08758109753898027 0.9124189024610198
+
+ + 12 + 0.06539229835221337 0.9346077016477866
+
+ + 13 + 0.4821255440173846 0.5178744559826155
+
+ + 14 + 0.20779500003367127 0.7922049999663289
+
+ + 15 + 2 + 0.5358067276365724 0.46419327236342756 0.33666107135176604 0.663338928648234
+
+ + 16 + 8 + 0.6157616124794659 0.38423838752053413 0.4928377295637333 0.5071622704362667
+
+ + 17 + 13 + 0.26403717372740426 0.7359628262725958 0.4497447812015932 0.5502552187984067
+
+ + 18 + 8 + 0.42634837647229906 0.5736516235277009 0.5515148122156346 0.4484851877843654
+
+ + 19 + 0.5758520340262804 0.4241479659737197
+
+ + 20 + 0.23196465658005247 0.7680353434199475
+
+ + 21 + 3 + 16 + 0.466122364671109 0.533877635328891 0.12942378419507786 0.8705762158049222 0.8910793955055686 0.10892060449443135 0.5353605449041434 0.4646394550958566
+
+ + 22 + 0 + 16 + 0.21716710312589346 0.7828328968741065 0.21640487085881063 0.7835951291411893 0.9167878563955975 0.0832121436044026 0.8223559542130198 0.17764404578698026
+
+ + 23 + 0.5749908659689548 0.42500913403104523
+
+ + 24 + 0.5905791937856046 0.4094208062143953
+
+ + 25 + 0.3706805875706532 0.6293194124293469
+
+ + 26 + 5 + 14 + 0.480572324107671 0.5194276758923291 0.3481080649663797 0.6518919350336203 0.6528714807684142 0.3471285192315859 0.5482591445803782 0.45174085541962183
+
+ + 27 + 23 + 0.32122145681211384 0.6787785431878861 0.8775461844950186 0.12245381550498124
+
+ + 28 + 22 + 1 + 0.9341306072908927 0.06586939270910729 0.12509672063652547 0.8749032793634746 0.4379840827801476 0.5620159172198523 0.6756659181926468 0.3243340818073533
+
+ + 29 + 9 + 1 + 0.30191454459483424 0.6980854554051656 0.5060268378105828 0.4939731621894171 0.6221420544269878 0.37785794557301233 0.7798726910373937 0.22012730896260635
+
+ + 30 + 0 + 16 + 0.42722781768698864 0.5727721823130113 0.5483506033949026 0.4516493966050975 0.8745590920037712 0.12544090799622876 0.9808528379147773 0.01914716208522273
+
+ + 31 + 28 + 8 + 0.3388164272915505 0.6611835727084495 0.3399632010994858 0.6600367989005143 0.5661426873879853 0.43385731261201455 0.035562482017195425 0.9644375179828045
+
+ + 32 + 18 + 0.7512824717502209 0.24871752824977908 0.04409940604914077 0.9559005939508592
+
+ + 33 + 10 + 0.6408298480688811 0.3591701519311189 0.8443593946943366 0.15564060530566334
+
+ + 34 + 10 + 0.6060305515532605 0.3939694484467395 0.03834750602582758 0.9616524939741724
+
+ + 35 + 6 + 0.481853630345848 0.5181463696541521 0.9060402024117522 0.0939597975882478
+
+ + 36 + 0.32347312389047117 0.6765268761095289
+
+ + 37 + 6 + 10 + 25 + 36 + 0.5998436793666223 0.40015632063337775 0.5354101111888425 0.4645898888111574 0.548079568614289 0.4519204313857111 0.38754399378789217 0.6124560062121078 0.4773081434832693 0.5226918565167307 0.42749635545076214 0.5725036445492379 0.3241935587253597 0.6758064412746403 0.9942854215937273 0.005714578406272635 0.5170858981625962 0.48291410183740385 0.38518310487074603 0.6148168951292539 0.7328310100346466 0.26716898996535343 0.8949008117671097 0.10509918823289024 0.9941908244844073 0.005809175515592706 0.18704061851127482 0.8129593814887252 0.5210491820157256 0.4789508179842744 0.47243515095910243 0.5275648490408975
+
+ + 38 + 10 + 0.5205786803177423 0.47942131968225765 0.06840170305060392 0.9315982969493961
+
+ + 39 + 32 + 0.8989721724799645 0.10102782752003553 0.6796775988662506 0.32032240113374943
+
+ + 40 + 35 + 0.5773522277012005 0.4226477722987994 0.3812098733429066 0.6187901266570934
+
+ + 41 + 30 + 0.9022355575275622 0.0977644424724378 0.99063404778325 0.009365952216750007
+
+ + 42 + 5 + 0.6403643704142681 0.3596356295857318 0.17997359136836463 0.8200264086316353
+
+ + 43 + 9 + 41 + 0.4555398885005008 0.5444601114994992 0.5938583622042064 0.40614163779579354 0.16287545151973404 0.837124548480266 0.1359168272517059 0.864083172748294
+
+ + 44 + 0.47926563434259495 0.520734365657405
+
+ + 45 + 43 + 17 + 0.7849049700188336 0.2150950299811664 0.9007616829349483 0.09923831706505168 0.8386358755943667 0.1613641244056333 0.6906257293482276 0.3093742706517724
+
+
+
diff --git a/testing/Part_2/network_48.XMLBIF b/testing/Part_2/network_48.XMLBIF new file mode 100644 index 00000000..1492bc53 --- /dev/null +++ b/testing/Part_2/network_48.XMLBIF @@ -0,0 +1,525 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.8570250516668588 0.14297494833314114
+
+ + 1 + 0.1608585428078922 0.8391414571921078
+
+ + 2 + 0.6839864339269535 0.3160135660730466
+
+ + 3 + 0.7804047008168791 0.21959529918312104
+
+ + 4 + 0.640492771081909 0.3595072289180909
+
+ + 5 + 0.9211853409486231 0.07881465905137686
+
+ + 6 + 0.5367193434081219 0.463280656591878
+
+ + 7 + 0.8739162182826217 0.12608378171737847
+
+ + 8 + 3 + 0.8917491581551762 0.10825084184482377 0.7548871239015903 0.24511287609840973
+
+ + 9 + 0.30262046386655717 0.697379536133443
+
+ + 10 + 4 + 5 + 0.39183250395772046 0.6081674960422795 0.15637746154761153 0.8436225384523884 0.6772157234956454 0.32278427650435454 0.6805231224268242 0.3194768775731758
+
+ + 11 + 0.45873027154475216 0.5412697284552478
+
+ + 12 + 10 + 0.002284089253335452 0.9977159107466645 0.4900525921444672 0.5099474078555328
+
+ + 13 + 9 + 0.7092732771792777 0.29072672282072237 0.8315327639939671 0.1684672360060329
+
+ + 14 + 0.828362677487875 0.17163732251212507
+
+ + 15 + 9 + 0.568692910994449 0.43130708900555104 0.5245909992791812 0.47540900072081876
+
+ + 16 + 1 + 0.7857974197190917 0.21420258028090836 0.5351772928331759 0.46482270716682417
+
+ + 17 + 16 + 2 + 0.5490608250718926 0.4509391749281074 0.5543451627073046 0.44565483729269545 0.6524858337873031 0.347514166212697 0.9449304771520449 0.05506952284795502
+
+ + 18 + 0.5843561728783233 0.4156438271216767
+
+ + 19 + 0 + 5 + 0.17741343167544338 0.8225865683245567 0.7410630534553577 0.2589369465446423 0.23445449507999533 0.7655455049200046 0.4273205685641066 0.5726794314358934
+
+ + 20 + 0.28677314570370993 0.71322685429629
+
+ + 21 + 0.4467633351020499 0.5532366648979501
+
+ + 22 + 15 + 0.5725723951466138 0.42742760485338616 0.31451766940632814 0.6854823305936718
+
+ + 23 + 11 + 0.6548432103442076 0.34515678965579244 0.9993471930387068 0.0006528069612931873
+
+ + 24 + 0 + 10 + 0.47828247686423303 0.521717523135767 0.9775649870340049 0.02243501296599512 0.6885506566903643 0.31144934330963564 0.9229889411253094 0.07701105887469059
+
+ + 25 + 17 + 0.3721423391052427 0.6278576608947573 0.3975469802128355 0.6024530197871645
+
+ + 26 + 0.6803786610393121 0.319621338960688
+
+ + 27 + 0.473464084610784 0.526535915389216
+
+ + 28 + 21 + 0.12835567041858195 0.871644329581418 0.9463884174763624 0.05361158252363759
+
+ + 29 + 20 + 0.7999634686583844 0.20003653134161556 0.5027737702150454 0.4972262297849546
+
+ + 30 + 22 + 0.40100888360728937 0.5989911163927105 0.49369521442851283 0.5063047855714872
+
+ + 31 + 0.4254676817535038 0.5745323182464963
+
+ + 32 + 24 + 0.5599015194117972 0.4400984805882028 0.35113421795750915 0.6488657820424909
+
+ + 33 + 9 + 0.6850200424246563 0.31497995757534364 0.7016270771220342 0.29837292287796585
+
+ + 34 + 22 + 0.49237339200967317 0.5076266079903268 0.5743069416346755 0.42569305836532434
+
+ + 35 + 24 + 28 + 34 + 0.8194092820053419 0.18059071799465806 0.31770683179525705 0.6822931682047428 0.23485452869494927 0.7651454713050507 0.3929743067454118 0.6070256932545882 0.1577739938921834 0.8422260061078167 0.9617065683207742 0.03829343167922595 0.4433618645240608 0.5566381354759392 0.37486185764743835 0.6251381423525617
+
+ + 36 + 0.24773810323358342 0.7522618967664165
+
+ + 37 + 0.9071156758881664 0.0928843241118336
+
+ + 38 + 3 + 35 + 26 + 0.8604396539664866 0.13956034603351336 0.12134869997996364 0.8786513000200363 0.5673356661446061 0.43266433385539393 0.49153897066825486 0.5084610293317452 0.7941654584378472 0.20583454156215275 0.6267776878581093 0.3732223121418907 0.4008018564370324 0.5991981435629676 0.6803881414092673 0.3196118585907327
+
+ + 39 + 8 + 14 + 0.43171080364297765 0.5682891963570224 0.38094587689076154 0.6190541231092384 0.5971318038666553 0.4028681961333447 0.6084091447861134 0.39159085521388665
+
+ + 40 + 15 + 0.4280868536297718 0.5719131463702283 0.528685115253229 0.4713148847467709
+
+ + 41 + 0.7311587058376505 0.2688412941623496
+
+ + 42 + 24 + 37 + 0.1606436514013062 0.8393563485986939 0.35358327188202954 0.6464167281179705 0.026510105793677755 0.9734898942063223 0.9277656125401509 0.07223438745984913
+
+ + 43 + 10 + 37 + 41 + 0.5209077760211788 0.4790922239788213 0.1656670903483775 0.8343329096516224 0.5546619407824614 0.4453380592175385 0.058172906732145396 0.9418270932678546 0.449614534824232 0.5503854651757679 0.521132742564886 0.478867257435114 0.36139348556795087 0.6386065144320491 0.7189778587788098 0.28102214122119024
+
+ + 44 + 3 + 22 + 0.15957434005419677 0.8404256599458032 0.20022433230006806 0.799775667699932 0.8111105610560717 0.1888894389439283 0.11971487504743347 0.8802851249525665
+
+ + 45 + 0.4074316050998923 0.5925683949001077
+
+ + 46 + 0.7246689827369022 0.2753310172630979
+
+ + 47 + 9 + 0.624242775385417 0.3757572246145831 0.5795325201244623 0.42046747987553773
+
+
+
diff --git a/testing/Part_2/network_50.XMLBIF b/testing/Part_2/network_50.XMLBIF new file mode 100644 index 00000000..54b6040c --- /dev/null +++ b/testing/Part_2/network_50.XMLBIF @@ -0,0 +1,548 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.03995570324210349 0.9600442967578965
+
+ + 1 + 0.39372392369173353 0.6062760763082664
+
+ + 2 + 0.9605297603529417 0.03947023964705829
+
+ + 3 + 0.3889583192669672 0.6110416807330328
+
+ + 4 + 0.5518296291822464 0.44817037081775357
+
+ + 5 + 0.26640424681147223 0.7335957531885278
+
+ + 6 + 0.28862932254553275 0.7113706774544674
+
+ + 7 + 6 + 0.7354584896934785 0.26454151030652145 0.9006832110256007 0.09931678897439937
+
+ + 8 + 0.7298833982124834 0.27011660178751673
+
+ + 9 + 0.7659849594658589 0.23401504053414116
+
+ + 10 + 0.7485824382815897 0.2514175617184104
+
+ + 11 + 0.43681689491480635 0.5631831050851936
+
+ + 12 + 0.6487177290561292 0.3512822709438707
+
+ + 13 + 0.9348048936619029 0.06519510633809701
+
+ + 14 + 0.6065674443245279 0.39343255567547214
+
+ + 15 + 10 + 0.5535991340446008 0.4464008659553992 0.13942876747550442 0.8605712325244954
+
+ + 16 + 0 + 0.5523635700689252 0.4476364299310747 0.7121363982144732 0.28786360178552683
+
+ + 17 + 1 + 0.3366022717117442 0.6633977282882557 0.36119554902276074 0.6388044509772394
+
+ + 18 + 0.46051864719428975 0.5394813528057103
+
+ + 19 + 0.49730580416439946 0.5026941958356006
+
+ + 20 + 0.08890794948013232 0.9110920505198676
+
+ + 21 + 0.2601048506312428 0.7398951493687572
+
+ + 22 + 21 + 0.407131392260997 0.5928686077390031 0.7586336915875127 0.24136630841248732
+
+ + 23 + 21 + 0.7393403129332847 0.2606596870667153 0.17801706553918997 0.82198293446081
+
+ + 24 + 17 + 9 + 0.4730603141341208 0.5269396858658791 0.283177126592541 0.716822873407459 0.3923959222317035 0.6076040777682965 0.5349720050043132 0.46502799499568687
+
+ + 25 + 15 + 0.5923221776976187 0.4076778223023813 0.26635654842121115 0.733643451578789
+
+ + 26 + 5 + 7 + 0.4841218912648217 0.5158781087351784 0.6040172752092823 0.3959827247907178 0.00650743909420428 0.9934925609057957 0.4136420854370243 0.5863579145629757
+
+ + 27 + 25 + 0.35710910733177414 0.6428908926682259 0.055815039602514376 0.9441849603974857
+
+ + 28 + 13 + 0.4758252420001889 0.5241747579998112 0.6463330179924491 0.35366698200755087
+
+ + 29 + 1 + 0.23006373370317618 0.7699362662968239 0.7654435912077735 0.23455640879222636
+
+ + 30 + 24 + 0.5489147292342972 0.4510852707657028 0.602170854029116 0.3978291459708841
+
+ + 31 + 0.537312674290896 0.4626873257091039
+
+ + 32 + 20 + 0.6346839114545231 0.36531608854547687 0.6238348402711554 0.3761651597288445
+
+ + 33 + 15 + 0.4845396127604591 0.5154603872395408 0.633029804025981 0.36697019597401903
+
+ + 34 + 0.42471638232246645 0.5752836176775336
+
+ + 35 + 26 + 0.27430793112539303 0.725692068874607 0.796029270287125 0.20397072971287494
+
+ + 36 + 10 + 18 + 19 + 0.5144457012804566 0.48555429871954336 0.2881527140227686 0.7118472859772313 0.10900412736635877 0.8909958726336412 0.6367454264488603 0.3632545735511397 0.5581450642753574 0.4418549357246426 0.7904411326183884 0.20955886738161156 0.6957116813071359 0.3042883186928641 0.41854626051967 0.5814537394803301
+
+ + 37 + 0.3511510309363162 0.6488489690636837
+
+ + 38 + 37 + 0.15449408044711166 0.8455059195528883 0.5902246246700574 0.40977537532994257
+
+ + 39 + 29 + 28 + 0.7323673096581372 0.2676326903418626 0.16814043667102369 0.8318595633289764 0.38968895709488094 0.6103110429051191 0.9460837386463294 0.0539162613536705
+
+ + 40 + 15 + 0.15565479721731876 0.8443452027826812 0.3381535352003288 0.6618464647996711
+
+ + 41 + 1 + 28 + 0.45438012448728965 0.5456198755127104 0.46711301036987984 0.5328869896301202 0.9423009011019514 0.05769909889804862 0.5069364832788963 0.4930635167211037
+
+ + 42 + 5 + 22 + 0.10035077249560566 0.8996492275043944 0.3439983139599996 0.6560016860400004 0.4843001673906859 0.5156998326093142 0.4616333139939351 0.5383666860060651
+
+ + 43 + 21 + 22 + 0.5011784069082222 0.4988215930917777 0.30231493592359865 0.6976850640764014 0.08777693056864581 0.9122230694313541 0.5637767533525238 0.43622324664747625
+
+ + 44 + 29 + 0.4589144813885204 0.5410855186114796 0.6173864992593608 0.38261350074063916
+
+ + 45 + 29 + 7 + 14 + 27 + 0.37843487165609224 0.6215651283439079 0.8781520643637724 0.12184793563622762 0.5911890966644782 0.4088109033355217 0.967313760887876 0.03268623911212393 0.5887334627381166 0.41126653726188356 0.2220905542268006 0.7779094457731994 0.9734183930354556 0.026581606964544317 0.7729533425120948 0.2270466574879052 0.8941085692219168 0.10589143077808316 0.711396387305241 0.288603612694759 0.47606369884580885 0.5239363011541911 0.8323586986687611 0.16764130133123892 0.6612408966609963 0.3387591033390038 0.14945285829926475 0.8505471417007352 0.583309212163893 0.41669078783610697 0.7811306262074091 0.21886937379259083
+
+ + 46 + 23 + 0.17017311628524923 0.8298268837147507 0.4113213398090778 0.5886786601909222
+
+ + 47 + 0.5162563071726863 0.48374369282731355
+
+ + 48 + 8 + 30 + 0.6475613783488164 0.35243862165118356 0.5101813310170973 0.48981866898290266 0.2460493072827463 0.7539506927172536 0.4683507609486902 0.5316492390513098
+
+ + 49 + 29 + 5 + 25 + 0.3784002769961079 0.6215997230038921 0.4900428644595396 0.5099571355404604 0.5571593414844715 0.44284065851552845 0.4836351066297834 0.5163648933702166 0.30691708525839995 0.6930829147416 0.7368852380795403 0.2631147619204597 0.10732014600297579 0.8926798539970242 0.05338762837081667 0.9466123716291833
+
+
+
diff --git a/testing/Part_2/network_52.XMLBIF b/testing/Part_2/network_52.XMLBIF new file mode 100644 index 00000000..285d88d4 --- /dev/null +++ b/testing/Part_2/network_52.XMLBIF @@ -0,0 +1,558 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.575566960971148 0.4244330390288518
+
+ + 1 + 0.7614474966465046 0.23855250335349532
+
+ + 2 + 0.7391640454049214 0.2608359545950785
+
+ + 3 + 0.4954014050899131 0.5045985949100869
+
+ + 4 + 1 + 0.16905770736081094 0.8309422926391891 0.6589419725643367 0.3410580274356632
+
+ + 5 + 0.28127550675418106 0.718724493245819
+
+ + 6 + 0.2190773928966427 0.7809226071033573
+
+ + 7 + 0.26562341712196025 0.7343765828780398
+
+ + 8 + 0.5002804734234064 0.4997195265765935
+
+ + 9 + 6 + 0.7376212829421476 0.2623787170578525 0.8800836931924666 0.1199163068075334
+
+ + 10 + 0.5434642012511743 0.4565357987488256
+
+ + 11 + 0.47759582526463296 0.5224041747353672
+
+ + 12 + 0.9509397213242247 0.04906027867577531
+
+ + 13 + 0.721823516982334 0.27817648301766595
+
+ + 14 + 0.20244436539865343 0.7975556346013467
+
+ + 15 + 10 + 0.05054145638027073 0.9494585436197293 0.46389267066269796 0.5361073293373021
+
+ + 16 + 0.5506342748635655 0.44936572513643447
+
+ + 17 + 13 + 0.5578327246147224 0.4421672753852776 0.96158818692926 0.03841181307073999
+
+ + 18 + 0.43741543346779455 0.5625845665322055
+
+ + 19 + 0.5376316990605449 0.4623683009394552
+
+ + 20 + 0.47014225945646504 0.529857740543535
+
+ + 21 + 0.525614632890543 0.474385367109457
+
+ + 22 + 6 + 0.5860028253584005 0.4139971746415995 0.4821830204718824 0.5178169795281177
+
+ + 23 + 0.27712842838956003 0.72287157161044
+
+ + 24 + 19 + 0.2299443543044162 0.7700556456955838 0.5230168463201411 0.4769831536798589
+
+ + 25 + 23 + 0.12025580109281717 0.8797441989071828 0.19142399893768872 0.8085760010623112
+
+ + 26 + 3 + 0.19881180950796518 0.8011881904920348 0.40978990485573946 0.5902100951442606
+
+ + 27 + 0.22497514262904977 0.7750248573709502
+
+ + 28 + 0.8740563935764571 0.12594360642354283
+
+ + 29 + 6 + 0.31388884457329214 0.6861111554267079 0.2878609848101354 0.7121390151898646
+
+ + 30 + 24 + 28 + 0.07782988017696528 0.9221701198230348 0.45400103856761287 0.5459989614323871 0.17324553460237657 0.8267544653976234 0.6581349515292847 0.3418650484707153
+
+ + 31 + 5 + 30 + 0.23819921363176003 0.76180078636824 0.7451151695517634 0.2548848304482366 0.37802532020984997 0.62197467979015 0.8827284841068512 0.11727151589314876
+
+ + 32 + 27 + 0.15497385596565452 0.8450261440343455 0.27064789368156755 0.7293521063184325
+
+ + 33 + 0.6816656267328045 0.31833437326719544
+
+ + 34 + 32 + 33 + 0.6711404477929729 0.32885955220702706 0.6956324807883685 0.3043675192116315 0.8182324582083254 0.18176754179167467 0.05602030053448754 0.9439796994655124
+
+ + 35 + 18 + 0.6495272840653684 0.35047271593463164 0.539066197523973 0.46093380247602694
+
+ + 36 + 0.8160777891972918 0.18392221080270835
+
+ + 37 + 0.40799570083837366 0.5920042991616264
+
+ + 38 + 5 + 0.6308179442291821 0.36918205577081786 0.23856019314951918 0.7614398068504808
+
+ + 39 + 6 + 0.9712833531486696 0.028716646851330352 0.17584565624021486 0.8241543437597851
+
+ + 40 + 0.02606426258712022 0.9739357374128798
+
+ + 41 + 22 + 0.507154526287058 0.49284547371294196 0.5299707026156923 0.4700292973843076
+
+ + 42 + 14 + 0.5447109772958972 0.45528902270410276 0.6750163232934998 0.32498367670650014
+
+ + 43 + 1 + 0.44953385636254584 0.550466143637454 0.5625672825002186 0.43743271749978146
+
+ + 44 + 22 + 0.6120974343456337 0.38790256565436637 0.2955831685624132 0.7044168314375868
+
+ + 45 + 43 + 8 + 0.9198287060771531 0.08017129392284694 0.6121617084592532 0.38783829154074684 0.3699963250339138 0.6300036749660862 0.5451336035359459 0.4548663964640542
+
+ + 46 + 0.2958349754499803 0.7041650245500197
+
+ + 47 + 32 + 0.683715987338419 0.31628401266158107 0.4224057625011467 0.5775942374988533
+
+ + 48 + 2 + 37 + 0.5549840614967467 0.44501593850325327 0.5114134354423827 0.4885865645576174 0.3926273155549263 0.6073726844450736 0.34052547179252407 0.6594745282074759
+
+ + 49 + 0.3569214128293835 0.6430785871706165
+
+ + 50 + 2 + 13 + 16 + 0.5793737800972801 0.42062621990271987 0.7637735897123192 0.23622641028768077 0.5064282156079416 0.49357178439205834 0.6334006867190061 0.36659931328099393 0.22048242391500442 0.7795175760849956 0.6959784958654568 0.30402150413454315 0.24568053119315278 0.7543194688068472 0.4323924624661688 0.5676075375338312
+
+ + 51 + 50 + 0.6964872454514344 0.30351275454856563 0.3029817426281911 0.6970182573718089
+
+
+
diff --git a/testing/Part_2/network_54.XMLBIF b/testing/Part_2/network_54.XMLBIF new file mode 100644 index 00000000..046b8797 --- /dev/null +++ b/testing/Part_2/network_54.XMLBIF @@ -0,0 +1,588 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.08201226243746312 0.9179877375625368
+
+ + 1 + 0.9198859619375559 0.08011403806244408
+
+ + 2 + 0.23103704149306356 0.7689629585069364
+
+ + 3 + 0.5141196617227326 0.48588033827726734
+
+ + 4 + 3 + 0.406198369789134 0.5938016302108661 0.9669905705861715 0.033009429413828326
+
+ + 5 + 0 + 0.49581465420465487 0.5041853457953451 0.4695070388794965 0.5304929611205035
+
+ + 6 + 0.41630114104979277 0.5836988589502072
+
+ + 7 + 0.35021491072805244 0.6497850892719476
+
+ + 8 + 6 + 0.507058307212748 0.4929416927872519 0.4599255985303484 0.5400744014696516
+
+ + 9 + 0.4451000627695286 0.5548999372304714
+
+ + 10 + 0.5952682533275617 0.40473174667243833
+
+ + 11 + 8 + 0.2815198445606224 0.7184801554393776 0.4320583479749491 0.567941652025051
+
+ + 12 + 0.5164518308206467 0.4835481691793533
+
+ + 13 + 0.1948530036223323 0.8051469963776677
+
+ + 14 + 0.6374658639736136 0.3625341360263865
+
+ + 15 + 0.6463783694900784 0.35362163050992146
+
+ + 16 + 0.4240106682738934 0.5759893317261067
+
+ + 17 + 0.45585105839091494 0.5441489416090851
+
+ + 18 + 0.6720453180936826 0.3279546819063174
+
+ + 19 + 15 + 0.5355551688564323 0.46444483114356777 0.470986030129221 0.529013969870779
+
+ + 20 + 0.3642447007792993 0.6357552992207007
+
+ + 21 + 10 + 0.8662530501796162 0.13374694982038385 0.523655213710484 0.4763447862895161
+
+ + 22 + 0.4196728094333974 0.5803271905666025
+
+ + 23 + 0.23129405976966516 0.7687059402303348
+
+ + 24 + 0.07646150373187635 0.9235384962681237
+
+ + 25 + 10 + 0.8192324666901525 0.18076753330984746 0.5633608424044159 0.4366391575955842
+
+ + 26 + 0.5303685828040606 0.46963141719593937
+
+ + 27 + 12 + 0.49565786064289385 0.504342139357106 0.6688435191738322 0.3311564808261678
+
+ + 28 + 0.8178931320131498 0.18210686798685016
+
+ + 29 + 2 + 0.3380074518139966 0.6619925481860034 0.4753286835808117 0.5246713164191883
+
+ + 30 + 5 + 0.49119448247692654 0.5088055175230735 0.0404433318303933 0.9595566681696067
+
+ + 31 + 0.9777436600852597 0.02225633991474028
+
+ + 32 + 4 + 0.5605564834936998 0.43944351650630026 0.6916199512643038 0.3083800487356962
+
+ + 33 + 0.551830585452325 0.448169414547675
+
+ + 34 + 21 + 0.0399035483091961 0.9600964516908039 0.3568663455467703 0.6431336544532297
+
+ + 35 + 2 + 0.6261345179303436 0.37386548206965653 0.3679137879160431 0.6320862120839569
+
+ + 36 + 17 + 0.25901166964150213 0.7409883303584979 0.5316863876630138 0.46831361233698626
+
+ + 37 + 30 + 17 + 0.5016997552169077 0.49830024478309226 0.8674824090546808 0.13251759094531926 0.5965949579543949 0.4034050420456051 0.512643234728083 0.4873567652719169
+
+ + 38 + 0.5527150447663112 0.44728495523368883
+
+ + 39 + 25 + 19 + 24 + 0.6348578384246473 0.3651421615753526 0.4756642576224189 0.5243357423775812 0.5728231599690297 0.4271768400309703 0.42983212311514063 0.5701678768848594 0.27252826135519775 0.7274717386448022 0.9138554525985971 0.08614454740140287 0.0225651787917925 0.9774348212082075 0.9246050800805783 0.07539491991942156
+
+ + 40 + 23 + 0.13211231053909195 0.8678876894609081 0.49280078406849237 0.5071992159315076
+
+ + 41 + 8 + 0.7262593730668909 0.2737406269331091 0.3041055035255529 0.6958944964744471
+
+ + 42 + 22 + 0.3634945654381955 0.6365054345618045 0.30220988868721993 0.69779011131278
+
+ + 43 + 0.3640031262201958 0.6359968737798042
+
+ + 44 + 9 + 22 + 26 + 0.7718098459510853 0.22819015404891474 0.849369554781034 0.15063044521896599 0.5072192467686741 0.4927807532313258 0.09376304099857448 0.9062369590014255 0.5726149546162271 0.42738504538377287 0.19994765158928682 0.8000523484107132 0.7834717660051493 0.21652823399485072 0.013434900640132596 0.9865650993598674
+
+ + 45 + 25 + 15 + 23 + 0.5043588236002207 0.49564117639977934 0.6305282761784499 0.36947172382155014 0.2740224527558034 0.7259775472441966 0.47797412481929147 0.5220258751807085 0.4706356992628292 0.5293643007371708 0.9032384842905292 0.09676151570947086 0.4988757726952695 0.5011242273047305 0.7085432387786392 0.29145676122136077
+
+ + 46 + 0.46815609723456447 0.5318439027654355
+
+ + 47 + 18 + 22 + 23 + 0.48485950619114243 0.5151404938088576 0.31314510572638177 0.6868548942736182 0.16276985305901262 0.8372301469409874 0.5722577801738651 0.4277422198261349 0.5883480133688691 0.41165198663113084 0.39199186011195475 0.6080081398880454 0.7188295020972743 0.2811704979027257 0.749699379336463 0.250300620663537
+
+ + 48 + 20 + 0.02320082064252196 0.9767991793574781 0.8033760677319276 0.19662393226807245
+
+ + 49 + 41 + 39 + 0.5065418566109452 0.4934581433890548 0.34755853284057064 0.6524414671594294 0.3448350092418647 0.6551649907581353 0.28364161085126843 0.7163583891487316
+
+ + 50 + 4 + 18 + 0.7187949532928188 0.2812050467071813 0.45420570611306466 0.5457942938869353 0.6279288406207122 0.37207115937928786 0.8757289636953577 0.12427103630464234
+
+ + 51 + 41 + 0.5612520668639435 0.4387479331360566 0.5263532703268418 0.4736467296731582
+
+ + 52 + 47 + 0.9758245483900309 0.024175451609969187 0.677645790243396 0.322354209756604
+
+ + 53 + 6 + 11 + 25 + 40 + 0.564395734157092 0.4356042658429079 0.18488970931330573 0.8151102906866943 0.8848369121812476 0.11516308781875238 0.6346028902539242 0.3653971097460758 0.854173250711717 0.14582674928828301 0.4677792213173943 0.5322207786826056 0.4301765098364782 0.5698234901635217 0.11789113098952651 0.8821088690104735 0.7800108492664775 0.21998915073352263 0.16232097174381668 0.8376790282561833 0.3650687766066776 0.6349312233933224 0.3044562932869468 0.6955437067130532 0.4891721254371069 0.510827874562893 0.7714512720973178 0.22854872790268216 0.5924349797197996 0.4075650202802005 0.19248268415347153 0.8075173158465284
+
+
+
diff --git a/testing/Part_2/network_56.XMLBIF b/testing/Part_2/network_56.XMLBIF new file mode 100644 index 00000000..2cb15625 --- /dev/null +++ b/testing/Part_2/network_56.XMLBIF @@ -0,0 +1,617 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.6470538184181779 0.35294618158182217
+
+ + 1 + 0.9103802724100859 0.0896197275899141
+
+ + 2 + 0.8707137108492558 0.12928628915074422
+
+ + 3 + 0.41324278427916816 0.5867572157208318
+
+ + 4 + 0.3718988857385984 0.6281011142614016
+
+ + 5 + 0.16650313840850592 0.833496861591494
+
+ + 6 + 5 + 0.3184959384919326 0.6815040615080674 0.18061109045665233 0.8193889095433476
+
+ + 7 + 0.28522276733477986 0.7147772326652201
+
+ + 8 + 0.48948872646218583 0.5105112735378142
+
+ + 9 + 0.7559586833883212 0.24404131661167885
+
+ + 10 + 0.6237152943072154 0.3762847056927846
+
+ + 11 + 0.21287487517632833 0.7871251248236717
+
+ + 12 + 5 + 0.26281320253705714 0.7371867974629429 0.9805844695580712 0.019415530441928737
+
+ + 13 + 0.6762038046220847 0.32379619537791515
+
+ + 14 + 0.8324546726696007 0.1675453273303993
+
+ + 15 + 13 + 0.928681639273374 0.07131836072662605 0.9520689109986112 0.04793108900138881
+
+ + 16 + 0.47058790725672445 0.5294120927432755
+
+ + 17 + 1 + 11 + 0.06893826857196211 0.9310617314280379 0.7810421867456923 0.21895781325430777 0.8403282458062381 0.15967175419376187 0.508625789751907 0.491374210248093
+
+ + 18 + 2 + 0.4938590229238857 0.5061409770761143 0.587108972036919 0.41289102796308086
+
+ + 19 + 6 + 0.5615774467721174 0.4384225532278826 0.2454051143406063 0.7545948856593937
+
+ + 20 + 6 + 0.44701810872598774 0.5529818912740122 0.9402852010777148 0.05971479892228516
+
+ + 21 + 0.9209215870276225 0.07907841297237754
+
+ + 22 + 21 + 0.48693385727963323 0.5130661427203668 0.5056756642893491 0.49432433571065093
+
+ + 23 + 1 + 11 + 0.7043977630808714 0.2956022369191285 0.51328554317319 0.4867144568268101 0.3266446546704601 0.6733553453295399 0.4796022481886857 0.5203977518113143
+
+ + 24 + 0.8349513647301446 0.16504863526985547
+
+ + 25 + 6 + 0.646882946180922 0.35311705381907804 0.37183226993647145 0.6281677300635286
+
+ + 26 + 0.916722236963361 0.08327776303663902
+
+ + 27 + 0.015997188856551957 0.984002811143448
+
+ + 28 + 3 + 15 + 0.44600173699666473 0.5539982630033352 0.48047174236760537 0.5195282576323946 0.790863684818729 0.20913631518127093 0.856544688627149 0.14345531137285109
+
+ + 29 + 0.5906770622567962 0.40932293774320383
+
+ + 30 + 0.9393872322106142 0.0606127677893859
+
+ + 31 + 13 + 0.4594707415330401 0.5405292584669599 0.0930366679207061 0.906963332079294
+
+ + 32 + 0.07837316746480572 0.9216268325351943
+
+ + 33 + 1 + 0.4975346558083663 0.5024653441916337 0.717370411080289 0.28262958891971096
+
+ + 34 + 3 + 0.07121146247431344 0.9287885375256866 0.5976668532516712 0.4023331467483288
+
+ + 35 + 0.3599940185715134 0.6400059814284865
+
+ + 36 + 3 + 26 + 0.30058305821096754 0.6994169417890325 0.9962973863927923 0.003702613607207677 0.635485744445049 0.364514255554951 0.09358594367616807 0.906414056323832
+
+ + 37 + 8 + 15 + 21 + 0.14053346003989642 0.8594665399601036 0.35438764212248686 0.6456123578775131 0.2769357077987469 0.7230642922012531 0.8890880293772349 0.11091197062276499 0.6060490920239652 0.39395090797603494 0.7457451186327207 0.2542548813672792 0.1628430229665956 0.8371569770334044 0.8709107453579005 0.12908925464209953
+
+ + 38 + 14 + 32 + 0.5064396588413711 0.4935603411586289 0.18909283838735527 0.8109071616126449 0.2587368488765082 0.7412631511234917 0.37325924405823685 0.626740755941763
+
+ + 39 + 9 + 31 + 27 + 0.5434977041822437 0.45650229581775625 0.022576895205636414 0.9774231047943636 0.8676965852125986 0.13230341478740137 0.5852366271844077 0.4147633728155923 0.5181578054031838 0.48184219459681626 0.6683185033041703 0.33168149669582975 0.39872227412123257 0.6012777258787675 0.6030614296404847 0.3969385703595154
+
+ + 40 + 5 + 0.5752315788107198 0.4247684211892801 0.7628713528566804 0.23712864714331966
+
+ + 41 + 0.6130364579771698 0.38696354202283034
+
+ + 42 + 0.3130408484464321 0.6869591515535679
+
+ + 43 + 0.460314040613683 0.539685959386317
+
+ + 44 + 18 + 20 + 9 + 0.5763047750369136 0.42369522496308637 0.7933177851340529 0.20668221486594704 0.23083220723294662 0.7691677927670534 0.4426400583073561 0.5573599416926439 0.37459293957706646 0.6254070604229336 0.08288397447627846 0.9171160255237215 0.5298564173680238 0.47014358263197625 0.22936152276323288 0.7706384772367673
+
+ + 45 + 21 + 0.30881339974014105 0.691186600259859 0.9770198866504733 0.02298011334952666
+
+ + 46 + 15 + 0.3634582800396628 0.6365417199603371 0.8080341681985267 0.19196583180147334
+
+ + 47 + 46 + 24 + 0.7124775367227402 0.2875224632772597 0.4919842183859091 0.5080157816140908 0.7310263348924182 0.26897366510758186 0.2307228582155016 0.7692771417844985
+
+ + 48 + 45 + 43 + 0.5770973739395915 0.4229026260604086 0.15496517756405115 0.8450348224359489 0.4350085624833653 0.5649914375166347 0.3069041298742455 0.6930958701257546
+
+ + 49 + 45 + 0.4021853088035782 0.5978146911964218 0.16895727219072393 0.8310427278092761
+
+ + 50 + 3 + 13 + 29 + 0.5609177128043485 0.43908228719565146 0.46114560895589235 0.5388543910441076 0.7856391313097293 0.2143608686902706 0.7132328113458501 0.2867671886541499 0.7952400651945867 0.20475993480541335 0.5039698576130563 0.4960301423869437 0.8879961974460134 0.11200380255398652 0.4369962288044716 0.5630037711955286
+
+ + 51 + 17 + 25 + 0.5278457642310757 0.47215423576892435 0.4219277296134504 0.5780722703865496 0.5447555632009953 0.4552444367990047 0.5123382949723647 0.4876617050276352
+
+ + 52 + 7 + 49 + 0.4058130424880246 0.5941869575119755 0.9610220518296383 0.038977948170361765 0.5545359057147083 0.4454640942852917 0.29772796207513164 0.7022720379248684
+
+ + 53 + 33 + 34 + 32 + 0.5150406090343882 0.4849593909656118 0.9721592032857368 0.027840796714263167 0.758374822936401 0.241625177063599 0.18750353835264139 0.8124964616473588 0.29231616469833793 0.7076838353016621 0.5776913534422894 0.4223086465577106 0.5541812513660946 0.4458187486339053 0.8713705310313393 0.12862946896866062
+
+ + 54 + 13 + 31 + 0.7095741171048958 0.2904258828951041 0.10587012770958829 0.8941298722904117 0.5977144833293235 0.4022855166706765 0.5112313141223562 0.4887686858776438
+
+ + 55 + 26 + 0.8593879973488675 0.14061200265113252 0.640511316734965 0.35948868326503497
+
+
+
diff --git a/testing/Part_2/network_58.XMLBIF b/testing/Part_2/network_58.XMLBIF new file mode 100644 index 00000000..357e052c --- /dev/null +++ b/testing/Part_2/network_58.XMLBIF @@ -0,0 +1,643 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.7296085313806163 0.2703914686193837
+
+ + 1 + 0.5587410581799829 0.4412589418200171
+
+ + 2 + 0.49271980695084844 0.5072801930491515
+
+ + 3 + 0.46274045770720296 0.537259542292797
+
+ + 4 + 0.896931038805407 0.10306896119459295
+
+ + 5 + 0.5967663969698845 0.40323360303011546
+
+ + 6 + 0.47037092268494196 0.5296290773150579
+
+ + 7 + 0.7639680581597151 0.23603194184028486
+
+ + 8 + 0.6297907752449766 0.37020922475502344
+
+ + 9 + 1 + 0.3173136762512018 0.6826863237487981 0.6874288155438804 0.3125711844561196
+
+ + 10 + 0.4699084867258037 0.5300915132741963
+
+ + 11 + 0.3947356509595216 0.6052643490404784
+
+ + 12 + 0.1807081358076083 0.8192918641923917
+
+ + 13 + 4 + 0.08835129667935232 0.9116487033206476 0.5086067631941902 0.4913932368058099
+
+ + 14 + 0.8200902172911784 0.17990978270882158
+
+ + 15 + 0.7553788352257016 0.24462116477429838
+
+ + 16 + 4 + 0.9133537561932549 0.08664624380674506 0.08451874788853984 0.9154812521114601
+
+ + 17 + 0.3933951314687424 0.6066048685312576
+
+ + 18 + 0.15169445683912364 0.8483055431608764
+
+ + 19 + 0.4445461236842484 0.5554538763157515
+
+ + 20 + 16 + 0.1248264440566088 0.8751735559433912 0.45002408214568507 0.5499759178543149
+
+ + 21 + 0.37274087728014277 0.6272591227198572
+
+ + 22 + 5 + 0.8106479457904091 0.1893520542095909 0.7577935590955152 0.24220644090448482
+
+ + 23 + 4 + 0.5736670419217483 0.4263329580782517 0.19078118431145516 0.8092188156885448
+
+ + 24 + 6 + 18 + 0.3211256116969524 0.6788743883030476 0.4807568071393118 0.5192431928606882 0.7164096580255465 0.2835903419744535 0.686913666370568 0.31308633362943195
+
+ + 25 + 1 + 13 + 12 + 0.13419283400955276 0.8658071659904473 0.12433914372139093 0.8756608562786091 0.49453974991223626 0.5054602500877637 0.7727032377362085 0.22729676226379142 0.3297214174202765 0.6702785825797235 0.6157863358783072 0.3842136641216928 0.5048930102192953 0.49510698978070466 0.8165163550931674 0.18348364490683255
+
+ + 26 + 0.47515819650070945 0.5248418034992905
+
+ + 27 + 11 + 0.18491615067737283 0.8150838493226271 0.4864089535537485 0.5135910464462515
+
+ + 28 + 25 + 2 + 17 + 0.3038386354097127 0.6961613645902874 0.43406100237717454 0.5659389976228255 0.566429964814591 0.4335700351854091 0.3719023430949845 0.6280976569050154 0.3172771982082604 0.6827228017917395 0.33235520820667674 0.6676447917933234 0.861815086284352 0.13818491371564798 0.5507186121176962 0.44928138788230376
+
+ + 29 + 0.4900680149358384 0.5099319850641616
+
+ + 30 + 0.6456045863307751 0.35439541366922483
+
+ + 31 + 4 + 0.23354019558409125 0.7664598044159089 0.4414025746106629 0.5585974253893371
+
+ + 32 + 0.9468973369567053 0.05310266304329473
+
+ + 33 + 32 + 0.6293000110979978 0.3706999889020021 0.12996747547963472 0.8700325245203653
+
+ + 34 + 0.4482353756502207 0.5517646243497794
+
+ + 35 + 6 + 10 + 20 + 0.414425514111716 0.585574485888284 0.5591513711413881 0.44084862885861187 0.6100482838001803 0.3899517161998198 0.16440449932225615 0.8355955006777439 0.7672246171735708 0.2327753828264292 0.6342718635897346 0.36572813641026547 0.40905428630927027 0.5909457136907298 0.43965790309296265 0.5603420969070374
+
+ + 36 + 19 + 0.674217133501529 0.32578286649847094 0.8859858210075985 0.11401417899240147
+
+ + 37 + 0.7812350842006476 0.21876491579935242
+
+ + 38 + 26 + 0.606638192677192 0.39336180732280807 0.25938904702892973 0.7406109529710702
+
+ + 39 + 3 + 38 + 0.09535381470942242 0.9046461852905776 0.8578425341464081 0.14215746585359193 0.6192342477078119 0.380765752292188 0.4560820496430606 0.5439179503569394
+
+ + 40 + 32 + 0.2739880877331088 0.7260119122668912 0.17876245208638028 0.8212375479136197
+
+ + 41 + 30 + 0.1606751660006531 0.8393248339993468 0.6389700506501118 0.36102994934988814
+
+ + 42 + 31 + 37 + 0.49894578983084614 0.501054210169154 0.15051233541463765 0.8494876645853624 0.8698442192894014 0.13015578071059858 0.24212835794966314 0.7578716420503369
+
+ + 43 + 1 + 25 + 3 + 16 + 11 + 33 + 0.6807898372209471 0.31921016277905306 0.760230158477527 0.23976984152247305 0.8285019109644794 0.17149808903552052 0.4674850858811551 0.5325149141188449 0.24761776246621509 0.752382237533785 0.6467440990779799 0.35325590092202014 0.8278210896392776 0.1721789103607224 0.6304815765874465 0.36951842341255353 0.2601102860601579 0.7398897139398422 0.5056605702069478 0.4943394297930521 0.5863594480287075 0.4136405519712925 0.36315528082142395 0.636844719178576 0.24902622031648974 0.7509737796835103 0.6393976787598988 0.3606023212401012 0.7455882145075242 0.2544117854924759 0.6259321217853248 0.37406787821467513 0.5468883138524894 0.4531116861475106 0.5226131476829055 0.47738685231709455 0.4668102783498952 0.5331897216501047 0.49230689551945417 0.5076931044805459 0.924542100561108 0.07545789943889207 0.14223659235786523 0.8577634076421348 0.34333980906056344 0.6566601909394366 0.3331255861799035 0.6668744138200965 0.7033950544884995 0.29660494551150046 0.6358718849646954 0.3641281150353046 0.4151342887583875 0.5848657112416125 0.32207799110417523 0.6779220088958248 0.3311805277441954 0.6688194722558046 0.9984328329414685 0.0015671670585315363 0.45992114775988663 0.5400788522401133 0.6638035271513264 0.3361964728486736 0.5439729862022816 0.4560270137977185 0.6591049048353539 0.34089509516464606 0.16485053896252433 0.8351494610374757 0.9472949248889412 0.05270507511105879 0.4268852003239011 0.5731147996760989 0.42605918122231645 0.5739408187776834 0.21539847893125963 0.7846015210687404 0.24135990928285064 0.7586400907171492 0.7896085802499428 0.21039141975005712 0.6252632237111073 0.3747367762888927 0.4996208156477822 0.5003791843522178 0.6811952617814048 0.31880473821859523 0.35785716507740967 0.6421428349225904 0.5716037330795434 0.4283962669204566 0.24004382824250906 0.7599561717574911 0.6150970161025572 0.3849029838974428 0.662156213584184 0.3378437864158159 0.26013025933730044 0.7398697406626996 0.3814336418739457 0.6185663581260543 0.900426424458662 0.09957357554133801 0.7672787946032764 0.2327212053967237 0.5486559550877448 0.4513440449122552 0.5396134807365361 0.4603865192634639 0.5367584735073271 0.463241526492673 0.9406729065784402 0.05932709342155981 0.035175273581452504 0.9648247264185474 0.9838462487520284 0.016153751247971568 0.460163506969267 0.5398364930307329 0.5158175327214454 0.4841824672785546 0.5613519369227226 0.4386480630772774 0.7321960789483474 0.26780392105165274 0.8158339917967206 0.18416600820327947
+
+ + 44 + 12 + 38 + 0.48751382365004053 0.5124861763499595 0.5081325684757582 0.4918674315242418 0.5306925068608993 0.4693074931391007 0.5013951027278784 0.49860489727212176
+
+ + 45 + 28 + 8 + 12 + 0.6077823711195781 0.392217628880422 0.5951998787746012 0.4048001212253987 0.8037856805678497 0.19621431943215026 0.6274554239446548 0.3725445760553452 0.2612112787704479 0.7387887212295522 0.5161592429341099 0.4838407570658902 0.28938689000186807 0.7106131099981319 0.2172914694347139 0.7827085305652861
+
+ + 46 + 11 + 0.4770593856312225 0.5229406143687775 0.12284527274686327 0.8771547272531367
+
+ + 47 + 0.633022966148177 0.3669770338518231
+
+ + 48 + 28 + 7 + 0.5718049976005288 0.4281950023994712 0.6713631872509692 0.3286368127490307 0.4395765140737655 0.5604234859262345 0.9417478705728971 0.05825212942710292
+
+ + 49 + 0 + 43 + 34 + 0.586368900218699 0.413631099781301 0.2287080574583297 0.7712919425416703 0.44619250845958436 0.5538074915404158 0.6421735773001641 0.3578264226998359 0.6969083863691221 0.30309161363087805 0.3168930260109708 0.6831069739890292 0.8315484559301024 0.16845154406989765 0.3065998040191709 0.6934001959808291
+
+ + 50 + 25 + 35 + 26 + 0.6516206022720393 0.34837939772796067 0.9442067413641647 0.05579325863583528 0.10809303035240998 0.89190696964759 0.4838650732956351 0.516134926704365 0.22186877119257015 0.7781312288074299 0.5752723343571544 0.4247276656428456 0.4849043290656323 0.5150956709343677 0.014246740476834064 0.985753259523166
+
+ + 51 + 0.14101860956628823 0.8589813904337118
+
+ + 52 + 40 + 0.405862170721209 0.594137829278791 0.8089193399095473 0.19108066009045263
+
+ + 53 + 6 + 52 + 0.18147249866847143 0.8185275013315287 0.37651134417952076 0.6234886558204793 0.32925834701046974 0.6707416529895303 0.5796179549379323 0.4203820450620678
+
+ + 54 + 35 + 7 + 0.1903128720477985 0.8096871279522014 0.8030303878776713 0.1969696121223287 0.012780359726622087 0.9872196402733779 0.5856979982528985 0.4143020017471015
+
+ + 55 + 25 + 0.4655245510422304 0.5344754489577695 0.17620942133721323 0.8237905786627867
+
+ + 56 + 23 + 5 + 55 + 0.585258320663522 0.414741679336478 0.40515920419424467 0.5948407958057553 0.6698497484435817 0.33015025155641836 0.8620273528294686 0.13797264717053143 0.1607848590231331 0.8392151409768669 0.5763911403515618 0.4236088596484382 0.653232051234303 0.34676794876569705 0.8822319652927818 0.11776803470721821
+
+ + 57 + 0.6733071003833566 0.32669289961664333
+
+
+
diff --git a/testing/Part_2/network_60.XMLBIF b/testing/Part_2/network_60.XMLBIF new file mode 100644 index 00000000..63e08d49 --- /dev/null +++ b/testing/Part_2/network_60.XMLBIF @@ -0,0 +1,654 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.07375833674159922 0.9262416632584007
+
+ + 1 + 0.41157206610256103 0.588427933897439
+
+ + 2 + 0.5575157329298424 0.44248426707015764
+
+ + 3 + 0.31719482693356676 0.6828051730664333
+
+ + 4 + 0.28171856165696996 0.71828143834303
+
+ + 5 + 0.603101829270352 0.39689817072964795
+
+ + 6 + 0.4374595184967578 0.5625404815032423
+
+ + 7 + 0.6982845993176022 0.3017154006823977
+
+ + 8 + 0.48175929602547346 0.5182407039745266
+
+ + 9 + 0.3431364589667414 0.6568635410332586
+
+ + 10 + 0.5785043399095415 0.4214956600904584
+
+ + 11 + 2 + 0.12085379842310401 0.879146201576896 0.22107084485066875 0.7789291551493313
+
+ + 12 + 5 + 9 + 0.2949538092952171 0.7050461907047828 0.4724645036706702 0.5275354963293297 0.18852894638187553 0.8114710536181244 0.14529676120415383 0.8547032387958462
+
+ + 13 + 4 + 0.5364670178486766 0.46353298215132344 0.07484566628275419 0.9251543337172459
+
+ + 14 + 0.6841472530456869 0.31585274695431315
+
+ + 15 + 7 + 0.9632156677514357 0.03678433224856426 0.4677315374842296 0.5322684625157704
+
+ + 16 + 0.2382420596471616 0.7617579403528384
+
+ + 17 + 0.1922997461743339 0.8077002538256661
+
+ + 18 + 8 + 0.7207476732108541 0.2792523267891459 0.5514795227754468 0.44852047722455335
+
+ + 19 + 0.24812381366265857 0.7518761863373414
+
+ + 20 + 0.21345881664671287 0.786541183353287
+
+ + 21 + 0.38628683362869193 0.613713166371308
+
+ + 22 + 8 + 10 + 0.35155150248423855 0.6484484975157614 0.7226805652319069 0.27731943476809306 0.6755701244214577 0.32442987557854225 0.33362196117327403 0.666378038826726
+
+ + 23 + 0.8497116145500851 0.15028838544991485
+
+ + 24 + 13 + 0.9116572305443809 0.08834276945561916 0.7527730907393292 0.2472269092606709
+
+ + 25 + 0.871015254831755 0.12898474516824496
+
+ + 26 + 0.3729807996442708 0.6270192003557292
+
+ + 27 + 0.36055240110345627 0.6394475988965437
+
+ + 28 + 11 + 0.3376756082674077 0.6623243917325923 0.4669869320109772 0.5330130679890228
+
+ + 29 + 1 + 5 + 0.6364822331184244 0.3635177668815756 0.5715962727872007 0.4284037272127992 0.7714138401093723 0.22858615989062767 0.4333980209818235 0.5666019790181765
+
+ + 30 + 11 + 0.6952261302020861 0.3047738697979137 0.45568336152233874 0.5443166384776613
+
+ + 31 + 0.6052527937037354 0.39474720629626464
+
+ + 32 + 28 + 0.0050768372274059325 0.9949231627725941 0.533741103127053 0.4662588968729471
+
+ + 33 + 31 + 0.7343534140885701 0.26564658591142976 0.516195660476963 0.4838043395230371
+
+ + 34 + 22 + 0.3747935407790183 0.6252064592209816 0.4249693403174422 0.5750306596825578
+
+ + 35 + 0.2220570852178301 0.7779429147821699
+
+ + 36 + 30 + 0.7526199237174437 0.24738007628255618 0.8336127507134717 0.16638724928652823
+
+ + 37 + 27 + 0.13232748123545637 0.8676725187645437 0.10951463758406983 0.8904853624159301
+
+ + 38 + 22 + 25 + 35 + 0.4774567368920555 0.5225432631079445 0.3480142935223079 0.651985706477692 0.11648158270464795 0.883518417295352 0.7743229192167286 0.22567708078327145 0.7299588675198189 0.27004113248018113 0.6583894599454255 0.3416105400545744 0.9710413033459341 0.028958696654065863 0.3097346488363804 0.6902653511636195
+
+ + 39 + 17 + 0.07473868996413577 0.9252613100358642 0.4257376061069013 0.5742623938930987
+
+ + 40 + 7 + 30 + 34 + 0.6470959317903966 0.35290406820960346 0.5485221218511491 0.451477878148851 0.6133792408072789 0.38662075919272104 0.0776446501591421 0.9223553498408579 0.4269075049533223 0.5730924950466777 0.6882617578522167 0.31173824214778334 0.9433728202338645 0.056627179766135474 0.5774729134775114 0.42252708652248855
+
+ + 41 + 0.3184965620828683 0.6815034379171317
+
+ + 42 + 2 + 0.7114898307947124 0.2885101692052877 0.4538040194439164 0.5461959805560835
+
+ + 43 + 42 + 9 + 32 + 0.5955782100810625 0.4044217899189375 0.7998293604661413 0.20017063953385875 0.7651711536339567 0.23482884636604326 0.43551163950736754 0.5644883604926325 0.6641555067989843 0.3358444932010158 0.22742650595946062 0.7725734940405394 0.3978644093034092 0.6021355906965908 0.11768807402925495 0.882311925970745
+
+ + 44 + 1 + 0.0950094234648721 0.9049905765351279 0.4186093256347161 0.5813906743652839
+
+ + 45 + 0.6359500995384272 0.3640499004615728
+
+ + 46 + 0.10920925045323941 0.8907907495467606
+
+ + 47 + 0.3555369355546024 0.6444630644453977
+
+ + 48 + 17 + 39 + 0.7913444949674154 0.20865550503258462 0.49385562063972627 0.5061443793602737 0.21584715549101352 0.7841528445089865 0.5457181303734611 0.4542818696265389
+
+ + 49 + 15 + 0.5216538728739722 0.4783461271260278 0.3943585877300807 0.6056414122699194
+
+ + 50 + 2 + 22 + 0.763908308615562 0.23609169138443803 0.3590955238401994 0.6409044761598006 0.5000114240701778 0.4999885759298222 0.8310621827544501 0.16893781724554993
+
+ + 51 + 49 + 0.4450980347599565 0.5549019652400435 0.5195006140781311 0.480499385921869
+
+ + 52 + 11 + 0.3293653316171823 0.6706346683828176 0.2969388784153131 0.7030611215846869
+
+ + 53 + 12 + 31 + 51 + 0.6469809184746007 0.3530190815253993 0.6281757233424471 0.3718242766575529 0.4255998332908115 0.5744001667091886 0.6105920773598221 0.3894079226401778 0.18188958221063622 0.8181104177893638 0.6555503398435284 0.34444966015647155 0.4221666409971936 0.5778333590028064 0.9857101895796229 0.014289810420377178
+
+ + 54 + 18 + 0.18522889627245223 0.8147711037275478 0.0716330880336586 0.9283669119663414
+
+ + 55 + 3 + 0.4735785056525242 0.5264214943474758 0.5480529759952188 0.4519470240047812
+
+ + 56 + 55 + 0.6746476722358019 0.32535232776419826 0.8830095154101073 0.11699048458989271
+
+ + 57 + 1 + 42 + 55 + 34 + 0.5248798585657789 0.4751201414342211 0.6200769862662818 0.37992301373371823 0.6745196837474106 0.3254803162525895 0.8406101897890469 0.15938981021095325 0.09426222834223194 0.905737771657768 0.24319635834548878 0.7568036416545111 0.06394299554381994 0.9360570044561801 0.6033831613119237 0.3966168386880762 0.06654360800382066 0.9334563919961794 0.30681557342931487 0.6931844265706851 0.25515021818062333 0.7448497818193767 0.5441266611947092 0.4558733388052908 0.4245867423836246 0.5754132576163754 0.9264598056944517 0.0735401943055483 0.1819389763170051 0.8180610236829949 0.6300418242881997 0.3699581757118003
+
+ + 58 + 39 + 0.7959469766014423 0.20405302339855771 0.9691487993728511 0.030851200627148863
+
+ + 59 + 0.47993136542395426 0.5200686345760458
+
+
+
diff --git a/testing/Part_2/network_62.XMLBIF b/testing/Part_2/network_62.XMLBIF new file mode 100644 index 00000000..0b08025a --- /dev/null +++ b/testing/Part_2/network_62.XMLBIF @@ -0,0 +1,690 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.4944166758977569 0.505583324102243
+
+ + 1 + 0.7417048805371453 0.25829511946285466
+
+ + 2 + 0.6330077948946657 0.3669922051053342
+
+ + 3 + 0.42831340379994515 0.5716865962000549
+
+ + 4 + 0.668994237652733 0.331005762347267
+
+ + 5 + 0.4020725423249834 0.5979274576750165
+
+ + 6 + 0.829393625716163 0.170606374283837
+
+ + 7 + 0 + 6 + 0.07468147304283475 0.9253185269571653 0.5623322479049728 0.43766775209502723 0.46918246501385735 0.5308175349861427 0.5251248062564325 0.4748751937435675
+
+ + 8 + 0 + 0.2646868502237835 0.7353131497762164 0.7373238326400068 0.26267616735999316
+
+ + 9 + 0.16969514668604527 0.8303048533139548
+
+ + 10 + 0.05147401365959051 0.9485259863404095
+
+ + 11 + 0.8692429724848363 0.13075702751516374
+
+ + 12 + 0.45835280728811106 0.541647192711889
+
+ + 13 + 0.3701790718116551 0.6298209281883449
+
+ + 14 + 0.7730741481103917 0.22692585188960837
+
+ + 15 + 0.4767511311234779 0.5232488688765222
+
+ + 16 + 7 + 0.8504748912842821 0.1495251087157179 0.45240552624315256 0.5475944737568474
+
+ + 17 + 1 + 0.1468443279889281 0.8531556720110719 0.6073399056886488 0.3926600943113512
+
+ + 18 + 0.2115248287443392 0.7884751712556608
+
+ + 19 + 0.6206443111247278 0.37935568887527216
+
+ + 20 + 0.3992955897286008 0.6007044102713991
+
+ + 21 + 0.6156788781344709 0.38432112186552914
+
+ + 22 + 0.24694438965807586 0.753055610341924
+
+ + 23 + 7 + 2 + 0.40799491239005264 0.5920050876099474 0.509753706110198 0.490246293889802 0.710166819497827 0.289833180502173 0.6827641701839511 0.3172358298160489
+
+ + 24 + 0.7106314479517687 0.28936855204823125
+
+ + 25 + 17 + 0.2067904701413737 0.7932095298586262 0.42283598707005454 0.5771640129299455
+
+ + 26 + 0.5206671572359491 0.4793328427640508
+
+ + 27 + 25 + 19 + 0.6033261508738643 0.3966738491261357 0.5781863685444987 0.4218136314555013 0.5374389623543281 0.4625610376456719 0.0202499216338182 0.9797500783661818
+
+ + 28 + 0.052575831251478355 0.9474241687485216
+
+ + 29 + 13 + 14 + 0.06179305420782067 0.9382069457921793 0.13253736515340514 0.8674626348465948 0.6207989326214869 0.37920106737851317 0.40557828278330665 0.5944217172166935
+
+ + 30 + 7 + 0.2846639618041139 0.7153360381958861 0.31563047437248604 0.684369525627514
+
+ + 31 + 0 + 4 + 26 + 0.5994353834628827 0.40056461653711734 0.5332086770202306 0.46679132297976933 0.40208999762543923 0.5979100023745608 0.6607306029664448 0.3392693970335552 0.09198648875393285 0.9080135112460671 0.9348827007092617 0.06511729929073833 0.5448421316542639 0.45515786834573624 0.2969176586677044 0.7030823413322956
+
+ + 32 + 0.5553487249510649 0.44465127504893515
+
+ + 33 + 7 + 6 + 30 + 15 + 27 + 0.6391639046938621 0.3608360953061379 0.6289561442518847 0.37104385574811527 0.3898541155298089 0.610145884470191 0.5760954645007555 0.42390453549924445 0.208187677221196 0.791812322778804 0.5148299238134805 0.48517007618651947 0.3176362434144646 0.6823637565855354 0.7367161865231359 0.26328381347686414 0.36979658078796424 0.6302034192120357 0.0708981931716757 0.9291018068283243 0.5802820550855022 0.41971794491449776 0.5922967463462727 0.4077032536537273 0.07760333443205501 0.922396665567945 0.3345502593023644 0.6654497406976356 0.38207632814672593 0.6179236718532741 0.42056579889671447 0.5794342011032855 0.23224549775878633 0.7677545022412137 0.038089102557397274 0.9619108974426027 0.3166164848497632 0.6833835151502369 0.5291383385104794 0.4708616614895206 0.3157738588661796 0.6842261411338204 0.8751924953376711 0.12480750466232889 0.8687908013264865 0.1312091986735135 0.6402339494230694 0.3597660505769306 0.1342324900532681 0.8657675099467319 0.5716035624170356 0.4283964375829644 0.5347189599779701 0.46528104002202986 0.13475967887212212 0.8652403211278779 0.16192307271869133 0.8380769272813087 0.686696539350393 0.313303460649607 0.40979304524592786 0.5902069547540721 0.22362430751226647 0.7763756924877335
+
+ + 34 + 0.49526350476069725 0.5047364952393028
+
+ + 35 + 20 + 28 + 0.502609075071797 0.4973909249282031 0.4630480364342866 0.5369519635657134 0.5020183366209303 0.4979816633790697 0.42635180675504597 0.573648193244954
+
+ + 36 + 31 + 23 + 0.5602112900985589 0.4397887099014412 0.4578283795462758 0.5421716204537242 0.5142879922365488 0.4857120077634513 0.27308799652846033 0.7269120034715396
+
+ + 37 + 16 + 36 + 0.3396141596942412 0.6603858403057589 0.4478687111057928 0.5521312888942072 0.37142866904961636 0.6285713309503836 0.31591687574972055 0.6840831242502795
+
+ + 38 + 10 + 29 + 0.9301597968362448 0.06984020316375518 0.6096883190906963 0.39031168090930374 0.4494519301926986 0.5505480698073014 0.20307785366874695 0.796922146331253
+
+ + 39 + 0.5711157658595987 0.4288842341404013
+
+ + 40 + 0.20902404328240257 0.7909759567175975
+
+ + 41 + 7 + 24 + 0.5082144762831127 0.49178552371688733 0.7346618691322385 0.26533813086776153 0.3277644134428857 0.6722355865571142 0.3100749277798922 0.6899250722201078
+
+ + 42 + 30 + 26 + 0.4747767341194191 0.5252232658805809 0.5976984201496323 0.40230157985036763 0.3152382483192618 0.6847617516807383 0.43282726963498214 0.5671727303650178
+
+ + 43 + 14 + 18 + 0.23805548197668835 0.7619445180233116 0.48420367034651585 0.5157963296534842 0.05760610085587717 0.9423938991441229 0.41702123741864716 0.5829787625813528
+
+ + 44 + 27 + 42 + 0.5356860090588883 0.46431399094111175 0.34019285091392387 0.6598071490860762 0.2458095422819855 0.7541904577180146 0.5837730829992971 0.4162269170007029
+
+ + 45 + 11 + 0.5293846116500088 0.4706153883499912 0.26674211536778936 0.7332578846322106
+
+ + 46 + 0.4719920175024604 0.5280079824975397
+
+ + 47 + 0.9357544995394542 0.06424550046054579
+
+ + 48 + 14 + 0.44250797890748644 0.5574920210925135 0.743216986711241 0.2567830132887589
+
+ + 49 + 8 + 5 + 45 + 13 + 0.5151692204411907 0.4848307795588092 0.37063326655355544 0.6293667334464446 0.5365940942892476 0.4634059057107524 0.8805084859156822 0.11949151408431778 0.41371393299242804 0.586286067007572 0.22443657906280506 0.775563420937195 0.5397733003271802 0.46022669967281976 0.25409052483978206 0.745909475160218 0.5099729990270591 0.490027000972941 0.5647775799409954 0.4352224200590046 0.3154599686504461 0.6845400313495539 0.8998216103324524 0.10017838966754754 0.6843688016756474 0.31563119832435266 0.5593950566618938 0.44060494333810624 0.299317581409063 0.7006824185909369 0.7513105048747825 0.2486894951252175
+
+ + 50 + 6 + 0.6002288774734934 0.39977112252650654 0.19020866726921862 0.8097913327307814
+
+ + 51 + 8 + 0.24234738017810073 0.7576526198218992 0.7897957191938917 0.21020428080610845
+
+ + 52 + 23 + 50 + 0.4751208629525827 0.5248791370474172 0.36044168372214663 0.6395583162778534 0.5280443603160149 0.47195563968398513 0.35384096344477484 0.6461590365552252
+
+ + 53 + 23 + 0.18625634564290397 0.8137436543570961 0.9620270957464027 0.03797290425359736
+
+ + 54 + 2 + 0.3149380879849354 0.6850619120150646 0.24667725599579887 0.7533227440042011
+
+ + 55 + 17 + 30 + 0.26920226505827977 0.7307977349417203 0.12597854693499572 0.8740214530650043 0.47497571255849497 0.525024287441505 0.5777120451284529 0.42228795487154713
+
+ + 56 + 31 + 43 + 15 + 0.49421284471391463 0.5057871552860854 0.015501718419680134 0.9844982815803198 0.4992416110711596 0.5007583889288404 0.7331175055813635 0.26688249441863643 0.38959931507718204 0.610400684922818 0.2607061716433249 0.7392938283566751 0.5847302252647221 0.4152697747352779 0.2686133196784024 0.7313866803215976
+
+ + 57 + 11 + 48 + 39 + 0.26754146809635987 0.7324585319036401 0.933514347703961 0.0664856522960391 0.041366201713213625 0.9586337982867864 0.2008864878072229 0.799113512192777 0.05263054062228186 0.9473694593777181 0.7538483515769736 0.24615164842302628 0.5240367042007513 0.4759632957992487 0.5188184494631767 0.48118155053682327
+
+ + 58 + 42 + 0.5073774108792621 0.49262258912073786 0.36236064700083515 0.6376393529991649
+
+ + 59 + 50 + 51 + 14 + 0.3338779368674939 0.6661220631325061 0.08324980306697548 0.9167501969330245 0.4492613166447931 0.550738683355207 0.1523467141482817 0.8476532858517183 0.3175895204079392 0.6824104795920608 0.7030693894171204 0.2969306105828796 0.37414955592177185 0.6258504440782281 0.4977822405325974 0.5022177594674027
+
+ + 60 + 0.12267367258345335 0.8773263274165467
+
+ + 61 + 57 + 35 + 58 + 0.4205392051119072 0.5794607948880928 0.45980706533045484 0.5401929346695451 0.465349505839887 0.534650494160113 0.5032638947986678 0.49673610520133216 0.8906154298964324 0.10938457010356763 0.7548396651267819 0.2451603348732181 0.05732672852623303 0.942673271473767 0.39533218010260696 0.6046678198973929
+
+
+
diff --git a/testing/Part_2/network_64.XMLBIF b/testing/Part_2/network_64.XMLBIF new file mode 100644 index 00000000..21866530 --- /dev/null +++ b/testing/Part_2/network_64.XMLBIF @@ -0,0 +1,698 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.8391745458715799 0.16082545412842003
+
+ + 1 + 0.26319568623263195 0.736804313767368
+
+ + 2 + 0.46271467254421517 0.5372853274557848
+
+ + 3 + 0.7314215532967111 0.2685784467032888
+
+ + 4 + 0.7278566224240346 0.2721433775759654
+
+ + 5 + 0.06708277629194938 0.9329172237080506
+
+ + 6 + 0.005949710047051118 0.9940502899529489
+
+ + 7 + 0.23017288330555988 0.7698271166944402
+
+ + 8 + 0.7343914316537852 0.2656085683462148
+
+ + 9 + 0.09758096295872408 0.9024190370412759
+
+ + 10 + 0.45106190068589297 0.5489380993141071
+
+ + 11 + 0.08380891138737583 0.9161910886126242
+
+ + 12 + 0.5547101423165464 0.4452898576834536
+
+ + 13 + 0.006654729811569634 0.9933452701884303
+
+ + 14 + 0.2731904361166668 0.7268095638833332
+
+ + 15 + 0.26407398486035344 0.7359260151396466
+
+ + 16 + 0.3228071451809799 0.67719285481902
+
+ + 17 + 0.15925725014706604 0.840742749852934
+
+ + 18 + 17 + 0.5090923152620813 0.4909076847379187 0.5719225521980356 0.4280774478019645
+
+ + 19 + 0.4962775080309823 0.5037224919690177
+
+ + 20 + 0.1402022108077294 0.8597977891922706
+
+ + 21 + 0.9586226358839538 0.0413773641160462
+
+ + 22 + 0.22252309802691508 0.7774769019730849
+
+ + 23 + 0.882504321454509 0.11749567854549113
+
+ + 24 + 0 + 16 + 0.7216543069143491 0.27834569308565094 0.47194858918019267 0.5280514108198074 0.49719317093833226 0.5028068290616677 0.019713978132266316 0.9802860218677337
+
+ + 25 + 0.7431809538365225 0.25681904616347745
+
+ + 26 + 0.4202489901370081 0.5797510098629919
+
+ + 27 + 0.8258691961921852 0.17413080380781482
+
+ + 28 + 0.39208611758081496 0.6079138824191851
+
+ + 29 + 17 + 0.6704247282942414 0.3295752717057587 0.9424667636100992 0.05753323638990077
+
+ + 30 + 2 + 18 + 28 + 0.2721004537530685 0.7278995462469315 0.7164946971310701 0.28350530286892994 0.7592678140506701 0.24073218594932988 0.8017819766508031 0.1982180233491969 0.271583654189525 0.728416345810475 0.48660726177350194 0.513392738226498 0.8137874965721407 0.18621250342785933 0.5806639107055921 0.41933608929440785
+
+ + 31 + 0.25914755105792436 0.7408524489420757
+
+ + 32 + 28 + 0.07319959837180741 0.9268004016281925 0.5711418414302368 0.4288581585697631
+
+ + 33 + 0.8478793870086592 0.1521206129913408
+
+ + 34 + 0.5229460536977489 0.477053946302251
+
+ + 35 + 0.66087427710042 0.33912572289958004
+
+ + 36 + 23 + 0.6551727384684242 0.34482726153157583 0.7318070502890511 0.2681929497109488
+
+ + 37 + 2 + 8 + 34 + 0.7979655339026773 0.20203446609732267 0.5397822342944701 0.4602177657055299 0.12191428693173836 0.8780857130682617 0.698698133814658 0.30130186618534205 0.6737882621684712 0.3262117378315288 0.334500898881922 0.665499101118078 0.5619708970670652 0.43802910293293484 0.521564942804245 0.47843505719575496
+
+ + 38 + 0.7472611508058119 0.2527388491941881
+
+ + 39 + 0.6437516596336965 0.3562483403663035
+
+ + 40 + 23 + 0.49158229719961716 0.5084177028003829 0.6496493315254773 0.35035066847452256
+
+ + 41 + 14 + 26 + 0.8037063547324816 0.19629364526751839 0.2727719902924173 0.7272280097075827 0.4234161560365322 0.5765838439634677 0.7060693416099108 0.2939306583900892
+
+ + 42 + 12 + 41 + 21 + 26 + 0.6212754418053 0.3787245581947001 0.4981730576648291 0.5018269423351709 0.9519580664369439 0.048041933563056125 0.9700223666216484 0.029977633378351614 0.2367720679013172 0.7632279320986827 0.5874800692554794 0.41251993074452065 0.09868473540775989 0.9013152645922401 0.32954082712664884 0.6704591728733511 0.5961980958695033 0.40380190413049655 0.9257799843944894 0.07422001560551061 0.572337317216463 0.427662682783537 0.7216559593571661 0.27834404064283397 0.5153644098802831 0.4846355901197168 0.6301379312119455 0.3698620687880545 0.9428066939218869 0.05719330607811308 0.8795037037071706 0.12049629629282943
+
+ + 43 + 0 + 26 + 0.7158346615954437 0.2841653384045564 0.6947985801582753 0.3052014198417246 0.8145379655215439 0.18546203447845616 0.21853591508933454 0.7814640849106654
+
+ + 44 + 0.598884201246062 0.401115798753938
+
+ + 45 + 10 + 0.19942745457423583 0.8005725454257642 0.7465035640554171 0.253496435944583
+
+ + 46 + 45 + 16 + 23 + 38 + 0.9312211768137222 0.06877882318627783 0.10863832965387032 0.8913616703461297 0.26308436650012984 0.7369156334998702 0.42759472503196283 0.5724052749680372 0.5635198985882979 0.43648010141170207 0.6237944074735963 0.3762055925264038 0.020435919706253077 0.979564080293747 0.10018921223614269 0.8998107877638574 0.052879178694073874 0.9471208213059261 0.21649906348044917 0.7835009365195508 0.6225681570062082 0.37743184299379184 0.09595009759461684 0.9040499024053832 0.525757177165001 0.47424282283499897 0.49057832802672025 0.5094216719732797 0.7793683793847604 0.2206316206152395 0.142049958578336 0.857950041421664
+
+ + 47 + 43 + 34 + 0.5002517588235963 0.4997482411764037 0.768000356884298 0.231999643115702 0.2126387011233865 0.7873612988766135 0.4561541688042362 0.5438458311957639
+
+ + 48 + 0.10234029489420658 0.8976597051057934
+
+ + 49 + 45 + 31 + 0.31860898256230347 0.6813910174376965 0.2772494895863863 0.7227505104136137 0.14155117700040798 0.8584488229995919 0.24066569903820886 0.7593343009617911
+
+ + 50 + 39 + 0.5136203578544108 0.4863796421455891 0.5380946213190191 0.4619053786809809
+
+ + 51 + 0.2614221824862375 0.7385778175137625
+
+ + 52 + 18 + 0.17220484458639362 0.8277951554136063 0.296210212927026 0.703789787072974
+
+ + 53 + 46 + 0.4561005856006557 0.5438994143993443 0.7655086649288083 0.23449133507119163
+
+ + 54 + 0 + 48 + 0.6641736598133324 0.3358263401866675 0.1401524855717917 0.8598475144282083 0.7616132366496066 0.23838676335039347 0.83915201564815 0.16084798435185005
+
+ + 55 + 29 + 0.6372648727001147 0.3627351272998853 0.7290475551375966 0.27095244486240344
+
+ + 56 + 40 + 0.005089450964144023 0.994910549035856 0.9749480541566747 0.02505194584332524
+
+ + 57 + 8 + 22 + 0.7583826076080097 0.24161739239199037 0.9229437663542874 0.07705623364571255 0.6122333516027744 0.3877666483972257 0.681882233893851 0.31811776610614884
+
+ + 58 + 0.3094721587296505 0.6905278412703494
+
+ + 59 + 22 + 38 + 0.5837676861941372 0.4162323138058628 0.18032319521081544 0.8196768047891846 0.7885174758094615 0.2114825241905385 0.5170228619658007 0.48297713803419934
+
+ + 60 + 0.6924269478714603 0.30757305212853964
+
+ + 61 + 46 + 0.6320599333075081 0.3679400666924919 0.48151358317718523 0.5184864168228148
+
+ + 62 + 6 + 19 + 51 + 0.3603962191840812 0.6396037808159188 0.46008128311969804 0.539918716880302 0.6745061204420758 0.3254938795579241 0.4278339537235571 0.5721660462764429 0.9401922934142399 0.05980770658576021 0.19995174082039963 0.8000482591796003 0.16664676288914526 0.8333532371108547 0.5787436417346724 0.42125635826532765
+
+ + 63 + 43 + 2 + 5 + 7 + 8 + 45 + 32 + 0.830267821379194 0.16973217862080603 0.6591012488048912 0.3408987511951088 0.7627414728098088 0.23725852719019117 0.4751134994924918 0.5248865005075082 0.060085620114080106 0.9399143798859199 0.33605485040621846 0.6639451495937815 0.4224694271825079 0.577530572817492 0.8328500135925468 0.16714998640745313 0.7496735725653646 0.2503264274346354 0.9810086105511956 0.018991389448804453 0.5191623776363168 0.48083762236368316 0.48830816386655435 0.5116918361334456 0.47860056246042637 0.5213994375395736 0.6403418181495387 0.3596581818504613 0.5366158419533815 0.4633841580466184 0.3441785581431563 0.6558214418568437 0.20209054817971883 0.7979094518202812 0.5920015590604595 0.4079984409395405 0.4746688414302345 0.5253311585697655 0.5132607141774961 0.486739285822504 0.7438671408847244 0.2561328591152757 0.9924931118534763 0.007506888146523627 0.977933078939501 0.022066921060498967 0.9277054302070603 0.0722945697929397 0.34571950128397005 0.6542804987160299 0.31205235549463034 0.6879476445053697 0.4556740855371056 0.5443259144628945 0.5601528064637074 0.43984719353629265 0.3756658830255996 0.6243341169744004 0.5264610081968059 0.47353899180319414 0.817064603679437 0.182935396320563 0.4727424861827579 0.5272575138172422 0.15936095396116062 0.8406390460388394 0.449546444892518 0.5504535551074821 0.15595424691421242 0.8440457530857876 0.2572050206253917 0.7427949793746084 0.6753430997762154 0.3246569002237845 0.7102296073068358 0.2897703926931641 0.23232604293236864 0.7676739570676314 0.6751499949729384 0.32485000502706163 0.8765561068707423 0.12344389312925776 0.5927132513808148 0.4072867486191851 0.3683985998265755 0.6316014001734245 0.9113202860244293 0.08867971397557073 0.5146932971463287 0.4853067028536712 0.6310150018062466 0.3689849981937534 0.3317765261575718 0.6682234738424283 0.4640176987266376 0.5359823012733624 0.4889358509046499 0.51106414909535 0.5162940290856307 0.48370597091436923 0.7518460848572333 0.24815391514276672 0.1942360244868485 0.8057639755131515 0.4624062189846547 0.5375937810153453 0.8223912536273905 0.17760874637260946 0.3850060215894704 0.6149939784105296 0.47273247154235204 0.527267528457648 0.38327783784512914 0.6167221621548707 0.5846356996337596 0.41536430036624034 0.7541628959498197 0.24583710405018028 0.12810556369551146 0.8718944363044886 0.8578252628091643 0.14217473719083568 0.2956490517341351 0.7043509482658649 0.6381909045432722 0.36180909545672774 0.622285312424722 0.37771468757527804 0.13272947594773105 0.867270524052269 0.5730299294877699 0.42697007051223007 0.5771716724451934 0.42282832755480665 0.8862382358796761 0.11376176412032386 0.04887952270843465 0.9511204772915653 0.81362261650618 0.1863773834938201 0.03393224037754494 0.9660677596224551 0.34563248619535386 0.6543675138046462 0.6096032514706026 0.3903967485293974 0.6900467460129774 0.30995325398702256 0.6502293469754594 0.3497706530245405 0.7210531178550638 0.27894688214493624 0.5838096169014697 0.4161903830985302 0.4828011750690928 0.5171988249309072 0.21211633012413744 0.7878836698758626 0.1623340121980154 0.8376659878019846 0.4858076988840834 0.5141923011159166 0.7480892288993527 0.2519107711006473 0.4738225081726953 0.5261774918273048 0.6462041922007472 0.35379580779925285 0.19935825732580353 0.8006417426741964 0.5602464190888361 0.43975358091116395 0.21340581404653616 0.7865941859534638 0.31765641326548644 0.6823435867345136 0.7527206251112196 0.24727937488878035 0.14964985605264416 0.8503501439473559 0.4995665880054966 0.5004334119945034 0.712849208831525 0.2871507911684749 0.4273475259413861 0.5726524740586139 0.5631830190114021 0.4368169809885978 0.6123829609667805 0.3876170390332196 0.6223811166853417 0.37761888331465837 0.7570722757964637 0.24292772420353625 0.570987029848169 0.42901297015183104 0.37634317750937774 0.6236568224906223 0.6721163422899106 0.32788365771008954 0.8874909960412845 0.1125090039587155 0.25169342036264925 0.7483065796373508 0.5522238573613681 0.44777614263863186 0.6296112077126764 0.3703887922873235 0.5940586931015017 0.40594130689849833 0.5315878085637161 0.46841219143628393 0.17917212965886975 0.8208278703411303 0.9616047275282459 0.03839527247175415 0.7105472364547032 0.28945276354529687 0.4544797881056033 0.5455202118943967 0.28813219645631294 0.7118678035436871 0.5070125916075927 0.49298740839240734 0.5625128696064641 0.4374871303935359 0.24633611519193885 0.7536638848080611 0.7682304910212854 0.2317695089787146 0.4295390008941165 0.5704609991058834 0.5766988468138516 0.4233011531861483 0.5797170326076381 0.4202829673923619 0.9652023787280138 0.03479762127198616 0.3570908866915522 0.6429091133084478 0.7836230264586356 0.21637697354136437 0.8096050737689402 0.19039492623105977 0.25581491681415686 0.7441850831858431 0.5062238891009013 0.4937761108990986 0.6656268639385292 0.3343731360614708 0.4459898869885298 0.5540101130114702 0.24391851270778958 0.7560814872922105 0.44868210471503134 0.5513178952849688
+
+
+
diff --git a/testing/Part_2/network_66.XMLBIF b/testing/Part_2/network_66.XMLBIF new file mode 100644 index 00000000..287b662e --- /dev/null +++ b/testing/Part_2/network_66.XMLBIF @@ -0,0 +1,722 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 64 + 0 + 1 + weight = None + + + 65 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.41529311693909243 0.5847068830609075
+
+ + 1 + 0.9791386175998656 0.020861382400134354
+
+ + 2 + 0.6981405478103715 0.3018594521896284
+
+ + 3 + 0.06623243004486826 0.9337675699551318
+
+ + 4 + 0.4113822263625325 0.5886177736374675
+
+ + 5 + 0.4808099867577773 0.5191900132422227
+
+ + 6 + 0.13746596199087746 0.8625340380091225
+
+ + 7 + 0.48512075609712463 0.5148792439028753
+
+ + 8 + 0.13591060688379086 0.8640893931162091
+
+ + 9 + 0.902637018909555 0.0973629810904451
+
+ + 10 + 8 + 0.07787151267217596 0.922128487327824 0.4083817188385969 0.5916182811614031
+
+ + 11 + 0.4207250076080375 0.5792749923919625
+
+ + 12 + 4 + 0.53887042621871 0.4611295737812901 0.2750341263190075 0.7249658736809926
+
+ + 13 + 0.15557139839007555 0.8444286016099245
+
+ + 14 + 0.9023422344734705 0.09765776552652947
+
+ + 15 + 0 + 0.7439316955739143 0.25606830442608575 0.20075213822897878 0.7992478617710213
+
+ + 16 + 0 + 0.17256997830896378 0.8274300216910362 0.029209592256156776 0.9707904077438432
+
+ + 17 + 0.8499472336775968 0.1500527663224031
+
+ + 18 + 10 + 0.558855749534837 0.44114425046516303 0.6222552006018985 0.37774479939810135
+
+ + 19 + 0.615309330311226 0.38469066968877386
+
+ + 20 + 13 + 0.8128904702770782 0.18710952972292186 0.5178941099100767 0.48210589008992344
+
+ + 21 + 0.7545634625853015 0.2454365374146985
+
+ + 22 + 0 + 0.2339474772948569 0.766052522705143 0.6045970478496926 0.3954029521503074
+
+ + 23 + 0.2867913234532752 0.7132086765467248
+
+ + 24 + 0.7277631764766677 0.2722368235233324
+
+ + 25 + 0.4957722992286832 0.5042277007713167
+
+ + 26 + 0.4224801561633916 0.5775198438366084
+
+ + 27 + 0.9348154969129835 0.06518450308701652
+
+ + 28 + 23 + 0.5159189659642351 0.48408103403576486 0.33073721920999827 0.6692627807900018
+
+ + 29 + 0.15125767453242647 0.8487423254675736
+
+ + 30 + 0.03145116859485892 0.968548831405141
+
+ + 31 + 16 + 6 + 14 + 0.6962578885208731 0.30374211147912683 0.2654822438663799 0.7345177561336201 0.39681219816075247 0.6031878018392475 0.044821991184114396 0.9551780088158857 0.5406303333320697 0.4593696666679302 0.3361479896824906 0.6638520103175094 0.3070726349192997 0.6929273650807003 0.34266914350896605 0.6573308564910338
+
+ + 32 + 2 + 0.617853483546509 0.38214651645349096 0.7560613897416552 0.24393861025834485
+
+ + 33 + 19 + 28 + 0.8051491618053378 0.19485083819466215 0.06554107155041693 0.9344589284495831 0.6374315531122544 0.3625684468877456 0.5579680092919053 0.44203199070809474
+
+ + 34 + 0.4791196145994841 0.520880385400516
+
+ + 35 + 0.4968800047651882 0.5031199952348119
+
+ + 36 + 0.458447775117749 0.541552224882251
+
+ + 37 + 19 + 0.3225214194127729 0.6774785805872272 0.6939649985091803 0.3060350014908198
+
+ + 38 + 32 + 0.6897915492670847 0.31020845073291525 0.9032287577649691 0.09677124223503084
+
+ + 39 + 37 + 0.6884816899739538 0.3115183100260462 0.8775009004017847 0.12249909959821524
+
+ + 40 + 14 + 26 + 39 + 0.46106373205783324 0.5389362679421666 0.8209819673271217 0.17901803267287833 0.5109392884670706 0.4890607115329294 0.5103313204057366 0.48966867959426325 0.010188458596239543 0.9898115414037605 0.13334850560393977 0.8666514943960603 0.3916930125079744 0.6083069874920256 0.9955914335466012 0.004408566453398792
+
+ + 41 + 0.2812230719546717 0.7187769280453283
+
+ + 42 + 4 + 31 + 29 + 0.20689427895481471 0.7931057210451852 0.9008509608937779 0.09914903910622208 0.463129253436573 0.5368707465634269 0.4240950827285723 0.5759049172714278 0.8022720469366149 0.19772795306338514 0.7322091517599595 0.2677908482400405 0.6368744599712715 0.36312554002872854 0.6483168540915114 0.35168314590848854
+
+ + 43 + 0.5024898724822878 0.4975101275177121
+
+ + 44 + 0.7656291284144322 0.23437087158556782
+
+ + 45 + 30 + 0.7083939675099036 0.2916060324900964 0.965343354307865 0.034656645692135016
+
+ + 46 + 33 + 0.661901885795415 0.3380981142045851 0.5295065714907528 0.47049342850924714
+
+ + 47 + 6 + 9 + 37 + 0.5415045635363118 0.4584954364636882 0.8118402864346739 0.18815971356532613 0.36448883920823805 0.635511160791762 0.6197120177918363 0.3802879822081637 0.15001301485883997 0.84998698514116 0.38941204543817176 0.6105879545618282 0.023825375013530836 0.9761746249864691 0.20671275060007938 0.7932872493999207
+
+ + 48 + 0.5032203552658234 0.49677964473417646
+
+ + 49 + 4 + 0.8914542207549483 0.10854577924505177 0.5490006885832549 0.4509993114167451
+
+ + 50 + 11 + 19 + 0.13364108023197907 0.8663589197680209 0.6145309444671874 0.3854690555328126 0.8872955638772055 0.11270443612279434 0.5318282048300169 0.4681717951699831
+
+ + 51 + 47 + 50 + 33 + 48 + 0.3604501892138396 0.6395498107861605 0.586237334461601 0.4137626655383991 0.9433989157874847 0.056601084212515286 0.3736559870897326 0.6263440129102674 0.30244514266003386 0.6975548573399661 0.40411627324576704 0.595883726754233 0.7911570494430593 0.20884295055694083 0.6051639879953641 0.3948360120046359 0.31292366489436685 0.6870763351056332 0.3960791374584665 0.6039208625415335 0.20496790992350983 0.7950320900764902 0.5447294768625397 0.4552705231374603 0.06846156873719651 0.9315384312628034 0.647539686279893 0.35246031372010694 0.37773374072273647 0.6222662592772635 0.4017993773159502 0.5982006226840498
+
+ + 52 + 41 + 0.6712185530388043 0.32878144696119566 0.22814027884981747 0.7718597211501824
+
+ + 53 + 42 + 25 + 0.709784697272942 0.29021530272705803 0.5541800839161437 0.4458199160838564 0.7090252357252228 0.29097476427477725 0.4675640965952409 0.532435903404759
+
+ + 54 + 19 + 0.5526685516120072 0.4473314483879928 0.7495558209382656 0.2504441790617344
+
+ + 55 + 33 + 35 + 0.19612152630414073 0.8038784736958593 0.7770561215868524 0.2229438784131475 0.01943148631864036 0.9805685136813597 0.05686334373412435 0.9431366562658756
+
+ + 56 + 47 + 0.34641061926163763 0.6535893807383624 0.20670198964294206 0.7932980103570579
+
+ + 57 + 0.6123103559895036 0.3876896440104964
+
+ + 58 + 2 + 10 + 13 + 20 + 35 + 0.4047771223369751 0.595222877663025 0.5558848160012105 0.4441151839987895 0.568691026550438 0.43130897344956204 0.48090677655322456 0.5190932234467753 0.478936097994987 0.5210639020050131 0.10880512785587092 0.8911948721441291 0.7628418086039443 0.2371581913960557 0.19865888142143964 0.8013411185785604 0.3106338088751208 0.6893661911248792 0.5654476320684604 0.4345523679315397 0.2028494654943287 0.7971505345056712 0.17014036927785547 0.8298596307221445 0.6170182733198475 0.38298172668015246 0.12440301957232218 0.8755969804276779 0.3547098036605228 0.6452901963394772 0.1654393127524762 0.8345606872475239 0.632106244589605 0.3678937554103951 0.7244096134100172 0.2755903865899828 0.9174779773716395 0.08252202262836048 0.7019660087630529 0.2980339912369471 0.48854559360820116 0.511454406391799 0.5623384093531397 0.4376615906468603 0.6444064030003199 0.3555935969996802 0.8549592002670594 0.14504079973294048 0.7653802019560908 0.23461979804390928 0.1721278413095275 0.8278721586904725 0.5304701094294885 0.4695298905705116 0.5366752038811984 0.4633247961188016 0.34693628634471074 0.6530637136552893 0.49270027638608577 0.5072997236139143 0.5378662155662188 0.46213378443378117 0.32887843537717193 0.6711215646228281
+
+ + 59 + 15 + 0.43916465214856737 0.5608353478514326 0.6866648770943609 0.31333512290563914
+
+ + 60 + 33 + 0.0823567926881704 0.9176432073118295 0.5676895229468757 0.43231047705312436
+
+ + 61 + 3 + 10 + 0.7255684637191295 0.2744315362808705 0.8135073734707345 0.1864926265292654 0.942443094172984 0.057556905827016024 0.6123395180206789 0.3876604819793211
+
+ + 62 + 0.6633930954136682 0.33660690458633186
+
+ + 63 + 45 + 0.5652510264785121 0.4347489735214878 0.47978954031323573 0.5202104596867643
+
+ + 64 + 38 + 0.428262431555679 0.571737568444321 0.7348223101726268 0.2651776898273732
+
+ + 65 + 22 + 52 + 44 + 0.6322808773325065 0.3677191226674936 0.5295253333339505 0.4704746666660496 0.012303153285412118 0.9876968467145879 0.3749458838978105 0.6250541161021895 0.7403256222999381 0.25967437770006185 0.3238799594877158 0.6761200405122842 0.6699101570050496 0.33008984299495037 0.8038434380024757 0.1961565619975243
+
+
+
diff --git a/testing/Part_2/network_68.XMLBIF b/testing/Part_2/network_68.XMLBIF new file mode 100644 index 00000000..8972faf2 --- /dev/null +++ b/testing/Part_2/network_68.XMLBIF @@ -0,0 +1,754 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 64 + 0 + 1 + weight = None + + + 65 + 0 + 1 + weight = None + + + 66 + 0 + 1 + weight = None + + + 67 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.28399536493081073 0.7160046350691892
+
+ + 1 + 0.9693709327797526 0.0306290672202474
+
+ + 2 + 0.7523384775607985 0.24766152243920145
+
+ + 3 + 0.5864732719120004 0.4135267280879996
+
+ + 4 + 0.38073148914987603 0.619268510850124
+
+ + 5 + 0.8158610758850791 0.18413892411492092
+
+ + 6 + 0.17796239932548294 0.822037600674517
+
+ + 7 + 0.6228471366864705 0.3771528633135295
+
+ + 8 + 0.5784437841581038 0.4215562158418961
+
+ + 9 + 0.014668648235687465 0.9853313517643125
+
+ + 10 + 0.6659306248585913 0.33406937514140855
+
+ + 11 + 0.46091952630639355 0.5390804736936065
+
+ + 12 + 0.4514468220971848 0.5485531779028152
+
+ + 13 + 0.6098368295639837 0.39016317043601634
+
+ + 14 + 0.5459209616986946 0.45407903830130536
+
+ + 15 + 0.5748788179375819 0.42512118206241806
+
+ + 16 + 0.5641880272815071 0.435811972718493
+
+ + 17 + 0 + 7 + 0.6655469196185924 0.33445308038140764 0.8225926291468333 0.17740737085316668 0.2770868660686449 0.722913133931355 0.4220932934492396 0.5779067065507605
+
+ + 18 + 0.8436020860320155 0.15639791396798455
+
+ + 19 + 0.7814276485619864 0.21857235143801362
+
+ + 20 + 14 + 0.9312612795840784 0.06873872041592158 0.7843767053031895 0.2156232946968105
+
+ + 21 + 19 + 0.13814163114513175 0.8618583688548683 0.5961982963603624 0.40380170363963763
+
+ + 22 + 2 + 13 + 0.5292608881128383 0.4707391118871617 0.004145499934576919 0.9958545000654231 0.6700160369651772 0.3299839630348227 0.22019852908688783 0.7798014709131121
+
+ + 23 + 0.20205523293926902 0.7979447670607309
+
+ + 24 + 0.37400349201473115 0.6259965079852687
+
+ + 25 + 8 + 18 + 0.9922850681912799 0.00771493180872012 0.7667853752699517 0.23321462473004834 0.8159185849558664 0.18408141504413356 0.19328765372894713 0.8067123462710529
+
+ + 26 + 1 + 7 + 0.24086082466183628 0.7591391753381638 0.7198404197406849 0.28015958025931503 0.7015895403133776 0.2984104596866224 0.6975285589240154 0.30247144107598456
+
+ + 27 + 0.13423545804426223 0.8657645419557377
+
+ + 28 + 0.20694930915426413 0.793050690845736
+
+ + 29 + 2 + 0.5583995133811572 0.4416004866188428 0.1586544616061161 0.8413455383938839
+
+ + 30 + 0.5198356507072179 0.4801643492927821
+
+ + 31 + 20 + 0.35987367264814724 0.6401263273518527 0.19868846231520568 0.8013115376847944
+
+ + 32 + 0.8033402530122968 0.19665974698770317
+
+ + 33 + 0 + 22 + 0.3240537556081733 0.6759462443918266 0.46544000463567187 0.5345599953643282 0.5124487804717093 0.4875512195282907 0.5381595603348239 0.4618404396651762
+
+ + 34 + 22 + 5 + 31 + 0.5963322517765541 0.4036677482234459 0.3052687838458537 0.6947312161541462 0.5980753695799805 0.40192463042001947 0.4357697145109763 0.5642302854890237 0.5508119496900317 0.4491880503099682 0.4886255571181391 0.511374442881861 0.07398280009881433 0.9260171999011857 0.3969850456389493 0.6030149543610507
+
+ + 35 + 24 + 0.4942704525205384 0.5057295474794615 0.4439508252537509 0.5560491747462492
+
+ + 36 + 0.4650363337466798 0.5349636662533203
+
+ + 37 + 11 + 0.7598838934352166 0.24011610656478347 0.3257005962630651 0.674299403736935
+
+ + 38 + 17 + 2 + 22 + 8 + 15 + 23 + 0.14570222824022838 0.8542977717597716 0.524389415508716 0.47561058449128407 0.6457115007715657 0.3542884992284344 0.44391565043622205 0.556084349563778 0.18440165580489232 0.8155983441951077 0.40468027426008807 0.5953197257399119 0.18059385512061843 0.8194061448793816 0.4912944966615882 0.5087055033384117 0.8230634063068736 0.17693659369312648 0.7997819805549556 0.20021801944504436 0.5929498106160325 0.4070501893839675 0.5480477352543548 0.4519522647456453 0.12111897667386479 0.8788810233261352 0.06358319299441699 0.936416807005583 0.5506253385534314 0.4493746614465685 0.2297638689594116 0.7702361310405884 0.45200208227423355 0.5479979177257664 0.5372678160044445 0.4627321839955555 0.904667198873867 0.09533280112613292 0.9291780388204571 0.07082196117954287 0.6559490740775984 0.34405092592240155 0.5563755387186479 0.4436244612813522 0.2548830400410034 0.7451169599589966 0.5981754058346702 0.4018245941653298 0.3528955949836258 0.6471044050163742 0.5963397604221705 0.40366023957782937 0.21061842865702282 0.789381571342977 0.7080653342421026 0.29193466575789734 0.45802839202108986 0.5419716079789102 0.24447607470540544 0.7555239252945944 0.9187563218713981 0.0812436781286019 0.4481003030078999 0.5518996969921002 0.4273946421944792 0.5726053578055209 0.7101658162548061 0.2898341837451938 0.5868319097167195 0.41316809028328044 0.5269788895635638 0.47302111043643624 0.176729756207666 0.823270243792334 0.6301895500175148 0.3698104499824851 0.41180755046361106 0.588192449536389 0.3413615391945534 0.6586384608054465 0.6653926602695582 0.33460733973044177 0.19722454605001496 0.8027754539499851 0.4366743258495823 0.5633256741504177 0.7302000296344098 0.2697999703655902 0.5448281347148863 0.4551718652851137 0.612365805080369 0.3876341949196311 0.5543421958079896 0.44565780419201045 0.273670783632863 0.726329216367137 0.47680440602528545 0.5231955939747146 0.5623023098111668 0.43769769018883314 0.42657681209028936 0.5734231879097107 0.23842072609799717 0.7615792739020029 0.25759939887828714 0.7424006011217129 0.19898987235222967 0.8010101276477704 0.09799959811571991 0.9020004018842801 0.5415704803515416 0.45842951964845835 0.2996521109369143 0.7003478890630858 0.4605339213352022 0.5394660786647978 0.7942745354475148 0.2057254645524852 0.2468024318479257 0.7531975681520743 0.5361958638677179 0.46380413613228205 0.4367168529100994 0.5632831470899007 0.852476986879732 0.147523013120268 0.5950099145628076 0.4049900854371924
+
+ + 39 + 0.22289402301522449 0.7771059769847755
+
+ + 40 + 15 + 28 + 0.5069488826405324 0.49305111735946766 0.9395435249076445 0.06045647509235552 0.5678838320220997 0.4321161679779002 0.425005169128721 0.574994830871279
+
+ + 41 + 28 + 0.3537195682105066 0.6462804317894935 0.8572739826243647 0.14272601737563528
+
+ + 42 + 18 + 0.49912329210279305 0.5008767078972071 0.7799687485227521 0.22003125147724786
+
+ + 43 + 37 + 0.29496853615751467 0.7050314638424853 0.29194998018717416 0.7080500198128257
+
+ + 44 + 0.45939717071650904 0.5406028292834909
+
+ + 45 + 19 + 0.4003509962132215 0.5996490037867784 0.5218851396559201 0.4781148603440799
+
+ + 46 + 3 + 0.5829105800219911 0.41708941997800886 0.2630549559549988 0.7369450440450013
+
+ + 47 + 0.46714170633557195 0.5328582936644279
+
+ + 48 + 36 + 0.25609748350103523 0.7439025164989649 0.9734588076976068 0.026541192302393112
+
+ + 49 + 0.3586277701816186 0.6413722298183814
+
+ + 50 + 29 + 25 + 41 + 0.9997491845846399 0.0002508154153600988 0.9910111804504734 0.00898881954952653 0.23206186642113158 0.7679381335788684 0.75681418881068 0.2431858111893201 0.28902799394729095 0.7109720060527092 0.7294274475842757 0.2705725524157243 0.2266553973320524 0.7733446026679476 0.7768431541861575 0.22315684581384254
+
+ + 51 + 38 + 4 + 0.676846327961736 0.32315367203826395 0.9249941802048344 0.07500581979516564 0.6420258024412644 0.35797419755873566 0.8107474895506087 0.18925251044939131
+
+ + 52 + 6 + 11 + 18 + 44 + 0.5550094271568646 0.44499057284313537 0.48449269346113316 0.515507306538867 0.19416217973643585 0.8058378202635641 0.6353568907012453 0.36464310929875465 0.47523859866802043 0.5247614013319797 0.7575888011975541 0.24241119880244583 0.8376284209103718 0.16237157908962818 0.6357246313961971 0.3642753686038029 0.23988765163157189 0.760112348368428 0.40049738841567817 0.5995026115843218 0.9258727324276259 0.07412726757237412 0.7126779972203944 0.28732200277960557 0.4599623024564794 0.5400376975435206 0.1278675111796312 0.8721324888203688 0.9516152934738815 0.04838470652611853 0.08101043783848777 0.9189895621615123
+
+ + 53 + 38 + 0.9571163354591116 0.04288366454088839 0.3786706363567867 0.6213293636432132
+
+ + 54 + 10 + 0.7717589194481512 0.22824108055184877 0.2467040685596658 0.7532959314403342
+
+ + 55 + 15 + 19 + 32 + 0.4655221596835163 0.5344778403164838 0.6031425280473169 0.39685747195268295 0.45029794421548636 0.5497020557845137 0.5394414550106144 0.46055854498938564 0.484847581056802 0.515152418943198 0.7404313294943489 0.2595686705056512 0.6050954736768638 0.3949045263231363 0.852453653469361 0.147546346530639
+
+ + 56 + 6 + 0.763094998073832 0.236905001926168 0.3428976983618867 0.6571023016381132
+
+ + 57 + 26 + 38 + 8 + 39 + 0.2587072577326644 0.7412927422673357 0.18842858463498635 0.8115714153650136 0.5269844457956484 0.4730155542043516 0.06724066801616617 0.9327593319838339 0.21325244597448867 0.7867475540255113 0.474869686291926 0.525130313708074 0.0908517530068225 0.9091482469931775 0.45346214894865744 0.5465378510513426 0.5552435441132527 0.4447564558867474 0.6000375903008598 0.3999624096991402 0.6025353311666852 0.3974646688333148 0.4365167458221063 0.5634832541778937 0.840737395855709 0.1592626041442912 0.2489682838663126 0.7510317161336875 0.6373489931858857 0.3626510068141144 0.5679820956363707 0.4320179043636293
+
+ + 58 + 56 + 0.033173392564405754 0.9668266074355942 0.4704453093715278 0.5295546906284722
+
+ + 59 + 0.9116155944110222 0.08838440558897773
+
+ + 60 + 1 + 0.41997591030195314 0.5800240896980469 0.7696081824063407 0.23039181759365934
+
+ + 61 + 1 + 29 + 57 + 14 + 48 + 0.9780171259426282 0.021982874057371718 0.49346997461228914 0.5065300253877109 0.41316168791562397 0.5868383120843761 0.7838804165277327 0.21611958347226737 0.5763079477447137 0.42369205225528617 0.6759127983778204 0.32408720162217974 0.5482767438941377 0.45172325610586234 0.5763159070977395 0.42368409290226045 0.1862388306279621 0.8137611693720379 0.4978428436355921 0.5021571563644078 0.06560251547038037 0.9343974845296197 0.8164956600088288 0.18350433999117124 0.8475825117097534 0.15241748829024654 0.09577212398047383 0.9042278760195261 0.39261979416199283 0.6073802058380073 0.8570151566818572 0.14298484331814285 0.7306087901157935 0.26939120988420645 0.18224118457989613 0.8177588154201038 0.7096275029606615 0.2903724970393385 0.8533548400791918 0.14664515992080812 0.5140898055835259 0.4859101944164741 0.7196299878360736 0.28037001216392643 0.6180913757069088 0.38190862429309125 0.3735125002129522 0.6264874997870479 0.35469435056899096 0.645305649431009 0.5292014560328848 0.4707985439671151 0.8605285361265932 0.13947146387340675 0.6007238419411721 0.3992761580588279 0.343464989096519 0.656535010903481 0.43528508744648986 0.5647149125535101 0.5443798920869277 0.45562010791307217 0.8707623657660675 0.12923763423393256
+
+ + 62 + 12 + 47 + 0.0973169055423481 0.9026830944576519 0.5211431480746246 0.47885685192537547 0.8460875875457943 0.1539124124542057 0.705883377037842 0.294116622962158
+
+ + 63 + 26 + 0.7036689252538298 0.29633107474617004 0.8685998475684602 0.1314001524315398
+
+ + 64 + 0 + 0.3810747468536334 0.6189252531463667 0.5665865365855831 0.43341346341441694
+
+ + 65 + 17 + 11 + 0.6263633780083655 0.3736366219916345 0.48355634330214814 0.5164436566978519 0.6767090760648256 0.32329092393517445 0.3946791327707169 0.605320867229283
+
+ + 66 + 58 + 0.6583018299078095 0.3416981700921904 0.45849805206059663 0.5415019479394034
+
+ + 67 + 56 + 23 + 0.347580129217332 0.6524198707826679 0.9957942644647114 0.0042057355352885266 0.3773056645675182 0.6226943354324819 0.4636829473758277 0.5363170526241723
+
+
+
diff --git a/testing/Part_2/network_70.XMLBIF b/testing/Part_2/network_70.XMLBIF new file mode 100644 index 00000000..9081788f --- /dev/null +++ b/testing/Part_2/network_70.XMLBIF @@ -0,0 +1,770 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 64 + 0 + 1 + weight = None + + + 65 + 0 + 1 + weight = None + + + 66 + 0 + 1 + weight = None + + + 67 + 0 + 1 + weight = None + + + 68 + 0 + 1 + weight = None + + + 69 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.36352401191426553 0.6364759880857345
+
+ + 1 + 0.7208268261386895 0.27917317386131035
+
+ + 2 + 0.3821383781074314 0.6178616218925684
+
+ + 3 + 0.47409519469885547 0.5259048053011446
+
+ + 4 + 0.8321461209949563 0.1678538790050436
+
+ + 5 + 0.9243173304114566 0.07568266958854337
+
+ + 6 + 4 + 0.08594556411299954 0.9140544358870004 0.8376040496803422 0.16239595031965778
+
+ + 7 + 0.8244217968897575 0.1755782031102425
+
+ + 8 + 4 + 0.3994253566599513 0.6005746433400487 0.32513094208706506 0.6748690579129349
+
+ + 9 + 0.20780400730183732 0.7921959926981627
+
+ + 10 + 0 + 0.7557856379953316 0.24421436200466834 0.9353322343730532 0.06466776562694672
+
+ + 11 + 0.25981635152507065 0.7401836484749292
+
+ + 12 + 0.3243120084800593 0.6756879915199407
+
+ + 13 + 0.3697413191987361 0.6302586808012639
+
+ + 14 + 0.7763110739073931 0.22368892609260693
+
+ + 15 + 10 + 0.5968290176797397 0.40317098232026033 0.9381094751638831 0.06189052483611687
+
+ + 16 + 0.14397312498994394 0.856026875010056
+
+ + 17 + 0.08258145662236992 0.9174185433776301
+
+ + 18 + 0.6321185157242943 0.36788148427570555
+
+ + 19 + 0.4134882651228061 0.5865117348771939
+
+ + 20 + 0.5068502924389431 0.4931497075610569
+
+ + 21 + 10 + 16 + 19 + 0.4909008812188 0.5090991187812 0.6750865483376993 0.32491345166230073 0.6257975065512699 0.3742024934487302 0.3026705615305041 0.6973294384694959 0.7643237145272382 0.23567628547276165 0.6066290228524972 0.3933709771475027 0.3943053827182926 0.6056946172817075 0.33263004304121174 0.6673699569587883
+
+ + 22 + 0 + 7 + 0.9769044247413142 0.023095575258685812 0.9454715343187506 0.05452846568124935 0.7661334094772605 0.2338665905227395 0.04575052013083518 0.9542494798691649
+
+ + 23 + 8 + 0.5272364739281346 0.47276352607186545 0.949932110665771 0.050067889334228996
+
+ + 24 + 7 + 14 + 16 + 0.5253705630509038 0.47462943694909626 0.9183986974040447 0.08160130259595536 0.43162484815678187 0.5683751518432181 0.7968825896204891 0.2031174103795109 0.27222394404015354 0.7277760559598464 0.2679537275367833 0.7320462724632167 0.5952983466759825 0.4047016533240175 0.5244363194905796 0.47556368050942055
+
+ + 25 + 0.260927638071428 0.739072361928572
+
+ + 26 + 22 + 0.6591997671591501 0.3408002328408499 0.7200137055358081 0.2799862944641918
+
+ + 27 + 24 + 14 + 0.7002558425165448 0.2997441574834551 0.45421972166223257 0.5457802783377675 0.8713660497228852 0.12863395027711483 0.30826410846584434 0.6917358915341558
+
+ + 28 + 0 + 0.34177323074443716 0.6582267692555629 0.47694528937465475 0.5230547106253453
+
+ + 29 + 8 + 0.30496082899633054 0.6950391710036694 0.6425927511728341 0.35740724882716596
+
+ + 30 + 29 + 0.5232464695043219 0.4767535304956781 0.7354060652209948 0.2645939347790052
+
+ + 31 + 7 + 26 + 0.7472693030591369 0.25273069694086314 0.4951985449208371 0.504801455079163 0.4900997792371903 0.5099002207628097 0.38388013516697367 0.6161198648330264
+
+ + 32 + 0.6414743857005851 0.3585256142994148
+
+ + 33 + 19 + 0.5487151639599789 0.4512848360400211 0.49287766371775155 0.5071223362822485
+
+ + 34 + 2 + 0.6762854431009154 0.3237145568990847 0.33295276321255624 0.6670472367874438
+
+ + 35 + 0.40277819009854904 0.597221809901451
+
+ + 36 + 23 + 0.9772373491953481 0.022762650804652004 0.5275289460470985 0.4724710539529014
+
+ + 37 + 0.613393511955312 0.3866064880446881
+
+ + 38 + 1 + 0.8300779415991186 0.16992205840088137 0.31419487050634365 0.6858051294936565
+
+ + 39 + 13 + 20 + 0.2983515584972885 0.7016484415027116 0.5384395350816736 0.4615604649183264 0.5770494135559082 0.4229505864440919 0.6907752593244405 0.3092247406755595
+
+ + 40 + 0.690442981907443 0.3095570180925569
+
+ + 41 + 34 + 24 + 0.31351156865141017 0.6864884313485897 0.7321550356494305 0.2678449643505694 0.05537961981733243 0.9446203801826676 0.4373175774520007 0.5626824225479992
+
+ + 42 + 0.8068800669116435 0.19311993308835648
+
+ + 43 + 0.39390196474050676 0.6060980352594932
+
+ + 44 + 0.1956413690711107 0.8043586309288893
+
+ + 45 + 19 + 0.5717900686899113 0.4282099313100887 0.5549849273550921 0.4450150726449079
+
+ + 46 + 13 + 0.6427249993688635 0.3572750006311366 0.48050877736756825 0.5194912226324317
+
+ + 47 + 35 + 0.5201416899554361 0.47985831004456403 0.571361456178912 0.42863854382108807
+
+ + 48 + 47 + 0.49975504425408845 0.5002449557459115 0.48185972547691547 0.5181402745230846
+
+ + 49 + 0.209016078086754 0.7909839219132461
+
+ + 50 + 0.7802352574210851 0.21976474257891493
+
+ + 51 + 38 + 4 + 0.6018041462365434 0.3981958537634566 0.08876358944130357 0.9112364105586964 0.4686654435740015 0.5313345564259986 0.7964215532800818 0.2035784467199182
+
+ + 52 + 0.5865094771886576 0.4134905228113423
+
+ + 53 + 21 + 43 + 0.4276092558124254 0.5723907441875745 0.50061822575363 0.49938177424637 0.5758403611178537 0.42415963888214625 0.4343985325519555 0.5656014674480445
+
+ + 54 + 0.3122238978589822 0.6877761021410179
+
+ + 55 + 23 + 46 + 41 + 0.7315856748165697 0.26841432518343034 0.32551466245693467 0.6744853375430653 0.45136118566771377 0.5486388143322863 0.2653607084032689 0.734639291596731 0.35120526754523074 0.6487947324547693 0.6183417961576647 0.3816582038423353 0.030169429807771302 0.9698305701922287 0.837707826698089 0.16229217330191104
+
+ + 56 + 14 + 0.5983517804761544 0.40164821952384555 0.40373798869830435 0.5962620113016955
+
+ + 57 + 14 + 0.19767449294159004 0.80232550705841 0.38786009246352865 0.6121399075364713
+
+ + 58 + 41 + 0.3537756934552247 0.6462243065447755 0.3887017214691439 0.6112982785308562
+
+ + 59 + 2 + 46 + 19 + 0.009014158409393305 0.9909858415906067 0.6318382276740058 0.36816177232599423 0.5995335703773171 0.4004664296226828 0.4292112125883505 0.5707887874116496 0.5796487578738487 0.42035124212615127 0.9982628388457545 0.0017371611542455457 0.05752594436613916 0.9424740556338609 0.09750984950598858 0.9024901504940114
+
+ + 60 + 1 + 20 + 43 + 49 + 0.7858966551017689 0.21410334489823107 0.5666547945228698 0.43334520547713024 0.44023658490058637 0.5597634150994136 0.5613063801352853 0.4386936198647148 0.49118274273029644 0.5088172572697035 0.21134125821514815 0.7886587417848518 0.3709400269979523 0.6290599730020477 0.4147210010403068 0.5852789989596933 0.5235920930656212 0.47640790693437873 0.5189179225238713 0.48108207747612886 0.3898962092310492 0.6101037907689508 0.5342556631804946 0.46574433681950556 0.40058344226638104 0.599416557733619 0.7743460749546816 0.2256539250453184 0.5644623452534525 0.43553765474654754 0.7159583076509501 0.2840416923490498
+
+ + 61 + 49 + 0.3813367740793092 0.6186632259206908 0.4512128179615889 0.548787182038411
+
+ + 62 + 6 + 18 + 42 + 54 + 0.39714876539276306 0.6028512346072369 0.4525360688346868 0.5474639311653132 0.6273596675003432 0.3726403324996567 0.11802140880824417 0.8819785911917558 0.9314744880218971 0.0685255119781029 0.5879006840745277 0.4120993159254723 0.46601373711066896 0.533986262889331 0.5854294965911945 0.41457050340880547 0.718820647301931 0.28117935269806904 0.35010496874354813 0.6498950312564519 0.2370526009345555 0.7629473990654445 0.5699953989793193 0.4300046010206807 0.5414297905388413 0.45857020946115873 0.5736946015901997 0.4263053984098003 0.4509443190303653 0.5490556809696348 0.1509760689591826 0.8490239310408174
+
+ + 63 + 34 + 17 + 0.5513923082113635 0.4486076917886364 0.42235871664562386 0.5776412833543761 0.5843192371939308 0.41568076280606925 0.5529220357518695 0.44707796424813057
+
+ + 64 + 27 + 50 + 0.757923775814121 0.24207622418587904 0.41539186263774 0.58460813736226 0.5018195055181436 0.4981804944818564 0.08646564163439514 0.9135343583656048
+
+ + 65 + 0.5644644371689345 0.4355355628310656
+
+ + 66 + 2 + 34 + 12 + 0.6595318029619635 0.3404681970380365 0.5149856968918833 0.48501430310811666 0.6505227716247679 0.34947722837523204 0.06744948931292892 0.9325505106870711 0.20888363313950406 0.7911163668604959 0.7151015942242147 0.2848984057757852 0.4538921603976646 0.5461078396023354 0.022562554967831727 0.9774374450321682
+
+ + 67 + 28 + 15 + 0.21532948087245068 0.7846705191275494 0.0861713517967056 0.9138286482032945 0.31360882444903687 0.6863911755509632 0.7247341574781851 0.27526584252181485
+
+ + 68 + 0.11878558004667548 0.8812144199533244
+
+ + 69 + 0.7894565181931876 0.21054348180681234
+
+
+
diff --git a/testing/Part_2/network_72.XMLBIF b/testing/Part_2/network_72.XMLBIF new file mode 100644 index 00000000..907aa007 --- /dev/null +++ b/testing/Part_2/network_72.XMLBIF @@ -0,0 +1,799 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 64 + 0 + 1 + weight = None + + + 65 + 0 + 1 + weight = None + + + 66 + 0 + 1 + weight = None + + + 67 + 0 + 1 + weight = None + + + 68 + 0 + 1 + weight = None + + + 69 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 70 + 0 + 1 + weight = None + + + 71 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.4881856429160759 0.5118143570839241
+
+ + 1 + 0.7793519964595851 0.22064800354041503
+
+ + 2 + 0.7129046945314637 0.2870953054685364
+
+ + 3 + 1 + 0.598150026972949 0.40184997302705117 0.35476258297041924 0.6452374170295808
+
+ + 4 + 0.9377598456461135 0.06224015435388655
+
+ + 5 + 0.9978614914199477 0.002138508580052318
+
+ + 6 + 0.09437421314802763 0.9056257868519724
+
+ + 7 + 0.04596304921944941 0.9540369507805506
+
+ + 8 + 0.8830378391480468 0.11696216085195327
+
+ + 9 + 0.7278377922170804 0.27216220778291955
+
+ + 10 + 0.4886874502417919 0.5113125497582081
+
+ + 11 + 0.8571384362252809 0.1428615637747192
+
+ + 12 + 0.5343233808778893 0.46567661912211067
+
+ + 13 + 0 + 0.5569001333856234 0.44309986661437667 0.7789923992230671 0.2210076007769329
+
+ + 14 + 0.2113440318835234 0.7886559681164765
+
+ + 15 + 0.19532515368956896 0.8046748463104311
+
+ + 16 + 0.4083251818114271 0.5916748181885728
+
+ + 17 + 1 + 12 + 0.5223296660640898 0.4776703339359103 0.640385634884613 0.35961436511538697 0.33958618800240914 0.6604138119975909 0.9831245750216284 0.016875424978371526
+
+ + 18 + 0.47416448428510793 0.5258355157148921
+
+ + 19 + 0.6426958261955169 0.3573041738044831
+
+ + 20 + 18 + 0.8071850134057956 0.19281498659420426 0.44633545304033906 0.5536645469596609
+
+ + 21 + 0.5918472565539603 0.40815274344603975
+
+ + 22 + 0.4275220436726477 0.5724779563273523
+
+ + 23 + 13 + 0.3880889295576766 0.6119110704423234 0.169003065881981 0.830996934118019
+
+ + 24 + 0.36233207339519563 0.6376679266048043
+
+ + 25 + 23 + 0.44444068578637447 0.5555593142136256 0.11646920577621604 0.883530794223784
+
+ + 26 + 3 + 5 + 0.559610500860128 0.440389499139872 0.6391167727382885 0.3608832272617116 0.5686353321204936 0.4313646678795064 0.6861303891655595 0.31386961083444054
+
+ + 27 + 2 + 0.1595089226695021 0.8404910773304979 0.2997337357812197 0.7002662642187802
+
+ + 28 + 0.5002819773733725 0.49971802262662735
+
+ + 29 + 3 + 0.4774069174595632 0.5225930825404368 0.7541947935737708 0.24580520642622916
+
+ + 30 + 6 + 14 + 16 + 28 + 0.522570903133506 0.4774290968664941 0.5155864902830769 0.48441350971692315 0.24606668983089983 0.7539333101691001 0.6399051194078614 0.36009488059213857 0.8756462269589024 0.12435377304109767 0.46253416411980613 0.5374658358801938 0.47562855148450456 0.5243714485154954 0.08785485689269769 0.9121451431073023 0.8132597716121386 0.18674022838786136 0.5829872616391276 0.4170127383608725 0.7106741031052698 0.28932589689473026 0.675825348112498 0.324174651887502 0.278167768894 0.7218322311059999 0.6635045555200648 0.3364954444799351 0.5282567649422725 0.47174323505772753 0.8397112721182475 0.16028872788175258
+
+ + 31 + 0.6107154672332693 0.38928453276673064
+
+ + 32 + 0.15823740831281044 0.8417625916871896
+
+ + 33 + 29 + 5 + 0.7958108720547429 0.20418912794525715 0.33107458687476987 0.6689254131252301 0.4945647200304217 0.5054352799695784 0.41120109483909567 0.5887989051609044
+
+ + 34 + 29 + 18 + 0.9123799857673188 0.08762001423268118 0.5844234070861989 0.4155765929138011 0.5292002682561069 0.4707997317438931 0.8246386732712742 0.1753613267287258
+
+ + 35 + 14 + 24 + 0.7771210521043184 0.22287894789568174 0.9632643083855424 0.036735691614457555 0.4402455423119032 0.5597544576880967 0.3866501579262597 0.6133498420737402
+
+ + 36 + 3 + 27 + 7 + 32 + 0.6734646206882234 0.32653537931177656 0.07149772614117703 0.9285022738588229 0.136187607340527 0.863812392659473 0.6016813425905109 0.3983186574094891 0.1534218823927077 0.8465781176072923 0.5318928002953021 0.4681071997046979 0.08395115252128203 0.916048847478718 0.3863295137581016 0.6136704862418983 0.8129231646137035 0.18707683538629644 0.640487576820754 0.3595124231792461 0.5029645077026146 0.4970354922973855 0.24786050431615095 0.7521394956838491 0.11568882081164401 0.884311179188356 0.19864707463152256 0.8013529253684775 0.7839814029666345 0.21601859703336546 0.37917182399374627 0.6208281760062537
+
+ + 37 + 4 + 5 + 0.12297296914940144 0.8770270308505985 0.5226290593716587 0.4773709406283412 0.14555177904319777 0.8544482209568022 0.41292115581971994 0.5870788441802801
+
+ + 38 + 3 + 18 + 0.16734795026545646 0.8326520497345435 0.4971973868702361 0.5028026131297638 0.7898707323328804 0.21012926766711956 0.22129823830118758 0.7787017616988124
+
+ + 39 + 33 + 0.19561018053305795 0.8043898194669421 0.5648418147355215 0.43515818526447847
+
+ + 40 + 0 + 28 + 0.4316472378541972 0.5683527621458028 0.35777555154981855 0.6422244484501815 0.5074634638687613 0.4925365361312387 0.027085043930052153 0.9729149560699478
+
+ + 41 + 0.17973486143067438 0.8202651385693256
+
+ + 42 + 35 + 31 + 0.7014859859726433 0.29851401402735667 0.5713150551504586 0.4286849448495415 0.8151528549672667 0.18484714503273322 0.7701366715624401 0.22986332843755986
+
+ + 43 + 41 + 0.2061922986359577 0.7938077013640423 0.689132524481596 0.310867475518404
+
+ + 44 + 9 + 0.7466532375582178 0.2533467624417821 0.756963816698384 0.24303618330161617
+
+ + 45 + 7 + 0.4085987115350684 0.5914012884649317 0.35370267397656474 0.6462973260234353
+
+ + 46 + 0 + 0.6259572888584474 0.37404271114155274 0.44660438424875837 0.5533956157512415
+
+ + 47 + 0.4383509330146087 0.5616490669853914
+
+ + 48 + 0.47631248587600067 0.5236875141239993
+
+ + 49 + 24 + 0.3338850510253105 0.6661149489746895 0.47334846827894755 0.5266515317210525
+
+ + 50 + 40 + 0.7880925065879203 0.2119074934120797 0.5030166578450884 0.49698334215491147
+
+ + 51 + 49 + 0.4866183041834222 0.5133816958165777 0.4673181199127636 0.5326818800872364
+
+ + 52 + 14 + 0.02029476127159181 0.9797052387284082 0.9815055642985813 0.01849443570141872
+
+ + 53 + 4 + 39 + 0.16070563823117526 0.8392943617688248 0.6349150005932974 0.36508499940670264 0.4275010548478962 0.5724989451521039 0.572989261221001 0.427010738778999
+
+ + 54 + 0.5809491027572616 0.41905089724273836
+
+ + 55 + 22 + 42 + 0.4826317225280211 0.5173682774719789 0.5775012334548932 0.42249876654510665 0.4592098635511675 0.5407901364488324 0.17662431304101409 0.8233756869589859
+
+ + 56 + 9 + 23 + 0.4667959147900137 0.5332040852099863 0.35471063984035195 0.645289360159648 0.7218111106834737 0.2781888893165263 0.557234081810551 0.442765918189449
+
+ + 57 + 0.036497306922258305 0.9635026930777417
+
+ + 58 + 38 + 56 + 21 + 31 + 0.08727274218824926 0.9127272578117508 0.5774381315586082 0.42256186844139176 0.31634456755047397 0.6836554324495261 0.9906925647597934 0.00930743524020662 0.21252880071118133 0.7874711992888187 0.5325948479617183 0.4674051520382816 0.1668830567172903 0.8331169432827097 0.6117666790513033 0.3882333209486967 0.10617854100409949 0.8938214589959006 0.7539118330986798 0.2460881669013203 0.4773719356947607 0.5226280643052393 0.45779575444534476 0.5422042455546552 0.9748151657421911 0.02518483425780898 0.12246388520643361 0.8775361147935664 0.5648746499443762 0.43512535005562386 0.4074117313865206 0.5925882686134794
+
+ + 59 + 20 + 42 + 43 + 0.4289203088876953 0.5710796911123048 0.08003406973846587 0.9199659302615342 0.12212662629976448 0.8778733737002355 0.6063721953819657 0.39362780461803426 0.5922739953514659 0.40772600464853404 0.6232828110553222 0.3767171889446777 0.19108619184607303 0.808913808153927 0.35867667118185176 0.6413233288181482
+
+ + 60 + 27 + 37 + 0.109273348386793 0.890726651613207 0.4922695926901516 0.5077304073098484 0.7426209242564739 0.2573790757435262 0.7753433525455378 0.22465664745446215
+
+ + 61 + 8 + 21 + 0.5528056543592171 0.4471943456407829 0.3708965194349416 0.6291034805650583 0.34095651108611436 0.6590434889138856 0.32728128545356266 0.6727187145464374
+
+ + 62 + 23 + 0.03132347250087307 0.9686765274991269 0.1799114124385875 0.8200885875614125
+
+ + 63 + 14 + 0.9862330359795117 0.013766964020488253 0.14068965549191614 0.8593103445080839
+
+ + 64 + 6 + 22 + 0.7402442084300603 0.2597557915699397 0.6112580670925819 0.38874193290741804 0.8765319400545658 0.12346805994543408 0.6803839431615091 0.31961605683849087
+
+ + 65 + 35 + 31 + 43 + 0.7449544591889092 0.25504554081109077 0.6652432533104087 0.3347567466895913 0.29414474492321374 0.7058552550767863 0.2974895315261699 0.7025104684738303 0.47572438960919095 0.5242756103908089 0.17905908979773247 0.8209409102022676 0.5201188343546511 0.47988116564534894 0.46660264233225746 0.5333973576677425
+
+ + 66 + 0.5022478162482111 0.49775218375178887
+
+ + 67 + 0.7161753615611992 0.28382463843880074
+
+ + 68 + 34 + 59 + 0.6175256107631272 0.3824743892368728 0.6981967543638301 0.30180324563616984 0.6911482537056973 0.30885174629430273 0.5454825395181868 0.4545174604818132
+
+ + 69 + 61 + 0.598946407434782 0.401053592565218 0.5693958405488349 0.4306041594511652
+
+ + 70 + 38 + 8 + 0.2952637249741276 0.7047362750258724 0.2577575552090494 0.7422424447909506 0.05218502645143432 0.9478149735485657 0.33338855411887464 0.6666114458811253
+
+ + 71 + 3 + 18 + 0.060391131866841426 0.9396088681331586 0.7004928180436147 0.2995071819563853 0.4927428865097823 0.5072571134902176 0.3755141778984798 0.6244858221015203
+
+
+
diff --git a/testing/Part_2/network_74.XMLBIF b/testing/Part_2/network_74.XMLBIF new file mode 100644 index 00000000..7a2b6aa5 --- /dev/null +++ b/testing/Part_2/network_74.XMLBIF @@ -0,0 +1,831 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 64 + 0 + 1 + weight = None + + + 65 + 0 + 1 + weight = None + + + 66 + 0 + 1 + weight = None + + + 67 + 0 + 1 + weight = None + + + 68 + 0 + 1 + weight = None + + + 69 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 70 + 0 + 1 + weight = None + + + 71 + 0 + 1 + weight = None + + + 72 + 0 + 1 + weight = None + + + 73 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.3679056960513354 0.6320943039486646
+
+ + 1 + 0.5688180581150101 0.43118194188499
+
+ + 2 + 0.9225240416348052 0.07747595836519482
+
+ + 3 + 0.7397749989414405 0.26022500105855945
+
+ + 4 + 0.22870468622613307 0.771295313773867
+
+ + 5 + 0.8288030803030122 0.1711969196969878
+
+ + 6 + 0.2876923862565848 0.7123076137434152
+
+ + 7 + 0.3643924804424185 0.6356075195575815
+
+ + 8 + 1 + 0.7618086652201582 0.23819133477984164 0.46790312447920607 0.532096875520794
+
+ + 9 + 5 + 0.5372941107038345 0.4627058892961655 0.5378190053429103 0.4621809946570897
+
+ + 10 + 1 + 4 + 0.6689071971508023 0.33109280284919784 0.4860606144969664 0.5139393855030336 0.8253210377971842 0.17467896220281573 0.14983530203218084 0.8501646979678191
+
+ + 11 + 0.5781725023234766 0.42182749767652344
+
+ + 12 + 8 + 0.7260497724105964 0.2739502275894036 0.8575122390488797 0.1424877609511202
+
+ + 13 + 0.23276713303324437 0.7672328669667556
+
+ + 14 + 8 + 0.770414695280708 0.22958530471929198 0.5367871170591102 0.4632128829408898
+
+ + 15 + 4 + 5 + 0.8946365720320544 0.10536342796794573 0.9383971840905487 0.06160281590945123 0.017831833754893358 0.9821681662451066 0.6824600309806412 0.3175399690193588
+
+ + 16 + 0.37732358890019196 0.6226764110998081
+
+ + 17 + 12 + 0.4530359360773109 0.546964063922689 0.5592382014905756 0.44076179850942443
+
+ + 18 + 0.38377648880020954 0.6162235111997904
+
+ + 19 + 0.44913763680801216 0.5508623631919879
+
+ + 20 + 0.6736687184645644 0.32633128153543567
+
+ + 21 + 0.6123576425296909 0.387642357470309
+
+ + 22 + 0.49739971169676866 0.5026002883032312
+
+ + 23 + 9 + 0.34914496920981875 0.6508550307901813 0.7421839466699924 0.25781605333000757
+
+ + 24 + 0.31011339855522346 0.6898866014447765
+
+ + 25 + 0.4553071230992325 0.5446928769007675
+
+ + 26 + 25 + 0.3778592701752853 0.6221407298247147 0.4719921634749432 0.5280078365250568
+
+ + 27 + 0.8861846407087333 0.11381535929126678
+
+ + 28 + 0.7610647935546513 0.23893520644534874
+
+ + 29 + 0.559451060983303 0.44054893901669695
+
+ + 30 + 6 + 13 + 0.3460298802333258 0.6539701197666743 0.0177868524163291 0.982213147583671 0.3218771892764684 0.6781228107235316 0.2035468892518336 0.7964531107481664
+
+ + 31 + 4 + 29 + 0.4796357244993115 0.5203642755006885 0.5621211422253107 0.4378788577746893 0.3650397165431393 0.6349602834568606 0.6558693227959785 0.34413067720402146
+
+ + 32 + 0.019152560654078173 0.9808474393459218
+
+ + 33 + 0.4545981321051139 0.5454018678948861
+
+ + 34 + 9 + 12 + 0.4327056953660724 0.5672943046339276 0.9621951870452027 0.037804812954797304 0.44834725639363254 0.5516527436063674 0.23497962720288706 0.7650203727971129
+
+ + 35 + 0.6831400062744766 0.31685999372552337
+
+ + 36 + 10 + 0.5399353395069586 0.46006466049304134 0.24059566148742448 0.7594043385125755
+
+ + 37 + 27 + 0.2230765113093201 0.7769234886906798 0.46184955413249756 0.5381504458675025
+
+ + 38 + 1 + 14 + 0.7885687263092146 0.2114312736907854 0.7782259111708212 0.22177408882917876 0.347776176236002 0.652223823763998 0.964805344909107 0.03519465509089301
+
+ + 39 + 0.4100213404118249 0.5899786595881752
+
+ + 40 + 1 + 5 + 0.7918511417950637 0.20814885820493634 0.4916721961876729 0.5083278038123272 0.5232787087859511 0.47672129121404894 0.8955259331204083 0.10447406687959172
+
+ + 41 + 0.6359596964516354 0.3640403035483646
+
+ + 42 + 8 + 0.16938835051889473 0.8306116494811053 0.5691651765130099 0.4308348234869901
+
+ + 43 + 0.4319575781780075 0.5680424218219926
+
+ + 44 + 0.07788723016475635 0.9221127698352437
+
+ + 45 + 37 + 0.7720178501743815 0.22798214982561849 0.8315892899648124 0.1684107100351876
+
+ + 46 + 36 + 35 + 0.872593629146309 0.12740637085369094 0.772398707419897 0.22760129258010292 0.5755753713629349 0.4244246286370651 0.035593193084448305 0.9644068069155517
+
+ + 47 + 40 + 2 + 0.687323401419875 0.312676598580125 0.5136606877267923 0.48633931227320765 0.7918854033505582 0.2081145966494418 0.589453119580924 0.4105468804190761
+
+ + 48 + 34 + 27 + 37 + 0.5969957807483853 0.40300421925161467 0.7148234339249826 0.2851765660750174 0.13156843024720424 0.8684315697527958 0.30066964717571687 0.6993303528242831 0.554215971511086 0.445784028488914 0.6910590705166267 0.3089409294833732 0.08407445300579132 0.9159255469942087 0.9813278548545515 0.01867214514544844
+
+ + 49 + 40 + 45 + 0.8804088089600444 0.11959119103995562 0.4183445341575239 0.5816554658424761 0.8100077507893757 0.18999224921062438 0.9116677866972442 0.0883322133027557
+
+ + 50 + 0.2499653633613734 0.7500346366386266
+
+ + 51 + 6 + 27 + 0.17077152049079825 0.8292284795092018 0.8809192329222829 0.11908076707771713 0.25664418387779764 0.7433558161222024 0.5998059613496096 0.4001940386503904
+
+ + 52 + 21 + 27 + 0.6093096148062765 0.3906903851937236 0.5068377717919745 0.4931622282080254 0.5083150220212623 0.4916849779787376 0.39227775091855643 0.6077222490814436
+
+ + 53 + 18 + 0.04601630051104762 0.9539836994889523 0.6270683675132664 0.3729316324867335
+
+ + 54 + 48 + 0.9028687837058043 0.09713121629419569 0.2884753127037552 0.7115246872962449
+
+ + 55 + 19 + 0.9643306348670305 0.035669365132969526 0.6199490576798774 0.38005094232012254
+
+ + 56 + 14 + 55 + 0.912899908599349 0.08710009140065103 0.5543285244860853 0.4456714755139147 0.26341054259735275 0.7365894574026473 0.37758466398227014 0.6224153360177298
+
+ + 57 + 31 + 6 + 52 + 0.8954772961099509 0.10452270389004917 0.7129110760491397 0.28708892395086033 0.6619746332015405 0.33802536679845957 0.5907927001942159 0.4092072998057841 0.34537813631979286 0.6546218636802071 0.8245539910067101 0.1754460089932899 0.07890316460802749 0.9210968353919725 0.3189116274592731 0.681088372540727
+
+ + 58 + 40 + 34 + 27 + 0.9347505543201989 0.06524944567980091 0.5819906221192219 0.4180093778807781 0.4141889552032265 0.5858110447967734 0.8625945248021741 0.13740547519782587 0.36103215619307216 0.6389678438069278 0.17235230112152036 0.8276476988784797 0.13178732106868501 0.868212678931315 0.46035491180114047 0.5396450881988596
+
+ + 59 + 23 + 13 + 37 + 41 + 0.9182887902302204 0.08171120976977958 0.5198642659019624 0.4801357340980375 0.8160404801785273 0.1839595198214727 0.37396482290326855 0.6260351770967315 0.3105892997588072 0.6894107002411928 0.5727923778111049 0.427207622188895 0.932832756703626 0.06716724329637404 0.5739242087382588 0.4260757912617411 0.35744096977290335 0.6425590302270966 0.11300436410461201 0.886995635895388 0.2807381483767333 0.7192618516232667 0.6904210557963183 0.30957894420368176 0.2266554383592621 0.773344561640738 0.9044301816210926 0.09556981837890749 0.3824826506977098 0.6175173493022901 0.9617435702052088 0.03825642979479111
+
+ + 60 + 3 + 15 + 0.5583257581230988 0.44167424187690113 0.549389688956723 0.450610311043277 0.0750623487913955 0.9249376512086044 0.4630705568782903 0.5369294431217096
+
+ + 61 + 0.2809410146931355 0.7190589853068645
+
+ + 62 + 10 + 49 + 61 + 0.5322696059022339 0.46773039409776596 0.21611285684061846 0.7838871431593816 0.5164870740745994 0.4835129259254006 0.2973889279217774 0.7026110720782225 0.5800242735038366 0.4199757264961635 0.5065614428323015 0.4934385571676985 0.6499922488702047 0.3500077511297953 0.3028476290857015 0.6971523709142984
+
+ + 63 + 41 + 61 + 0.7489317820980397 0.25106821790196027 0.7782370693894689 0.22176293061053104 0.8633267520614734 0.13667324793852667 0.7385214308822099 0.2614785691177901
+
+ + 64 + 4 + 30 + 19 + 0.4794127816404241 0.520587218359576 0.4526427247772673 0.5473572752227326 0.869097411649556 0.13090258835044402 0.6493449819823445 0.35065501801765553 0.4173380890488105 0.5826619109511896 0.06850712704435442 0.9314928729556455 0.4317719354624079 0.5682280645375921 0.6463286504039538 0.3536713495960462
+
+ + 65 + 7 + 11 + 35 + 0.10594096223892213 0.8940590377610779 0.4335753328350411 0.5664246671649589 0.12673483850446512 0.8732651614955349 0.6703501829240206 0.3296498170759794 0.8214722720640076 0.17852772793599236 0.4294821150385924 0.5705178849614077 0.7764670624126285 0.22353293758737144 0.44631075539584464 0.5536892446041553
+
+ + 66 + 37 + 0.8946853777703773 0.10531462222962278 0.6591190920050807 0.3408809079949193
+
+ + 67 + 38 + 7 + 62 + 29 + 0.5721659893654418 0.4278340106345583 0.4227141664601483 0.5772858335398516 0.7096803482329933 0.29031965176700664 0.6112365875844917 0.38876341241550827 0.9091682216129775 0.09083177838702265 0.9848158474376001 0.015184152562399933 0.4926558259188923 0.5073441740811078 0.8992940113325515 0.10070598866744847 0.618694393209699 0.3813056067903009 0.4802900689405272 0.5197099310594728 0.6784070963836455 0.3215929036163545 0.7460766972488658 0.25392330275113423 0.5951578002462387 0.4048421997537613 0.4729997157602627 0.5270002842397373 0.7102873021783789 0.2897126978216211 0.46125069041889455 0.5387493095811055
+
+ + 68 + 20 + 32 + 0.8075461880755169 0.19245381192448308 0.4537244682226784 0.5462755317773216 0.43766342920705115 0.5623365707929487 0.9533243322487965 0.04667566775120349
+
+ + 69 + 0.3524093674179447 0.6475906325820552
+
+ + 70 + 30 + 48 + 28 + 0.5556782811241899 0.44432171887580996 0.2946982361309859 0.7053017638690141 0.01880666981253551 0.9811933301874645 0.17000566241226486 0.829994337587735 0.6434346250144208 0.3565653749855792 0.5270637458388198 0.47293625416118024 0.5697755093046202 0.4302244906953799 0.8710056651456746 0.12899433485432543
+
+ + 71 + 66 + 69 + 0.39567034458887856 0.6043296554111215 0.5745396242727399 0.4254603757272601 0.7237205528489792 0.27627944715102076 0.5639694951940283 0.43603050480597183
+
+ + 72 + 8 + 19 + 35 + 46 + 0.3399396228788002 0.6600603771211998 0.1245229775813589 0.8754770224186411 0.6872556654147045 0.3127443345852955 0.7139605871084452 0.28603941289155477 0.7854112628811204 0.21458873711887957 0.3052767332911505 0.6947232667088495 0.38587516797014065 0.6141248320298593 0.3098367760421668 0.6901632239578332 0.07898640665516976 0.9210135933448302 0.5192173277680687 0.4807826722319312 0.32509262820658313 0.6749073717934169 0.9159741142507364 0.08402588574926363 0.5298916624400216 0.4701083375599784 0.5060361926897964 0.4939638073102036 0.6485661825128972 0.3514338174871028 0.2546776290887764 0.7453223709112237
+
+ + 73 + 8 + 47 + 44 + 0.6956228398151417 0.3043771601848582 0.4077598800254753 0.5922401199745247 0.6573786653030184 0.3426213346969816 0.32415774134886743 0.6758422586511326 0.45109274418889456 0.5489072558111054 0.6857626868855492 0.3142373131144508 0.8951424242484939 0.1048575757515061 0.5287919284829147 0.4712080715170853
+
+
+
diff --git a/testing/Part_2/network_76.XMLBIF b/testing/Part_2/network_76.XMLBIF new file mode 100644 index 00000000..cc3c52ac --- /dev/null +++ b/testing/Part_2/network_76.XMLBIF @@ -0,0 +1,853 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 64 + 0 + 1 + weight = None + + + 65 + 0 + 1 + weight = None + + + 66 + 0 + 1 + weight = None + + + 67 + 0 + 1 + weight = None + + + 68 + 0 + 1 + weight = None + + + 69 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 70 + 0 + 1 + weight = None + + + 71 + 0 + 1 + weight = None + + + 72 + 0 + 1 + weight = None + + + 73 + 0 + 1 + weight = None + + + 74 + 0 + 1 + weight = None + + + 75 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.6164204342577148 0.38357956574228513
+
+ + 1 + 0 + 0.25972338179390814 0.7402766182060918 0.5849405998182813 0.41505940018171866
+
+ + 2 + 0.381313504624704 0.6186864953752961
+
+ + 3 + 0.9273333838155642 0.07266661618443578
+
+ + 4 + 0.16606793758438634 0.8339320624156137
+
+ + 5 + 0.45021518251911075 0.5497848174808893
+
+ + 6 + 0.6057656199131983 0.3942343800868017
+
+ + 7 + 0.6054420566161626 0.39455794338383743
+
+ + 8 + 0.991303714594571 0.00869628540542897
+
+ + 9 + 8 + 0.7289256552290956 0.2710743447709044 0.35962606897636923 0.6403739310236307
+
+ + 10 + 0.4963910742669017 0.5036089257330982
+
+ + 11 + 4 + 0.9448609111529975 0.05513908884700245 0.09819901908044115 0.9018009809195588
+
+ + 12 + 8 + 9 + 0.5796863368286296 0.42031366317137053 0.40116386195144216 0.5988361380485578 0.5496125108267839 0.4503874891732161 0.7019613530074602 0.2980386469925397
+
+ + 13 + 0.7611144747492756 0.2388855252507244
+
+ + 14 + 0.8291938665204752 0.1708061334795248
+
+ + 15 + 1 + 0.4179639620475985 0.5820360379524016 0.4749262238619379 0.525073776138062
+
+ + 16 + 8 + 0.45357519189183837 0.5464248081081616 0.8320877053091029 0.16791229469089697
+
+ + 17 + 6 + 0.6546306815805744 0.34536931841942553 0.40638999330826214 0.5936100066917378
+
+ + 18 + 4 + 0.41602387458578427 0.5839761254142157 0.3647604307293097 0.6352395692706903
+
+ + 19 + 0.9715798409447296 0.02842015905527045
+
+ + 20 + 0.9875493718200433 0.012450628179956723
+
+ + 21 + 0.4236197100750929 0.5763802899249071
+
+ + 22 + 18 + 0.7144371245078013 0.2855628754921987 0.5532785909241671 0.44672140907583296
+
+ + 23 + 4 + 16 + 0.45365498255282805 0.5463450174471719 0.5007422983523778 0.49925770164762223 0.37389620187075284 0.6261037981292471 0.6192411550346174 0.3807588449653826
+
+ + 24 + 0.4622869370656134 0.5377130629343866
+
+ + 25 + 20 + 0.21557274144319186 0.7844272585568082 0.24295404558985279 0.7570459544101473
+
+ + 26 + 0.401289576604026 0.598710423395974
+
+ + 27 + 26 + 0.9566950478500165 0.04330495214998359 0.3351700651407888 0.6648299348592113
+
+ + 28 + 0.12212703743775977 0.8778729625622402
+
+ + 29 + 27 + 0.4412986356528873 0.5587013643471127 0.4772488552413534 0.5227511447586465
+
+ + 30 + 0.5218419380476691 0.47815806195233085
+
+ + 31 + 11 + 30 + 0.24353911527712294 0.7564608847228771 0.3338225073190021 0.6661774926809979 0.2959138545383591 0.7040861454616408 0.5019034581737915 0.4980965418262086
+
+ + 32 + 16 + 20 + 0.34837618071126725 0.6516238192887328 0.47773526053876963 0.5222647394612303 0.12106185191192674 0.8789381480880732 0.7865089499245409 0.21349105007545913
+
+ + 33 + 0.5449255866712727 0.45507441332872733
+
+ + 34 + 21 + 0.6887606850225996 0.3112393149774005 0.5585069294379723 0.4414930705620277
+
+ + 35 + 30 + 0.6117904678077195 0.38820953219228055 0.81266318518866 0.18733681481133987
+
+ + 36 + 6 + 0.0229841466185631 0.9770158533814368 0.6525222175744684 0.3474777824255317
+
+ + 37 + 0.5461210736920521 0.453878926307948
+
+ + 38 + 0.4023743680907862 0.5976256319092138
+
+ + 39 + 1 + 0.38439455712081677 0.6156054428791832 0.7240269655340682 0.2759730344659318
+
+ + 40 + 31 + 0.05577262028926915 0.9442273797107309 0.48131274417557146 0.5186872558244285
+
+ + 41 + 35 + 0.12511870352286675 0.8748812964771332 0.1332332440673809 0.8667667559326191
+
+ + 42 + 7 + 0.6301563553101718 0.3698436446898282 0.701087834680566 0.298912165319434
+
+ + 43 + 7 + 22 + 0.1419221693865793 0.8580778306134207 0.4740519839055861 0.5259480160944139 0.37074234000901773 0.6292576599909823 0.533582499565288 0.466417500434712
+
+ + 44 + 12 + 32 + 0.06403170262074916 0.9359682973792508 0.7546293719471573 0.2453706280528427 0.7414761073626719 0.2585238926373282 0.3249298986281436 0.6750701013718564
+
+ + 45 + 0.6092349804872662 0.3907650195127339
+
+ + 46 + 0 + 20 + 29 + 0.6233396715196905 0.37666032848030945 0.5766324315616318 0.4233675684383682 0.8686232041335729 0.1313767958664272 0.3173229571137028 0.6826770428862972 0.017487576924541788 0.9825124230754582 0.23437242139127742 0.7656275786087227 0.07867261527770213 0.9213273847222979 0.4401012471662913 0.5598987528337087
+
+ + 47 + 15 + 14 + 27 + 0.542118717037253 0.4578812829627469 0.5513270860775431 0.44867291392245695 0.5011653443853297 0.49883465561467033 0.21282857297598026 0.7871714270240198 0.7038838407289004 0.2961161592710995 0.6163624262573483 0.3836375737426517 0.5544168478306979 0.4455831521693022 0.4799322822811465 0.5200677177188536
+
+ + 48 + 38 + 0.2373721698952479 0.7626278301047521 0.5190183389156114 0.48098166108438856
+
+ + 49 + 15 + 0.30580226898398105 0.6941977310160189 0.8163841592653508 0.18361584073464926
+
+ + 50 + 23 + 12 + 32 + 34 + 0.19498985341634004 0.80501014658366 0.8513619871973956 0.14863801280260439 0.5427154339497806 0.45728456605021933 0.6934681456460137 0.3065318543539862 0.3013431019327775 0.6986568980672225 0.25747887961190796 0.742521120388092 0.5876741303728849 0.4123258696271152 0.41485307483714684 0.5851469251628532 0.5814904453944699 0.41850955460553013 0.22672668533411333 0.7732733146658867 0.49969990868754705 0.5003000913124529 0.9730351087881133 0.026964891211886718 0.642848242721314 0.35715175727868603 0.695375694520765 0.304624305479235 0.7086415460606922 0.29135845393930787 0.11653595198401649 0.8834640480159835
+
+ + 51 + 12 + 13 + 28 + 0.684119142486437 0.315880857513563 0.473439484384318 0.5265605156156821 0.48879250918460276 0.5112074908153972 0.18050340784549326 0.8194965921545069 0.4110239679647732 0.5889760320352267 0.7796479541209534 0.22035204587904655 0.9759825547169171 0.024017445283082955 0.4505746544276192 0.5494253455723808
+
+ + 52 + 0.4953315117662127 0.5046684882337873
+
+ + 53 + 1 + 0.7782018475384651 0.22179815246153492 0.6171985585891516 0.38280144141084826
+
+ + 54 + 23 + 14 + 35 + 0.7531956856287044 0.2468043143712955 0.5448481638131863 0.45515183618681376 0.3747362375029909 0.6252637624970091 0.6048724508397637 0.39512754916023635 0.495488670783414 0.504511329216586 0.36456057929464425 0.6354394207053558 0.6435801463857671 0.35641985361423284 0.1499921867708502 0.8500078132291498
+
+ + 55 + 41 + 0.446713215989337 0.553286784010663 0.024195512594694032 0.975804487405306
+
+ + 56 + 36 + 38 + 0.8701510852687973 0.12984891473120277 0.6580772319785202 0.3419227680214798 0.47986654491293784 0.5201334550870622 0.7493172686148907 0.2506827313851093
+
+ + 57 + 8 + 19 + 56 + 0.30152044881276036 0.6984795511872396 0.7507569138111626 0.24924308618883736 0.402875757275934 0.5971242427240661 0.4102599166137861 0.589740083386214 0.6226810573297705 0.3773189426702296 0.37746216559860474 0.6225378344013952 0.5340336476159739 0.4659663523840261 0.7241506880622006 0.2758493119377994
+
+ + 58 + 0.10454565596401814 0.8954543440359819
+
+ + 59 + 13 + 56 + 0.44222426392185304 0.557775736078147 0.41186130612727995 0.58813869387272 0.5664961950044266 0.43350380499557334 0.5203310578437227 0.47966894215627737
+
+ + 60 + 19 + 0.5505249521468214 0.4494750478531786 0.251661946134485 0.7483380538655149
+
+ + 61 + 0.4672838881655437 0.5327161118344562
+
+ + 62 + 1 + 10 + 60 + 0.8457485512269453 0.15425144877305474 0.661187501417956 0.33881249858204404 0.36114768280606446 0.6388523171939355 0.8479494239526695 0.15205057604733058 0.558504115254521 0.4414958847454789 0.4520760741977224 0.5479239258022778 0.48095870674876623 0.5190412932512337 0.6249669465981071 0.3750330534018929
+
+ + 63 + 0.267480229575582 0.7325197704244181
+
+ + 64 + 9 + 47 + 20 + 0.7126154624296842 0.2873845375703158 0.39956829135477295 0.6004317086452271 0.4149297260501183 0.5850702739498818 0.640641579678039 0.3593584203219609 0.41397449636524997 0.58602550363475 0.23580921021950793 0.764190789780492 0.2807189801841661 0.7192810198158339 0.9024647068638644 0.09753529313613564
+
+ + 65 + 7 + 32 + 0.3979203600073781 0.6020796399926218 0.590189416818008 0.409810583181992 0.9112707907165098 0.08872920928349014 0.15546748376778688 0.8445325162322131
+
+ + 66 + 25 + 61 + 0.8983841543753724 0.10161584562462751 0.49429221661912504 0.505707783380875 0.6332665839959909 0.3667334160040092 0.8445878250384428 0.15541217496155726
+
+ + 67 + 3 + 12 + 22 + 26 + 0.5200064546693814 0.47999354533061855 0.6710819501322418 0.32891804986775824 0.5978683078670036 0.4021316921329963 0.6881811376630376 0.3118188623369623 0.5736457238491786 0.4263542761508215 0.030380628432235636 0.9696193715677643 0.4428129193730072 0.5571870806269927 0.38751221595560464 0.6124877840443953 0.4291165759202997 0.5708834240797003 0.292382029162788 0.707617970837212 0.8280630375951413 0.17193696240485865 0.7452372591935574 0.25476274080644246 0.85181280169954 0.14818719830046007 0.793862763304489 0.20613723669551093 0.816178101025048 0.18382189897495202 0.361412241578827 0.638587758421173
+
+ + 68 + 0 + 0.18189889524911204 0.8181011047508879 0.3271586747392972 0.6728413252607027
+
+ + 69 + 3 + 7 + 22 + 0.3272068850487928 0.6727931149512072 0.6327016616570176 0.3672983383429826 0.6121171781188938 0.3878828218811062 0.5994363726874414 0.4005636273125586 0.4163388904683491 0.583661109531651 0.1155270429292427 0.8844729570707575 0.4101937454170368 0.5898062545829632 0.01820412563343188 0.9817958743665681
+
+ + 70 + 42 + 44 + 0.5626288046459458 0.43737119535405417 0.3771750489869563 0.6228249510130438 0.5931298478001508 0.40687015219984923 0.8554658369726919 0.14453416302730815
+
+ + 71 + 45 + 0.157099804111539 0.842900195888461 0.3552364038925808 0.6447635961074193
+
+ + 72 + 36 + 26 + 0.9305339305941966 0.06946606940580333 0.6029094352706251 0.3970905647293749 0.7554488301488882 0.24455116985111192 0.4894469866782849 0.5105530133217152
+
+ + 73 + 16 + 45 + 0.5162028265134718 0.48379717348652823 0.5529800335458882 0.4470199664541118 0.03444549636993002 0.96555450363007 0.4749641484266176 0.5250358515733824
+
+ + 74 + 23 + 7 + 73 + 0.7580098343186674 0.24199016568133264 0.5361580624238025 0.4638419375761975 0.46160326950740993 0.5383967304925901 0.6716089138519795 0.32839108614802054 0.17118156181145167 0.8288184381885483 0.7641285595242573 0.23587144047574268 0.49216070430009107 0.5078392956999088 0.5352916303649811 0.4647083696350189
+
+ + 75 + 22 + 0.47056939687841304 0.529430603121587 0.4192006136450181 0.580799386354982
+
+
+
diff --git a/testing/Part_2/network_78.XMLBIF b/testing/Part_2/network_78.XMLBIF new file mode 100644 index 00000000..59a49f41 --- /dev/null +++ b/testing/Part_2/network_78.XMLBIF @@ -0,0 +1,890 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 64 + 0 + 1 + weight = None + + + 65 + 0 + 1 + weight = None + + + 66 + 0 + 1 + weight = None + + + 67 + 0 + 1 + weight = None + + + 68 + 0 + 1 + weight = None + + + 69 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 70 + 0 + 1 + weight = None + + + 71 + 0 + 1 + weight = None + + + 72 + 0 + 1 + weight = None + + + 73 + 0 + 1 + weight = None + + + 74 + 0 + 1 + weight = None + + + 75 + 0 + 1 + weight = None + + + 76 + 0 + 1 + weight = None + + + 77 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.590562666571533 0.40943733342846694
+
+ + 1 + 0.5531854459013418 0.4468145540986581
+
+ + 2 + 0.6197080142827088 0.38029198571729117
+
+ + 3 + 0.8506559299466873 0.14934407005331285
+
+ + 4 + 0.19476414411073525 0.8052358558892647
+
+ + 5 + 0.3086882898671564 0.6913117101328436
+
+ + 6 + 5 + 0.3854272125944302 0.6145727874055698 0.7134127173218167 0.28658728267818334
+
+ + 7 + 0.4428140414585907 0.5571859585414092
+
+ + 8 + 0.7787914385541599 0.22120856144584017
+
+ + 9 + 0.6312698123997317 0.3687301876002682
+
+ + 10 + 0.4678455992300387 0.5321544007699613
+
+ + 11 + 0.46450922464757893 0.5354907753524212
+
+ + 12 + 0.09280031346559309 0.907199686534407
+
+ + 13 + 0.1730891881954008 0.8269108118045991
+
+ + 14 + 0.403471854981513 0.596528145018487
+
+ + 15 + 0.3800951758420211 0.6199048241579789
+
+ + 16 + 9 + 0.40542168635739845 0.5945783136426016 0.47960045608166085 0.5203995439183392
+
+ + 17 + 0.6072814676963871 0.39271853230361287
+
+ + 18 + 6 + 17 + 0.3358266438869833 0.6641733561130166 0.530094031555147 0.46990596844485305 0.13729049716095948 0.8627095028390405 0.9747056855622358 0.025294314437764243
+
+ + 19 + 8 + 0.7095675570104055 0.29043244298959453 0.02933008900713791 0.970669910992862
+
+ + 20 + 0.07197678816160641 0.9280232118383936
+
+ + 21 + 0.450303511787949 0.549696488212051
+
+ + 22 + 0.32688720840445673 0.6731127915955433
+
+ + 23 + 1 + 9 + 0.10195205909020638 0.8980479409097937 0.24324140420759438 0.7567585957924056 0.30409235778790406 0.695907642212096 0.7975183535999762 0.20248164640002364
+
+ + 24 + 0.5961500462184611 0.40384995378153876
+
+ + 25 + 20 + 0.22907946810541316 0.7709205318945869 0.3185927977116311 0.6814072022883688
+
+ + 26 + 11 + 0.5339750534581722 0.4660249465418278 0.9183152879587059 0.08168471204129411
+
+ + 27 + 11 + 0.36745817435746064 0.6325418256425394 0.4938163712790133 0.5061836287209867
+
+ + 28 + 0.7143455235710375 0.2856544764289625
+
+ + 29 + 26 + 0.34875791157455305 0.651242088425447 0.43516373513718 0.56483626486282
+
+ + 30 + 29 + 0.1575116388737373 0.8424883611262627 0.8689701503034264 0.13102984969657364
+
+ + 31 + 0.9013563846122324 0.09864361538776757
+
+ + 32 + 18 + 0.3380689702879502 0.6619310297120498 0.1748865316248519 0.8251134683751481
+
+ + 33 + 0.10351977835647756 0.8964802216435225
+
+ + 34 + 11 + 32 + 0.601238037757426 0.3987619622425741 0.6392979585604789 0.360702041439521 0.7831184955386951 0.21688150446130505 0.3104831507155405 0.6895168492844594
+
+ + 35 + 28 + 0.5490086431800256 0.4509913568199742 0.4635111136528681 0.5364888863471318
+
+ + 36 + 1 + 32 + 0.965191457895292 0.03480854210470792 0.2374644258571015 0.7625355741428986 0.613004141640177 0.38699585835982303 0.06690148140162948 0.9330985185983706
+
+ + 37 + 0.7256587726497148 0.27434122735028516
+
+ + 38 + 0.8892558558609452 0.11074414413905476
+
+ + 39 + 13 + 0.07919967706475514 0.9208003229352448 0.43551009769160387 0.564489902308396
+
+ + 40 + 0.31506565908138523 0.6849343409186147
+
+ + 41 + 8 + 12 + 28 + 0.6707142140601131 0.32928578593988694 0.47240347387753007 0.52759652612247 0.5114567081200808 0.4885432918799192 0.5198902096011003 0.4801097903988996 0.5611774974222274 0.43882250257777256 0.5729895958905068 0.4270104041094931 0.17589309883861554 0.8241069011613844 0.4883139948295235 0.5116860051704765
+
+ + 42 + 5 + 13 + 0.7654887856637943 0.2345112143362057 0.035468397581299285 0.9645316024187007 0.8011250005345634 0.1988749994654366 0.11697479597672918 0.8830252040232708
+
+ + 43 + 26 + 15 + 0.44688412876155315 0.5531158712384469 0.7018922061748566 0.29810779382514335 0.5865011580437766 0.41349884195622344 0.07119879076229284 0.9288012092377071
+
+ + 44 + 42 + 13 + 0.34358824688249384 0.6564117531175061 0.2261585889321984 0.7738414110678016 0.21624240277738313 0.7837575972226168 0.611511969153886 0.388488030846114
+
+ + 45 + 20 + 0.29047800762436915 0.7095219923756308 0.6304552058327558 0.36954479416724423
+
+ + 46 + 9 + 0.6920277189418474 0.3079722810581525 0.24729752372743438 0.7527024762725657
+
+ + 47 + 36 + 38 + 0.7898800471159905 0.2101199528840096 0.5122729556593449 0.48772704434065495 0.5292052489675819 0.4707947510324181 0.33345803808908403 0.666541961910916
+
+ + 48 + 38 + 0.4280010233017337 0.5719989766982664 0.30326538648106155 0.6967346135189385
+
+ + 49 + 23 + 19 + 43 + 0.6342974827437906 0.3657025172562094 0.1491290130227993 0.8508709869772006 0.5064535627104336 0.49354643728956643 0.2868233495625019 0.7131766504374981 0.020372109169437016 0.979627890830563 0.5329038558352561 0.4670961441647439 0.673619676239823 0.32638032376017706 0.7149835300487748 0.2850164699512252
+
+ + 50 + 41 + 26 + 0.39956594512503335 0.6004340548749667 0.7852420476875904 0.21475795231240954 0.5664565392644072 0.43354346073559286 0.595836756354704 0.404163243645296
+
+ + 51 + 6 + 0.7304197937729221 0.2695802062270779 0.9593757468331726 0.040624253166827426
+
+ + 52 + 1 + 25 + 35 + 0.9493754964261575 0.05062450357384249 0.9962134735815557 0.0037865264184443457 0.6580799443391103 0.3419200556608896 0.49024582385340976 0.5097541761465902 0.23342215298634164 0.7665778470136585 0.42454375976388675 0.5754562402361132 0.7189643164976376 0.28103568350236247 0.4692811068571338 0.5307188931428661
+
+ + 53 + 14 + 0.30652764182477543 0.6934723581752246 0.4236127615086115 0.5763872384913885
+
+ + 54 + 0 + 2 + 5 + 9 + 0.5040767704472915 0.49592322955270857 0.7368495781643402 0.26315042183565984 0.4333540312515323 0.5666459687484677 0.8963137708343676 0.1036862291656324 0.45679546005607813 0.5432045399439218 0.03241006360893419 0.9675899363910658 0.6081331885122497 0.39186681148775027 0.4277663361100447 0.5722336638899552 0.13109100939751092 0.868908990602489 0.4671912512850056 0.5328087487149944 0.14606474519068213 0.8539352548093179 0.49849706565138713 0.5015029343486129 0.7176359688309711 0.28236403116902875 0.5869255147949929 0.413074485205007 0.8461168903581497 0.15388310964185029 0.04641136416680433 0.9535886358331956
+
+ + 55 + 54 + 42 + 33 + 0.5475614756839977 0.45243852431600234 0.08930244831663484 0.9106975516833652 0.34348049692177507 0.6565195030782248 0.007197709939519269 0.9928022900604807 0.2818075741520532 0.7181924258479468 0.5619722702707579 0.4380277297292421 0.8972948606768187 0.10270513932318129 0.3881692868983416 0.6118307131016584
+
+ + 56 + 0.5979981796339893 0.4020018203660108
+
+ + 57 + 27 + 0.4724265826450597 0.5275734173549403 0.5798667464225759 0.42013325357742415
+
+ + 58 + 0.6164486726996613 0.3835513273003387
+
+ + 59 + 54 + 41 + 10 + 28 + 0.833270439025614 0.166729560974386 0.8361933150312743 0.16380668496872577 0.32263886641633016 0.6773611335836698 0.36479141342684485 0.6352085865731552 0.8397799240746416 0.16022007592535834 0.09680811336720677 0.9031918866327933 0.26170816680581077 0.7382918331941892 0.43479910550665357 0.5652008944933464 0.8221398319972854 0.17786016800271467 0.2933224059739728 0.7066775940260271 0.3415976333537412 0.6584023666462588 0.7990066962033384 0.20099330379666155 0.5853133796140276 0.41468662038597237 0.18757162267597022 0.8124283773240297 0.47341446424518524 0.5265855357548148 0.24890009435331034 0.7510999056466896
+
+ + 60 + 0.3583395606047111 0.6416604393952888
+
+ + 61 + 1 + 23 + 55 + 58 + 0.031540006465003 0.968459993534997 0.5286829480833165 0.4713170519166835 0.3218855513446609 0.6781144486553391 0.438807872306777 0.561192127693223 0.234258702357537 0.765741297642463 0.5312153035092672 0.46878469649073284 0.22935096614927028 0.7706490338507297 0.4171826928791522 0.5828173071208477 0.39318684487244854 0.6068131551275515 0.04272677348718697 0.957273226512813 0.382349826008848 0.617650173991152 0.4008815444524935 0.5991184555475064 0.5210927290912608 0.47890727090873925 0.5204774326406669 0.47952256735933313 0.5732379526859851 0.4267620473140149 0.8949646348361023 0.10503536516389762
+
+ + 62 + 1 + 36 + 25 + 50 + 0.4099223011249497 0.5900776988750503 0.4212543485477072 0.5787456514522927 0.4717712178840147 0.5282287821159853 0.3717266034473334 0.6282733965526667 0.7393202940308599 0.2606797059691401 0.8576902517737565 0.14230974822624348 0.25635281010202365 0.7436471898979764 0.5242620403435971 0.47573795965640275 0.005408587904951544 0.9945914120950484 0.597724582487501 0.4022754175124989 0.4566299419516601 0.5433700580483399 0.484655329637195 0.5153446703628051 0.6235059578670962 0.3764940421329039 0.26989238150184464 0.7301076184981553 0.7848630074949488 0.2151369925050512 0.4810580399312825 0.5189419600687175
+
+ + 63 + 36 + 0.4275216597355975 0.5724783402644026 0.9520413959668222 0.04795860403317771
+
+ + 64 + 26 + 38 + 56 + 0.062276487016510076 0.9377235129834899 0.4169161948161428 0.5830838051838573 0.10073201907557001 0.8992679809244299 0.3732716563633852 0.6267283436366149 0.5646021569278892 0.4353978430721108 0.5730533846760829 0.426946615323917 0.050750783896665486 0.9492492161033346 0.8642136014412132 0.13578639855878677
+
+ + 65 + 52 + 5 + 9 + 40 + 0.9136618854242781 0.08633811457572199 0.7627048283411023 0.2372951716588977 0.3961689506659716 0.6038310493340284 0.43544932852880497 0.564550671471195 0.5739348175064474 0.42606518249355263 0.5510997958707635 0.4489002041292365 0.2747806841509585 0.7252193158490414 0.18160004408194394 0.8183999559180561 0.41705309487381065 0.5829469051261893 0.30607122068841647 0.6939287793115835 0.3195227301820183 0.6804772698179817 0.028493960477184003 0.971506039522816 0.4355688219131951 0.5644311780868049 0.8215628220824494 0.17843717791755065 0.7725311612217891 0.2274688387782109 0.18398037287474858 0.8160196271252514
+
+ + 66 + 54 + 8 + 19 + 27 + 17 + 22 + 0.2270448301166343 0.7729551698833658 0.23760575626685623 0.7623942437331437 0.3555577195884926 0.6444422804115074 0.6884328500076055 0.31156714999239443 0.6721230938546967 0.32787690614530335 0.6571298898208824 0.3428701101791177 0.735847243385785 0.26415275661421495 0.7007390399240606 0.2992609600759394 0.2781134301666592 0.7218865698333408 0.6881913167257018 0.3118086832742982 0.7073956818860284 0.29260431811397164 0.2049701817030911 0.7950298182969089 0.8527057166904144 0.14729428330958555 0.044493530267008606 0.9555064697329914 0.5694165008589614 0.4305834991410385 0.9142985946019696 0.08570140539803042 0.30054011018782234 0.6994598898121778 0.4217214616137327 0.5782785383862672 0.11057789401670932 0.8894221059832906 0.2836133453773801 0.71638665462262 0.36465924149589185 0.6353407585041081 0.4416799114968187 0.5583200885031814 0.4267066661893084 0.5732933338106916 0.2594643299454009 0.7405356700545991 0.7447582033172309 0.25524179668276914 0.16250256009014535 0.8374974399098547 0.7566214894854529 0.243378510514547 0.8465485601866363 0.15345143981336376 0.4508053725100435 0.5491946274899565 0.26760891374876605 0.732391086251234 0.24630164899168028 0.7536983510083198 0.633053962167591 0.3669460378324089 0.5003845071313121 0.49961549286868795 0.6056624820814344 0.3943375179185657 0.8482073047098767 0.15179269529012338 0.451457329496759 0.548542670503241 0.5029603072994958 0.49703969270050424 0.6194539259153589 0.38054607408464114 0.7177126134766363 0.28228738652336377 0.15157935168730358 0.8484206483126965 0.787957809859955 0.21204219014004505 0.5018096813218416 0.4981903186781584 0.42618466195264465 0.5738153380473554 0.45531958654008003 0.5446804134599201 0.5004616374762418 0.4995383625237581 0.03007400170482607 0.9699259982951739 0.8567116614075801 0.14328833859241982 0.9766993550112271 0.02330064498877292 0.41134987049341026 0.5886501295065898 0.16670081094892367 0.8332991890510764 0.47421680527560717 0.5257831947243928 0.5401322243270741 0.4598677756729259 0.009936042206495403 0.9900639577935046 0.5324870174890867 0.46751298251091333 0.8983345856348492 0.10166541436515078 0.8303700048673102 0.16962999513268984 0.4335979372812014 0.5664020627187987 0.45319106407325566 0.5468089359267443 0.33839537967586936 0.6616046203241307 0.36933825529367525 0.6306617447063247 0.3197556802149263 0.6802443197850737 0.36421708997071517 0.6357829100292849 0.42257703847357847 0.5774229615264216 0.08351007725187372 0.9164899227481262
+
+ + 67 + 46 + 26 + 34 + 0.45294254047510346 0.5470574595248966 0.4599896648438167 0.5400103351561832 0.6790547838227151 0.32094521617728483 0.36978826046438795 0.630211739535612 0.7656724934030359 0.23432750659696408 0.49516698243130136 0.5048330175686987 0.23505154614502508 0.764948453854975 0.48860038782789805 0.511399612172102
+
+ + 68 + 39 + 21 + 0.585648188143674 0.41435181185632597 0.5199138914249151 0.4800861085750849 0.24973825444070497 0.750261745559295 0.2588067782843323 0.7411932217156678
+
+ + 69 + 34 + 20 + 38 + 0.22057067558423546 0.7794293244157646 0.895175714297303 0.10482428570269699 0.49630578455821145 0.5036942154417885 0.6071902212057364 0.3928097787942635 0.5563521464254987 0.44364785357450126 0.11094235094557521 0.8890576490544247 0.6442043485503458 0.3557956514496542 0.2026272988072776 0.7973727011927224
+
+ + 70 + 8 + 10 + 64 + 55 + 0.8609264887717115 0.1390735112282885 0.3900230590769641 0.6099769409230358 0.6536666016055539 0.3463333983944461 0.011743024900951039 0.988256975099049 0.4444425740161929 0.5555574259838071 0.517563213633015 0.48243678636698495 0.6222384240280466 0.37776157597195337 0.32927841667028274 0.6707215833297171 0.4668278671244606 0.5331721328755394 0.48432658195945055 0.5156734180405494 0.04620213807213583 0.9537978619278642 0.11201450642163031 0.8879854935783696 0.5757214015397413 0.4242785984602587 0.5394716924892695 0.4605283075107305 0.7699397376691828 0.23006026233081725 0.24195814883066885 0.7580418511693312
+
+ + 71 + 28 + 56 + 0.6283633370916459 0.3716366629083541 0.8852513475258216 0.11474865247417841 0.02718749623472391 0.9728125037652761 0.3945239862695787 0.6054760137304213
+
+ + 72 + 62 + 22 + 0.5412563872671998 0.4587436127328001 0.6103274905004579 0.3896725094995421 0.16223716808819294 0.8377628319118071 0.3468729923247124 0.6531270076752876
+
+ + 73 + 7 + 39 + 68 + 31 + 0.6540695734607979 0.34593042653920214 0.615803241352027 0.3841967586479729 0.7268955627823569 0.2731044372176431 0.7407708306354988 0.2592291693645013 0.9902424453849568 0.009757554615043282 0.3769782113922492 0.6230217886077508 0.6857785724000485 0.3142214275999516 0.551498359011197 0.44850164098880296 0.06379382044712452 0.9362061795528754 0.27406979363083633 0.7259302063691636 0.3829938793946202 0.6170061206053798 0.46179736744154026 0.5382026325584598 0.23011361663722818 0.7698863833627718 0.4321444823878239 0.5678555176121761 0.42368515174065585 0.5763148482593441 0.7031780331490342 0.29682196685096585
+
+ + 74 + 54 + 26 + 0.614139373859279 0.385860626140721 0.36729279689232264 0.6327072031076774 0.006218187654826113 0.9937818123451739 0.028127704361107647 0.9718722956388923
+
+ + 75 + 0.4850721929563934 0.5149278070436065
+
+ + 76 + 4 + 0.9871218695165204 0.012878130483479579 0.8612550361992861 0.13874496380071388
+
+ + 77 + 52 + 59 + 13 + 48 + 0.23332397640566221 0.7666760235943377 0.3625378200591043 0.6374621799408958 0.6107366562561186 0.3892633437438814 0.5315150416205093 0.46848495837949056 0.6779621196530744 0.3220378803469256 0.3511763765346776 0.6488236234653224 0.24331473745445037 0.7566852625455497 0.748869547257695 0.25113045274230505 0.5577560522298183 0.4422439477701818 0.22319234512822728 0.7768076548717727 0.8810132852591095 0.11898671474089052 0.4978233580627187 0.5021766419372813 0.2495167895241596 0.7504832104758404 0.384159012008857 0.615840987991143 0.055926772970899555 0.9440732270291005 0.007922030262930296 0.9920779697370697
+
+
+
diff --git a/testing/Part_2/network_80.XMLBIF b/testing/Part_2/network_80.XMLBIF new file mode 100644 index 00000000..b79f1ca1 --- /dev/null +++ b/testing/Part_2/network_80.XMLBIF @@ -0,0 +1,907 @@ + + + + UNTITLED + + 0 + 0 + 1 + weight = None + + + 1 + 0 + 1 + weight = None + + + 10 + 0 + 1 + weight = None + + + 11 + 0 + 1 + weight = None + + + 12 + 0 + 1 + weight = None + + + 13 + 0 + 1 + weight = None + + + 14 + 0 + 1 + weight = None + + + 15 + 0 + 1 + weight = None + + + 16 + 0 + 1 + weight = None + + + 17 + 0 + 1 + weight = None + + + 18 + 0 + 1 + weight = None + + + 19 + 0 + 1 + weight = None + + + 2 + 0 + 1 + weight = None + + + 20 + 0 + 1 + weight = None + + + 21 + 0 + 1 + weight = None + + + 22 + 0 + 1 + weight = None + + + 23 + 0 + 1 + weight = None + + + 24 + 0 + 1 + weight = None + + + 25 + 0 + 1 + weight = None + + + 26 + 0 + 1 + weight = None + + + 27 + 0 + 1 + weight = None + + + 28 + 0 + 1 + weight = None + + + 29 + 0 + 1 + weight = None + + + 3 + 0 + 1 + weight = None + + + 30 + 0 + 1 + weight = None + + + 31 + 0 + 1 + weight = None + + + 32 + 0 + 1 + weight = None + + + 33 + 0 + 1 + weight = None + + + 34 + 0 + 1 + weight = None + + + 35 + 0 + 1 + weight = None + + + 36 + 0 + 1 + weight = None + + + 37 + 0 + 1 + weight = None + + + 38 + 0 + 1 + weight = None + + + 39 + 0 + 1 + weight = None + + + 4 + 0 + 1 + weight = None + + + 40 + 0 + 1 + weight = None + + + 41 + 0 + 1 + weight = None + + + 42 + 0 + 1 + weight = None + + + 43 + 0 + 1 + weight = None + + + 44 + 0 + 1 + weight = None + + + 45 + 0 + 1 + weight = None + + + 46 + 0 + 1 + weight = None + + + 47 + 0 + 1 + weight = None + + + 48 + 0 + 1 + weight = None + + + 49 + 0 + 1 + weight = None + + + 5 + 0 + 1 + weight = None + + + 50 + 0 + 1 + weight = None + + + 51 + 0 + 1 + weight = None + + + 52 + 0 + 1 + weight = None + + + 53 + 0 + 1 + weight = None + + + 54 + 0 + 1 + weight = None + + + 55 + 0 + 1 + weight = None + + + 56 + 0 + 1 + weight = None + + + 57 + 0 + 1 + weight = None + + + 58 + 0 + 1 + weight = None + + + 59 + 0 + 1 + weight = None + + + 6 + 0 + 1 + weight = None + + + 60 + 0 + 1 + weight = None + + + 61 + 0 + 1 + weight = None + + + 62 + 0 + 1 + weight = None + + + 63 + 0 + 1 + weight = None + + + 64 + 0 + 1 + weight = None + + + 65 + 0 + 1 + weight = None + + + 66 + 0 + 1 + weight = None + + + 67 + 0 + 1 + weight = None + + + 68 + 0 + 1 + weight = None + + + 69 + 0 + 1 + weight = None + + + 7 + 0 + 1 + weight = None + + + 70 + 0 + 1 + weight = None + + + 71 + 0 + 1 + weight = None + + + 72 + 0 + 1 + weight = None + + + 73 + 0 + 1 + weight = None + + + 74 + 0 + 1 + weight = None + + + 75 + 0 + 1 + weight = None + + + 76 + 0 + 1 + weight = None + + + 77 + 0 + 1 + weight = None + + + 78 + 0 + 1 + weight = None + + + 79 + 0 + 1 + weight = None + + + 8 + 0 + 1 + weight = None + + + 9 + 0 + 1 + weight = None + + + 0 + 0.16691396640677694 0.8330860335932231
+
+ + 1 + 0.23312494910321316 0.7668750508967869
+
+ + 2 + 0.9053902023199618 0.09460979768003816
+
+ + 3 + 0.5816800194476972 0.4183199805523028
+
+ + 4 + 0.4677391411067297 0.5322608588932702
+
+ + 5 + 0.489282097045883 0.510717902954117
+
+ + 6 + 0.5203704509124735 0.4796295490875265
+
+ + 7 + 0.9484301433628081 0.0515698566371919
+
+ + 8 + 0.934399647275906 0.06560035272409409
+
+ + 9 + 8 + 0.4796417532811616 0.5203582467188383 0.4027784992965645 0.5972215007034354
+
+ + 10 + 0.2662134464645107 0.7337865535354893
+
+ + 11 + 0.4442936370696801 0.5557063629303199
+
+ + 12 + 0.4473898029870925 0.5526101970129075
+
+ + 13 + 0.8334548240936277 0.16654517590637227
+
+ + 14 + 0.3547703292530532 0.6452296707469468
+
+ + 15 + 0.20158311885669883 0.7984168811433012
+
+ + 16 + 3 + 0.730364981135223 0.2696350188647771 0.7787224579464714 0.22127754205352854
+
+ + 17 + 0.9333129831857827 0.06668701681421725
+
+ + 18 + 0.003663530196648996 0.996336469803351
+
+ + 19 + 14 + 0.5096257249719303 0.49037427502806963 0.4712399999410218 0.5287600000589782
+
+ + 20 + 0.25773193289856955 0.7422680671014305
+
+ + 21 + 8 + 0.7913039571738625 0.20869604282613752 0.5408473328258007 0.45915266717419934
+
+ + 22 + 0.5914004831568703 0.4085995168431297
+
+ + 23 + 0.7763625688288411 0.2236374311711589
+
+ + 24 + 0.9347215480566442 0.06527845194335577
+
+ + 25 + 12 + 0.670595909304839 0.3294040906951611 0.2474164424915236 0.7525835575084763
+
+ + 26 + 14 + 0.9214626586456307 0.07853734135436927 0.08558931256268223 0.9144106874373179
+
+ + 27 + 0.45551292889181255 0.5444870711081875
+
+ + 28 + 0.794417077033074 0.205582922966926
+
+ + 29 + 0.21176807674298448 0.7882319232570155
+
+ + 30 + 0.406507035216853 0.593492964783147
+
+ + 31 + 25 + 24 + 0.3902075188559703 0.6097924811440296 0.014321864764933977 0.985678135235066 0.48663116848179305 0.5133688315182069 0.9538350952755937 0.046164904724406285
+
+ + 32 + 1 + 0.334396367199277 0.665603632800723 0.49462199851576516 0.5053780014842348
+
+ + 33 + 0.4692703349367227 0.5307296650632773
+
+ + 34 + 9 + 19 + 24 + 0.032898005300990324 0.9671019946990097 0.09372050032701872 0.9062794996729813 0.45768472320232895 0.542315276797671 0.680342006187585 0.31965799381241494 0.5156294394075961 0.4843705605924039 0.6738345883536488 0.32616541164635116 0.44647624229657895 0.5535237577034211 0.6130485856153817 0.3869514143846184
+
+ + 35 + 0.571637841690359 0.4283621583096411
+
+ + 36 + 35 + 0.3604796200573697 0.6395203799426303 0.40882801165635 0.59117198834365
+
+ + 37 + 0.9292315023554648 0.0707684976445352
+
+ + 38 + 0.803569040771637 0.1964309592283629
+
+ + 39 + 8 + 34 + 0.3365317236262758 0.6634682763737242 0.7844571550673196 0.2155428449326804 0.9629057430497462 0.03709425695025379 0.05067375189442851 0.9493262481055715
+
+ + 40 + 17 + 0.5542209323173893 0.44577906768261066 0.6689843398794297 0.3310156601205703
+
+ + 41 + 0.18648473370586494 0.8135152662941351
+
+ + 42 + 1 + 25 + 40 + 0.9101559057289623 0.08984409427103766 0.47215291183967145 0.5278470881603287 0.4538787077925477 0.5461212922074523 0.458530522697466 0.5414694773025339 0.5207505822705124 0.4792494177294876 0.6484560076612848 0.35154399233871536 0.9726404876576162 0.027359512342383752 0.6292833423665402 0.37071665763345985
+
+ + 43 + 42 + 38 + 0.4490867229157653 0.5509132770842348 0.5100126940474731 0.4899873059525269 0.2506671764914203 0.7493328235085798 0.6518170757134644 0.3481829242865357
+
+ + 44 + 20 + 0.2486905708590624 0.7513094291409376 0.43904199565607915 0.560958004343921
+
+ + 45 + 19 + 20 + 22 + 0.9119481587973508 0.0880518412026492 0.5072503044676415 0.4927496955323584 0.16660124898374865 0.8333987510162513 0.07448100644217563 0.9255189935578244 0.5002172000934871 0.49978279990651286 0.36959050546315153 0.6304094945368486 0.349268754183831 0.6507312458161689 0.22848646679922138 0.7715135332007785
+
+ + 46 + 32 + 4 + 27 + 0.8346662827988106 0.16533371720118936 0.2359716038200874 0.7640283961799127 0.5854367635336943 0.41456323646630566 0.24685154341538354 0.7531484565846164 0.5673934225166907 0.43260657748330933 0.6608217768954724 0.33917822310452767 0.5071587829059754 0.49284121709402456 0.466887703051496 0.5331122969485039
+
+ + 47 + 16 + 33 + 0.2615449746190835 0.7384550253809165 0.6316963677987163 0.3683036322012837 0.4489969669730959 0.5510030330269041 0.029850754628956738 0.9701492453710433
+
+ + 48 + 16 + 5 + 14 + 0.48737272981339536 0.5126272701866046 0.3547090820103163 0.6452909179896836 0.497184516301275 0.502815483698725 0.8798195609247538 0.12018043907524625 0.23429490128444755 0.7657050987155525 0.25213227023480256 0.7478677297651974 0.9000002665768982 0.0999997334231017 0.465407638949846 0.534592361050154
+
+ + 49 + 18 + 44 + 0.6211205424790969 0.37887945752090313 0.6056787804839299 0.3943212195160701 0.5356561212217222 0.4643438787782778 0.43750449982812345 0.5624955001718766
+
+ + 50 + 0.46035631587329856 0.5396436841267014
+
+ + 51 + 50 + 0.7912538212243763 0.20874617877562385 0.15549195267270083 0.8445080473272992
+
+ + 52 + 43 + 0.9695162260418039 0.03048377395819615 0.5697596437148831 0.43024035628511687
+
+ + 53 + 41 + 0.4157858440810037 0.5842141559189963 0.44550650820853477 0.5544934917914652
+
+ + 54 + 22 + 0.6162169179559828 0.3837830820440172 0.5017484787419949 0.498251521258005
+
+ + 55 + 0.5049067271169388 0.4950932728830612
+
+ + 56 + 32 + 12 + 49 + 0.3704108675661764 0.6295891324338235 0.5751542090327151 0.4248457909672849 0.3620172876192586 0.6379827123807413 0.6546900356685912 0.34530996433140876 0.7504655763783049 0.24953442362169498 0.8644080596693791 0.1355919403306209 0.8027493485361171 0.19725065146388282 0.6862450329477608 0.3137549670522393
+
+ + 57 + 0 + 0.07755890499788033 0.9224410950021197 0.6382438386056377 0.3617561613943623
+
+ + 58 + 54 + 24 + 29 + 36 + 0.15351819891080565 0.8464818010891944 0.29708799294458393 0.702912007055416 0.9132492761550056 0.0867507238449944 0.5898374918149486 0.4101625081850513 0.40350142905588293 0.5964985709441171 0.43847617653081655 0.5615238234691835 0.8126498505463093 0.1873501494536907 0.930683263664022 0.069316736335978 0.3938167127208165 0.6061832872791836 0.5502391659436988 0.44976083405630113 0.38048039271429096 0.619519607285709 0.8794804584740552 0.12051954152594481 0.34881195304762097 0.6511880469523791 0.8193773773355294 0.18062262266447054 0.41677935075646316 0.5832206492435368 0.5707930404128426 0.4292069595871574
+
+ + 59 + 32 + 10 + 37 + 0.22717085412535992 0.7728291458746401 0.7140891623207545 0.2859108376792455 0.08533339520814152 0.9146666047918585 0.4119830489671437 0.5880169510328563 0.8967995183983253 0.10320048160167476 0.7083902489027519 0.291609751097248 0.4628892510287413 0.5371107489712588 0.8396998170740849 0.16030018292591505
+
+ + 60 + 3 + 21 + 0.45102951255325807 0.5489704874467418 0.5519648701802438 0.4480351298197563 0.5969976241225299 0.40300237587747 0.6049621560536078 0.39503784394639224
+
+ + 61 + 52 + 0.23852070931918695 0.7614792906808131 0.6930535353650961 0.306946464634904
+
+ + 62 + 3 + 60 + 27 + 33 + 53 + 0.614393464125409 0.38560653587459104 0.40588997412802297 0.594110025871977 0.47350423093456073 0.5264957690654392 0.24105521468628444 0.7589447853137156 0.5532495870238126 0.44675041297618756 0.31134481135640696 0.688655188643593 0.27570680392737335 0.7242931960726267 0.3432551513655939 0.6567448486344061 0.231507366489607 0.768492633510393 0.4693459055992104 0.5306540944007896 0.4158536321346019 0.5841463678653981 0.5264844599155916 0.47351554008440844 0.5885731863904918 0.41142681360950806 0.788561936154825 0.21143806384517502 0.5482981915810726 0.4517018084189274 0.019193729083611208 0.9808062709163888 0.4378756405607096 0.5621243594392904 0.7037457797947101 0.2962542202052899 0.5158997944928237 0.48410020550717625 0.5351418605474211 0.4648581394525788 0.7381313522685693 0.2618686477314307 0.4279246861721682 0.5720753138278317 0.2636899439931465 0.7363100560068535 0.5985669190931726 0.40143308090682744 0.6404468329501161 0.35955316704988394 0.4435758939212464 0.5564241060787535 0.6734523195739096 0.3265476804260904 0.6904008281628349 0.30959917183716507 0.6060474886594442 0.3939525113405556 0.2220672639608736 0.7779327360391264 0.02656375162034987 0.9734362483796501 0.5586405678763792 0.44135943212362083
+
+ + 63 + 19 + 43 + 0.850605481847751 0.14939451815224908 0.31610956123489425 0.6838904387651058 0.45287190292220586 0.5471280970777942 0.670272628120301 0.329727371879699
+
+ + 64 + 48 + 0.14888453749961636 0.8511154625003836 0.33563392636488243 0.6643660736351175
+
+ + 65 + 46 + 6 + 10 + 56 + 58 + 0.7249985994014774 0.2750014005985226 0.5458346562453569 0.4541653437546432 0.19574161264805962 0.8042583873519404 0.5712294078213102 0.4287705921786898 0.5498672737499815 0.45013272625001866 0.7617728878683535 0.23822711213164646 0.5461521625391992 0.4538478374608008 0.5569726071542247 0.4430273928457753 0.8619480027207399 0.13805199727926007 0.48632733323191873 0.5136726667680813 0.5799943689940077 0.42000563100599236 0.4729945908674374 0.5270054091325626 0.39539441658711727 0.6046055834128826 0.20981605940333423 0.7901839405966657 0.6515437761093275 0.34845622389067243 0.3420929704602229 0.657907029539777 0.5224397063002008 0.4775602936997992 0.7946097706393243 0.2053902293606757 0.5336412950699044 0.46635870493009557 0.4887086635640171 0.5112913364359829 0.2649151942924037 0.7350848057075962 0.5436164711083329 0.45638352889166717 0.6188798811559795 0.3811201188440204 0.4075026574752646 0.5924973425247354 0.642394370777109 0.357605629222891 0.34765889989929494 0.652341100100705 0.47255204930015327 0.5274479506998467 0.47403777381878126 0.5259622261812187 0.6046906604886049 0.3953093395113951 0.9829678872874845 0.01703211271251544 0.2929910339685378 0.7070089660314621 0.6565849647150922 0.34341503528490774
+
+ + 66 + 0.3547259204238333 0.6452740795761667
+
+ + 67 + 16 + 55 + 0.11205275771777273 0.8879472422822273 0.546558150252654 0.453441849747346 0.6207405607307425 0.37925943926925754 0.5358136070147687 0.4641863929852314
+
+ + 68 + 40 + 63 + 66 + 0.21918372032213512 0.7808162796778648 0.9043891933989674 0.09561080660103251 0.266225591591849 0.733774408408151 0.04874721063661648 0.9512527893633835 0.3717821050512213 0.6282178949487787 0.40796798072070994 0.5920320192792902 0.0335267076434474 0.9664732923565525 0.5275745398946705 0.47242546010532943
+
+ + 69 + 3 + 9 + 11 + 64 + 51 + 0.46476115093454795 0.535238849065452 0.49488758882084327 0.5051124111791568 0.4513248417896151 0.5486751582103849 0.36997869201533284 0.630021307984667 0.7322075936712278 0.2677924063287724 0.5543391803935906 0.4456608196064093 0.6541844490635784 0.3458155509364216 0.14206977343655874 0.8579302265634412 0.3579040557962873 0.6420959442037127 0.7338479267987076 0.2661520732012924 0.6279093366878867 0.3720906633121134 0.8393727004007454 0.16062729959925456 0.780047550377859 0.21995244962214097 0.521729082428204 0.478270917571796 0.4093709086642767 0.5906290913357233 0.04499453291443484 0.9550054670855651 0.5143201588433618 0.48567984115663826 0.44606483934406327 0.5539351606559367 0.8595320172412336 0.14046798275876637 0.3665086947115529 0.6334913052884471 0.34008628628131055 0.6599137137186895 0.6018768146988474 0.39812318530115265 0.5067338104481326 0.49326618955186735 0.44613702511921755 0.5538629748807824 0.8751204406317542 0.12487955936824574 0.10819753826314574 0.8918024617368543 0.6102907411535747 0.3897092588464253 0.2529003317583041 0.7470996682416959 0.38610789749398344 0.6138921025060166 0.027859781741795372 0.9721402182582046 0.3156387892170701 0.68436121078293 0.3673740293359377 0.6326259706640623
+
+ + 70 + 0.24381815548003563 0.7561818445199644
+
+ + 71 + 54 + 38 + 0.1846913779500586 0.8153086220499414 0.6460654401243202 0.3539345598756798 0.9314772048241865 0.0685227951758135 0.21999304148208473 0.7800069585179152
+
+ + 72 + 33 + 52 + 0.6496624536998048 0.35033754630019526 0.07004819090384495 0.929951809096155 0.44129056046937637 0.5587094395306237 0.09362971064351254 0.9063702893564874
+
+ + 73 + 62 + 8 + 19 + 18 + 0.21178157979661702 0.788218420203383 0.5213049707540172 0.4786950292459829 0.4132474186247592 0.5867525813752408 0.2674160733931986 0.7325839266068014 0.5591025185013165 0.4408974814986836 0.7817075842399821 0.21829241576001793 0.2917756427188375 0.7082243572811625 0.5833440531296616 0.41665594687033836 0.9224681650413638 0.07753183495863629 0.6299726497827091 0.370027350217291 0.7699644358133192 0.2300355641866808 0.3438474632036891 0.6561525367963109 0.39113543339725354 0.6088645666027465 0.8104765792575166 0.18952342074248338 0.7641010225978112 0.2358989774021889 0.5756112580128983 0.4243887419871018
+
+ + 74 + 6 + 27 + 71 + 70 + 0.22150598542263994 0.7784940145773601 0.4122720778918523 0.5877279221081477 0.19058602473911154 0.8094139752608884 0.9302496344039437 0.06975036559605631 0.5837822609316611 0.41621773906833887 0.8265074732896668 0.17349252671033324 0.5811525963814965 0.4188474036185036 0.76153031751333 0.23846968248667003 0.2695975824228822 0.7304024175771179 0.6620875142053416 0.3379124857946584 0.464794143128973 0.535205856871027 0.12423564558117128 0.8757643544188287 0.6271789057922718 0.3728210942077282 0.6965187800171004 0.3034812199828997 0.7267971642547424 0.27320283574525767 0.44856449351924915 0.5514355064807509
+
+ + 75 + 0.30629707112825344 0.6937029288717466
+
+ + 76 + 69 + 23 + 0.4306226377759095 0.5693773622240905 0.8844136191256506 0.11558638087434933 0.4863818700874412 0.5136181299125588 0.4513547257039312 0.5486452742960688
+
+ + 77 + 4 + 71 + 0.9676745236023234 0.03232547639767655 0.4305906182377321 0.5694093817622679 0.5292277283341897 0.47077227166581015 0.9071813498266721 0.09281865017332788
+
+ + 78 + 57 + 69 + 77 + 68 + 0.4870071546722285 0.5129928453277715 0.18569178396143296 0.8143082160385671 0.3301897441506713 0.6698102558493286 0.6761523233184352 0.3238476766815647 0.7454589258993146 0.25454107410068544 0.9021170847818731 0.09788291521812688 0.8057212381832776 0.1942787618167224 0.27880947951589696 0.721190520484103 0.2605720217543868 0.7394279782456131 0.936026220262268 0.06397377973773195 0.3080233756125639 0.691976624387436 0.40405478118715654 0.5959452188128433 0.6615999499979486 0.33840005000205137 0.4873595953463941 0.5126404046536058 0.299320884586851 0.7006791154131491 0.5350918297500542 0.46490817024994585
+
+ + 79 + 0 + 67 + 63 + 37 + 52 + 0.49324595824124673 0.5067540417587533 0.8711493336412589 0.1288506663587411 0.3208414135225827 0.6791585864774173 0.9956351590279139 0.004364840972086131 0.6683066465578974 0.3316933534421026 0.15791247920487464 0.8420875207951254 0.32299204717755725 0.6770079528224427 0.5947397362601382 0.40526026373986174 0.48459897214588377 0.5154010278541162 0.5562214286338434 0.44377857136615656 0.4801539435252925 0.5198460564747076 0.17831653778028617 0.8216834622197138 0.24380186018948233 0.7561981398105176 0.45831744317811457 0.5416825568218855 0.45392254445657315 0.5460774555434268 0.6759464209287482 0.32405357907125176 0.9138988097272776 0.08610119027272248 0.2848326026980698 0.7151673973019302 0.1336219877619951 0.8663780122380049 0.0467270944616696 0.9532729055383304 0.5328868172452078 0.4671131827547922 0.8075743099028952 0.19242569009710475 0.7016617447229998 0.29833825527700025 0.3826152022364812 0.6173847977635187 0.6071439963152069 0.392856003684793 0.14056432426576587 0.8594356757342342 0.48023646754084576 0.5197635324591543 0.5764438445559609 0.42355615544403913 0.40494135365721995 0.59505864634278 0.5260377085380483 0.4739622914619516 0.033571407339634346 0.9664285926603656 0.18189332103421227 0.8181066789657877
+
+
+
diff --git a/use_case.py b/use_case.py new file mode 100644 index 00000000..9c51f932 --- /dev/null +++ b/use_case.py @@ -0,0 +1,65 @@ +from BNReasoner import BNReasoner +from BayesNet import BayesNet +import pandas as pd +import warnings +warnings.filterwarnings("ignore") + +if __name__ == "__main__": + print("begin") + + net = 'testing/use_case.BIFXML' + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + + + Marginal_distribution = True + checkMAP = False + checkMEP = False + + + ### Marginal distribution, a-priori for stroke or bleed + if Marginal_distribution: + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + #outcome_md = bnr.compute_marginal(['Stroke'], order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Stroke history': True, "High blood pressure": True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Anticoagulant': True, "High blood pressure": True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Diabetes': True, "70+": True, "Liver/kidney disease":True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Diabetes': True, "70+": True, "Anticoagulant":True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Smoking': True, "70+": True, "Hyperlipidemia":True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Smoking': True, "70+": True, "Diabetes":True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Smoking': True, "Blood thick": True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Stroke history': True, "Hyperlipidemia": True}), order=bnr.min_degree()) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Liver/kidney disease': True, "Stroke history": True}), order=bnr.min_degree()) + outcome_md = bnr.compute_marginal(['Internal Bleeding'], order=bnr.min_degree()) + print(outcome_md) + ''' + + ### Marginal distribution, apostpriori for stroke or bleed + if Marginal_distribution: + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + #outcome_md = bnr.compute_marginal(['Stroke'], pd.Series({'Stroke history': True, "High blood pressure": True}), order=bnr.min_degree()) + outcome_md = bnr.compute_marginal(['Internal Bleeding'], pd.Series({'Anticoagulant':True, "Diabetes":True}), order=bnr.min_degree()) + print(outcome_md) +''' + + ### MAP + if checkMAP: + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_map = bnr.MAP(["70+", "Smoker"], pd.Series({'Stroke history': True, "High blood pressure": True, "Hyperlipidemie":True})) + print(outcome_map) + + + ### MPE + if checkMEP: + bn = BayesNet() + bn.load_from_bifxml(net) + bnr = BNReasoner(bn) + outcome_mpe = bnr.MPE(pd.Series({'Stroke': True, "High blood pressure":True})) + print(outcome_mpe.to_string()) From a118e36c5c54292159f51b5949a9e0af490cedff Mon Sep 17 00:00:00 2001 From: tkaintura <40258112+tkaintura@users.noreply.github.com> Date: Fri, 16 Dec 2022 17:27:13 +0100 Subject: [PATCH 15/16] Add files via upload --- BNReasoner.py | 850 +++++++++++++++++++++----------------------------- 1 file changed, 356 insertions(+), 494 deletions(-) diff --git a/BNReasoner.py b/BNReasoner.py index d8a75e71..d6ccfb68 100644 --- a/BNReasoner.py +++ b/BNReasoner.py @@ -1,494 +1,356 @@ -from typing import Union, Dict, List -from xmlrpc.client import Boolean -from BayesNet import BayesNet -from copy import deepcopy - -import numpy as np -import pandas as pd -from typing import Dict, List, Optional, Tuple, Union - -from itertools import product, combinations - -class BNReasoner: - def __init__(self, net: Union[str, BayesNet]): - if type(net) == str: - # constructs a BN object - self.bn = BayesNet() - # Loads the BN from an BIFXML file - self.bn.load_from_bifxml(net) - else: - self.bn = net - - # TODO: This is where your methods should go - def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: - - bayes_net = deepcopy(self.bn) - finished = True # Continue checking if the pruning can continue - all_cpts = bayes_net.get_all_cpts() # A dictionary of all cps in the network indexed by the variable they belong to - while finished: # Stop pruning when the network cannot be pruned further - finished = False - for var in bayes_net.get_all_variables(): - if bayes_net.get_children(var) == [] and var not in query and var not in values: # Check if node is part of query - bayes_net.del_var(var) # Delete node if not part of query - finished = True - for a, b in values.items(): # Get node name and value - for variable in bayes_net.get_all_variables(): # Get all variables - cpt = all_cpts[variable] - if a in cpt.columns: # If variable from input matches a variable from a cpt column: - new_cpt = cpt.drop(cpt[cpt[a] != b].index) # If the same node exist with the opposite value, delete it - bayes_net.update_cpt(variable, new_cpt) # Update the cpt table without the opposite value - else: - continue - for child in bayes_net.get_children(a): # Check if the removed node has children, if yes delete edge - bayes_net.del_edge((a, child)) # Delete edge if input variable has child - finished = True -<<<<<<< Updated upstream - # print(p.get_all_cpts()," dit is p") - return p -======= - print(bayes_net.get_all_cpts()," dit is p") - return bayes_net ->>>>>>> Stashed changes - - def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: - bayes_net = deepcopy(self.bn) - reach_single = [] - iterated = [] - - for var in bayes_net.get_all_variables(): - if bayes_net.get_children(var) == [] and var not in x and var not in y and var not in z: - bayes_net.del_var(var) - for var in z: - for child in bayes_net.get_children(var): - bayes_net.del_edge([var, child]) - for var in x: - iterated.append(var) # Append variables to check - reach_single.extend(bayes_net.get_children(var)) # Append children - while list(set(reach_single) - set(iterated)) !=[]: # While loop makes sure children of children are checked - for a in list(set(reach_single) - set(iterated)): # Make sure all children are checked - reach_single.extend(bayes_net.get_children(a)) # Append children of children if there are any - iterated.append(a) # Append variable to prevent loop from checking again - for var_2 in y: - if var_2 in reach_single: # If y in x, not d-seperated - print(x, 'and', y, 'are not d-separated by', z) - return False - print(x, 'and', y, 'are d-separated by', z) # Else d-seperated - return True - - def random_order(self, network: BayesNet = None) -> List[str]: - if network is None: - return list(np.random.permutation(self.bn.get_all_variables())) - else: - return list(np.random.permutation(network.get_all_variables())) - - def min_degree(self, network: BayesNet = None) -> List[str]: - if network is None: - bayes_net = deepcopy(self.bn) - else: - bayes_net = deepcopy(network) - - return [x[0] for x in sorted(bayes_net.get_interaction_graph().degree(), key = lambda x: x[1])] # Sort list and only return the variable name - - def min_fill(self, network: BayesNet = None) -> List[str]: - if network is None: - bayes_net = deepcopy(self.bn) - else: - bayes_net = deepcopy(network) - - i_graph = bayes_net.get_interaction_graph() - order_edges = [] - for node in i_graph: - i = 0 - neighbors = i_graph.neighbors(node) - for a in neighbors: - neigh_a = i_graph.neighbors(a) - for b in neighbors: - if a == b: # Do nothing - continue - if b not in neigh_a: # Count if b is not in neigh_a - i += 1 - order_edges.append((node, i)) - return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name - -<<<<<<< Updated upstream - def init_factor(self,variables: List[str], value=0) -> pd.DataFrame: - """ - Generate a default CPT. - :param variables: Column names - :param value: Which the default p-value should be - :return: A CPT - """ -======= - def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: ->>>>>>> Stashed changes - truth_table = product([True, False], repeat=len(variables)) - factor = pd.DataFrame(truth_table, columns=variables) - factor['p'] = value - return factor - - def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - if isinstance(factor, str): - factor = self.bn.get_cpt(factor) - if isinstance(subset, str): - subset = [subset] - - new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() - new_factor['p'] = 0 - subset_factor = self.init_factor(subset) - - for i, y in new_factor.iterrows(): - for _, z in subset_factor.iterrows(): - new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( - y[:-1].append(z[:-1]), factor)['p'].sum() - # sum() instead of float() here, since the compatible table can be empty at times, this works around it - - return new_factor.reset_index(drop=True) - - def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - if isinstance(factor, str): - factor = self.bn.get_cpt(factor) - if isinstance(subset, str): - subset = [subset] - - # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get - # each possible instantiation. - ext = [c for c in factor.columns if c[:3] == 'ext'] - instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() - res_factor = pd.DataFrame(columns=factor.columns) - - if len(instantiations.columns) == 0: - try: - res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) - except IndexError: - print('w') - else: - for _, instantiation in instantiations.iterrows(): - cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) - res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) - - # For each maximized-out variable(s), rename them to ext(variable) - for v in subset: - x = res_factor.pop(v) - res_factor[f'ext({v})'] = x - - return res_factor.reset_index(drop=True) - - def factor_multiplication(self,f,g): - ''' - Given two factors f and g, compute the multiplied factor h=fg - :param f: Factor f - :param g: Factor g - :returns: Multiplied factor h=f*g - ''' - - # check what the overlapping var(s) is - vars_f = [x for x in f.columns] - vars_g = [x for x in g.columns] - - for var in vars_f: - if var in vars_g and var != 'p': - join_var = var - - # merge two dataframes - merged = f.merge(g,left_on=join_var,right_on=join_var) - - # multiply probabilities - merged['p'] = merged['p_x']*merged['p_y'] - - # drop individual probability columns - h = merged.drop(['p_x','p_y'],axis=1) - - # return h - return h - - def factor_multiplication(self, factors: List[Union[str, pd.DataFrame]]) -> pd.DataFrame: - # If there are strings in the input-list of factors, replace them with the corresponding cpt - for x, y in enumerate(factors): - if isinstance(y, str): - factors[x] = self.bn.get_cpt(y) - - new_factor = factors[0].drop('p', axis=1) - for i, factor in enumerate(factors[1:]): - try: - new_factor = new_factor.merge(factor.drop('p', axis=1), how='outer') - except pd.errors.MergeError: - new_factor = new_factor.join(factor.drop('p', axis=1), how='outer') - new_factor['p'] = 1 - - for i, z in new_factor.iterrows(): - for _, f in enumerate(factors): - new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] * self.bn.get_compatible_instantiations_table( - z[:-1], f)['p'].sum() - # sum() instead of float() here, since the compatible table can be empty at times, this works around it - - # Reordering new_factor, putting the extensions to the back - cols = new_factor.columns - ext = [c for c in cols if c[:3] == 'ext'] - if len(ext) > 0: - rest = list(np.setdiff1d(cols, ext)) - new_factor = new_factor[rest + ext] - - return new_factor.reset_index(drop=True) - - - def MPE(self, evidence: pd.Series, order_func: str = None) -> pd.DataFrame: - N = deepcopy(self.bn) - # Prune Edges - for var in evidence.keys(): - for child in N.get_children(var): - N.del_edge((var, child)) - - new = N.get_compatible_instantiations_table(evidence, N.get_cpt(child)).reset_index(drop=True) - new = new.drop([var], axis=1) - N.update_cpt(child, new) - u = N.get_compatible_instantiations_table(evidence, N.get_cpt(var)).reset_index(drop=True) - N.update_cpt(var, u) - - if order_func is None or order_func == "random": - order = self.random_order(N) - elif order_func == "min_degree": - order = self.min_degree(N) - elif order_func == "min_fill": - order = self.min_fill(N) - else: - raise Exception("Wrong order argument") - - S = N.get_all_cpts() - for var_pi in order: - # Pop all functions from S, which mention var_pi... - func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] - - new_factor = self.multiply_factors(func_k) if len(func_k) > 1 else func_k[0] - new_factor = self.maximise_out(new_factor, var_pi) - - # And replace them with the new factor - S[var_pi] = new_factor - - res_factor = self.multiply_factors(list(S.values())) if len(S) > 1 else S.popitem()[1] - return res_factor - - def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.DataFrame: - if len(np.intersect1d(list(evidence.keys()), M)) > 0: - raise Exception("Evidence cannot intersect with M") - - N = deepcopy(self.bn) - N = self.pruning(M, evidence) - for e in evidence.items(): - N.update_cpt(e[0], self.bn.get_compatible_instantiations_table(evidence, - N.get_cpt(e[0])).reset_index(drop=True)) - - if order_func is None or order_func == "random": - order = self.random_order(N) - elif order_func == "min_degree": - order = self.min_degree(N) - elif order_func == "min_fill": - order = self.min_fill(N) - else: - raise Exception("Wrong order argument") - - S = N.get_all_cpts() - for var_pi in order: - # Pop all functions from S, which mention var_pi... - func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] - - new_factor = self.factor_multiplication(func_k) if len(func_k) > 1 else func_k[0] - if var_pi in M: - new_factor = self.maximise_out(new_factor, var_pi) - else: - new_factor = self.sum_out_factors(new_factor, var_pi) - # And replace them with the new factor - # print(new_factor) - S[var_pi] = new_factor - - - res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] - return res_factor - -<<<<<<< Updated upstream - # def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - # """ - # :param factor: - # :param subset: - # :return: - # """ - # if isinstance(factor, str): - # factor = self.bn.get_cpt(factor) - # if isinstance(subset, str): - # subset = [subset] - - # # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get - # # each possible instantiation. - # ext = [c for c in factor.columns if c[:3] == 'ext'] - # instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() - # res_factor = pd.DataFrame(columns=factor.columns) - - # if len(instantiations.columns) == 0: - # try: - # res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) - # except IndexError: - # print('w') - # else: - # for _, instantiation in instantiations.iterrows(): - # cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) - # res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) - - # # For each maximized-out variable(s), rename them to ext(variable) - # for v in subset: - # x = res_factor.pop(v) - # res_factor[f'ext({v})'] = x - - # return res_factor.reset_index(drop=True) - - # def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: - # """ - # Generate a default CPT. - # :param variables: Column names - # :param value: Which the default p-value should be - # :return: A CPT - # """ - # print(variables) - # truth_table = product([True, False], repeat=len(variables)) - # factor = pd.DataFrame(truth_table, columns=variables) - # factor['p'] = value - # return factor - - # def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: - # """ - # Sum out some variable(s) in subset from a factor. - # :param factor: factor over variables X - # :param subset: a subset of variables X - # :return: a factor corresponding to the factor with the subset summed out - # """ - - # if isinstance(factor, str): - # factor = self.bn.get_cpt(factor) - # if isinstance(subset, str): - # subset = [subset] - - # new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() - # new_factor['p'] = 0 - # subset_factor = self.init_factor(subset) - - # for i, y in new_factor.iterrows(): - # for _, z in subset_factor.iterrows(): - # new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( - # y[:-1].append(z[:-1]), factor)['p'].sum() - # # sum() instead of float() here, since the compatible table can be empty at times, this works around it - - # return new_factor.reset_index(drop=True) - - def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: - """ Sum out a set of variables by using variable elimination - - Args: - data (pd.Dataframe): Dataframe of where elimination should take place - var (List): Variable to be summed out - - Returns: - pd.Dataframe: Dataframe after elimination - """ -======= - def compute_marginal(self, query: List[str], evidence: pd.Series = None, order: List[str] = None) -> pd.DataFrame: - if order is None: - order = self.random_order() - - S = self.bn.get_all_cpts() - - if evidence is not None: # If there's evidence, reduce all CPTs using the evidence - for var in self.bn.get_all_variables(): - var_cpt = self.bn.get_cpt(var) - if any(evidence.keys().intersection(var_cpt.columns)): # If the evidence occurs in the cpt - new_cpt = self.bn.get_compatible_instantiations_table(evidence, var_cpt) - S[var] = new_cpt - - pi = [nv for nv in order if nv not in query] - for var_pi in pi: - # Pop all functions from S, which mention var_pi... - func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] - - new_factor = self.factor_multiplication(func_k) - new_factor = self.sum_out_factors(new_factor, var_pi) - # And replace them with the new factor - S[var_pi] = new_factor - - res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] - - if evidence is not None: # Normalizing over pr_evidence - cpt_e = self.compute_marginal(list(evidence.keys()), order=order) - pr_evidence = float(self.bn.get_compatible_instantiations_table(evidence, cpt_e)['p']) - res_factor['p'] = res_factor['p'] / pr_evidence - - return res_factor - - def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: ->>>>>>> Stashed changes - print(data, "initial dataframe") - remaining = data.drop(columns=var) # Drop column thats need to be summed out - rem_list = list(remaining.columns.values)[:-1] # Get remaining dataframe - if len(rem_list) == 0: # If empty return empty frame - print("This was the only variable, thus no data could be returned") - return pd.DataFrame() - eliminated = remaining.groupby( # Else sum of matching values of variables - rem_list).aggregate({'p': 'sum'}) - eliminated.reset_index(inplace=True) - return eliminated - - def loop_over_children(self,bn, y, parent): - # print("parent: ", parent) - children = BayesNet.get_children(bn, parent) - # print("children: ", children) - if len(children) == 0: - return True - else: - for child in children: - if child == y: - return False - else: - if not self.loop_over_children(bn, y, child): - return False - return True -<<<<<<< Updated upstream - - def independence(self, bn, X, Y, Z): - ''' - Implementation of Markov Property and Symmetry in DAGS to determine independence - :param bn: Bayesian Network - :param X, Y, Z: sets of variable of which to decide whether X is independent of Y given Z - :returns: Bool, True if X and Y are independent given Z, False if X and Y are not independent given Z - ''' -======= - - def check_independence(self, bn, X, Y, Z): ->>>>>>> Stashed changes - Not_all_parents_of_X = False - for x in X: - for parent in BayesNet.get_all_variables(bn): - if x in BayesNet.get_children(bn, parent): - if parent not in Z: - Not_all_parents_of_X = True - break - if Not_all_parents_of_X: - break - - if Not_all_parents_of_X: - for y in Y: - for parent in BayesNet.get_all_variables(bn): - if y in BayesNet.get_children(bn, parent): - if parent not in Z: - return False - for y in Y: - # print(y) - for x in X: - # print(self.loop_over_children(bn, x, y)) - if not self.loop_over_children(bn, x, y): - # print(x, "is not a descendent of ", y) - return False - return True - - for x in X: - for y in Y: - if not self.loop_over_children(bn, y, x): - return False - - return True - +from typing import Union, Dict, List +from xmlrpc.client import Boolean +from BayesNet import BayesNet +from copy import deepcopy + +import numpy as np +import pandas as pd +from typing import Dict, List, Optional, Tuple, Union + +from itertools import product, combinations + +class BNReasoner: + def __init__(self, net: Union[str, BayesNet]): + if type(net) == str: + # constructs a BN object + self.bn = BayesNet() + # Loads the BN from an BIFXML file + self.bn.load_from_bifxml(net) + else: + self.bn = net + + # TODO: This is where your methods should go + def pruning(self,query: List[str], values: Dict[str, bool]) -> BayesNet: + + bayes_net = deepcopy(self.bn) + finished = True # Continue checking if the pruning can continue + all_cpts = bayes_net.get_all_cpts() # A dictionary of all cps in the network indexed by the variable they belong to + while finished: # Stop pruning when the network cannot be pruned further + finished = False + for var in bayes_net.get_all_variables(): + if bayes_net.get_children(var) == [] and var not in query and var not in values: # Check if node is part of query + bayes_net.del_var(var) # Delete node if not part of query + finished = True + for a, b in values.items(): # Get node name and value + for variable in bayes_net.get_all_variables(): # Get all variables + cpt = all_cpts[variable] + if a in cpt.columns: # If variable from input matches a variable from a cpt column: + new_cpt = cpt.drop(cpt[cpt[a] != b].index) # If the same node exist with the opposite value, delete it + bayes_net.update_cpt(variable, new_cpt) # Update the cpt table without the opposite value + else: + continue + for child in bayes_net.get_children(a): # Check if the removed node has children, if yes delete edge + bayes_net.del_edge((a, child)) # Delete edge if input variable has child + finished = True + print(bayes_net.get_all_cpts()," dit is p") + return bayes_net + + def d_separation(self, x: List[str], y: List[str], z: List[str]) -> bool: + bayes_net = deepcopy(self.bn) + reach_single = [] + iterated = [] + + for var in bayes_net.get_all_variables(): + if bayes_net.get_children(var) == [] and var not in x and var not in y and var not in z: + bayes_net.del_var(var) + for var in z: + for child in bayes_net.get_children(var): + bayes_net.del_edge([var, child]) + for var in x: + iterated.append(var) # Append variables to check + reach_single.extend(bayes_net.get_children(var)) # Append children + while list(set(reach_single) - set(iterated)) !=[]: # While loop makes sure children of children are checked + for a in list(set(reach_single) - set(iterated)): # Make sure all children are checked + reach_single.extend(bayes_net.get_children(a)) # Append children of children if there are any + iterated.append(a) # Append variable to prevent loop from checking again + for var_2 in y: + if var_2 in reach_single: # If y in x, not d-seperated + print(x, 'and', y, 'are not d-separated by', z) + return False + print(x, 'and', y, 'are d-separated by', z) # Else d-seperated + return True + + def random_order(self, network: BayesNet = None) -> List[str]: + if network is None: + return list(np.random.permutation(self.bn.get_all_variables())) + else: + return list(np.random.permutation(network.get_all_variables())) + + def min_degree(self, network: BayesNet = None) -> List[str]: + if network is None: + bayes_net = deepcopy(self.bn) + else: + bayes_net = deepcopy(network) + + return [x[0] for x in sorted(bayes_net.get_interaction_graph().degree(), key = lambda x: x[1])] # Sort list and only return the variable name + + def min_fill(self, network: BayesNet = None) -> List[str]: + if network is None: + bayes_net = deepcopy(self.bn) + else: + bayes_net = deepcopy(network) + + i_graph = bayes_net.get_interaction_graph() + order_edges = [] + for node in i_graph: + i = 0 + neighbors = i_graph.neighbors(node) + for a in neighbors: + neigh_a = i_graph.neighbors(a) + for b in neighbors: + if a == b: # Do nothing + continue + if b not in neigh_a: # Count if b is not in neigh_a + i += 1 + order_edges.append((node, i)) + return [x[0] for x in sorted(order_edges, key=lambda x: x[1])] # Sort the list and return only the variable name + + def init_factor(self, variables: List[str], value=0) -> pd.DataFrame: + truth_table = product([True, False], repeat=len(variables)) + factor = pd.DataFrame(truth_table, columns=variables) + factor['p'] = value + return factor + + def sum_out_factors(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + if isinstance(factor, str): + factor = self.bn.get_cpt(factor) + if isinstance(subset, str): + subset = [subset] + + new_factor = factor.drop(subset + ['p'], axis=1).drop_duplicates() + new_factor['p'] = 0 + subset_factor = self.init_factor(subset) + + for i, y in new_factor.iterrows(): + for _, z in subset_factor.iterrows(): + new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] + self.bn.get_compatible_instantiations_table( + y[:-1].append(z[:-1]), factor)['p'].sum() + # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + return new_factor.reset_index(drop=True) + + def maximise_out(self, factor: Union[str, pd.DataFrame], subset: Union[str, list]) -> pd.DataFrame: + if isinstance(factor, str): + factor = self.bn.get_cpt(factor) + if isinstance(subset, str): + subset = [subset] + + # Copy the factor, drop the variable(s) to be maximized, the extensions and 'p' and drop all duplicates to get + # each possible instantiation. + ext = [c for c in factor.columns if c[:3] == 'ext'] + instantiations = deepcopy(factor).drop(subset + ext + ['p'], axis=1).drop_duplicates() + res_factor = pd.DataFrame(columns=factor.columns) + + if len(instantiations.columns) == 0: + try: + res_factor = res_factor.append(factor.iloc[factor['p'].idxmax()]) + except IndexError: + print('w') + else: + for _, instantiation in instantiations.iterrows(): + cpt = self.bn.get_compatible_instantiations_table(instantiation, factor) + res_factor = res_factor.append(factor.iloc[cpt['p'].idxmax()]) + + # For each maximized-out variable(s), rename them to ext(variable) + for v in subset: + x = res_factor.pop(v) + res_factor[f'ext({v})'] = x + + return res_factor.reset_index(drop=True) + + + def factor_multiplication(self, factors: List[Union[str, pd.DataFrame]]) -> pd.DataFrame: + # If there are strings in the input-list of factors, replace them with the corresponding cpt + for x, y in enumerate(factors): + if isinstance(y, str): + factors[x] = self.bn.get_cpt(y) + + new_factor = factors[0].drop('p', axis=1) + for i, factor in enumerate(factors[1:]): + try: + new_factor = new_factor.merge(factor.drop('p', axis=1), how='outer') + except pd.errors.MergeError: + new_factor = new_factor.join(factor.drop('p', axis=1), how='outer') + new_factor['p'] = 1 + + for i, z in new_factor.iterrows(): + for _, f in enumerate(factors): + new_factor.loc[i, 'p'] = new_factor.loc[i, 'p'] * self.bn.get_compatible_instantiations_table( + z[:-1], f)['p'].sum() + # sum() instead of float() here, since the compatible table can be empty at times, this works around it + + # Reordering new_factor, putting the extensions to the back + cols = new_factor.columns + ext = [c for c in cols if c[:3] == 'ext'] + if len(ext) > 0: + rest = list(np.setdiff1d(cols, ext)) + new_factor = new_factor[rest + ext] + + return new_factor.reset_index(drop=True) + + + def MPE(self, evidence: pd.Series, order_func: str = None) -> pd.DataFrame: + N = deepcopy(self.bn) + # Prune Edges + for var in evidence.keys(): + for child in N.get_children(var): + N.del_edge((var, child)) + + new = N.get_compatible_instantiations_table(evidence, N.get_cpt(child)).reset_index(drop=True) + new = new.drop([var], axis=1) + N.update_cpt(child, new) + u = N.get_compatible_instantiations_table(evidence, N.get_cpt(var)).reset_index(drop=True) + N.update_cpt(var, u) + + if order_func is None or order_func == "random": + order = self.random_order(N) + elif order_func == "min_degree": + order = self.min_degree(N) + elif order_func == "min_fill": + order = self.min_fill(N) + else: + raise Exception("Wrong order argument") + + S = N.get_all_cpts() + for var_pi in order: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.factor_multiplication(func_k) if len(func_k) > 1 else func_k[0] + new_factor = self.maximise_out(new_factor, var_pi) + + # And replace them with the new factor + S[var_pi] = new_factor + + res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] + return res_factor + + def MAP(self, M: List[str], evidence: pd.Series, order_func: str = None) -> pd.DataFrame: + if len(np.intersect1d(list(evidence.keys()), M)) > 0: + raise Exception("Evidence cannot intersect with M") + + N = deepcopy(self.bn) + N = self.pruning(M, evidence) + for e in evidence.items(): + N.update_cpt(e[0], self.bn.get_compatible_instantiations_table(evidence, + N.get_cpt(e[0])).reset_index(drop=True)) + + if order_func is None or order_func == "random": + order = self.random_order(N) + elif order_func == "min_degree": + order = self.min_degree(N) + elif order_func == "min_fill": + order = self.min_fill(N) + else: + raise Exception("Wrong order argument") + + S = N.get_all_cpts() + for var_pi in order: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.factor_multiplication(func_k) if len(func_k) > 1 else func_k[0] + if var_pi in M: + new_factor = self.maximise_out(new_factor, var_pi) + else: + new_factor = self.sum_out_factors(new_factor, var_pi) + # And replace them with the new factor + # print(new_factor) + S[var_pi] = new_factor + + + res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] + return res_factor + + def compute_marginal(self, query: List[str], evidence: pd.Series = None, order: List[str] = None) -> pd.DataFrame: + if order is None: + order = self.random_order() + + S = self.bn.get_all_cpts() + + if evidence is not None: # If there's evidence, reduce all CPTs using the evidence + for var in self.bn.get_all_variables(): + var_cpt = self.bn.get_cpt(var) + if any(evidence.keys().intersection(var_cpt.columns)): # If the evidence occurs in the cpt + new_cpt = self.bn.get_compatible_instantiations_table(evidence, var_cpt) + S[var] = new_cpt + + pi = [nv for nv in order if nv not in query] + for var_pi in pi: + # Pop all functions from S, which mention var_pi... + func_k = [S.pop(key) for key, cpt in deepcopy(S).items() if var_pi in cpt] + + new_factor = self.factor_multiplication(func_k) + new_factor = self.sum_out_factors(new_factor, var_pi) + # And replace them with the new factor + S[var_pi] = new_factor + + res_factor = self.factor_multiplication(list(S.values())) if len(S) > 1 else S.popitem()[1] + + if evidence is not None: # Normalizing over pr_evidence + cpt_e = self.compute_marginal(list(evidence.keys()), order=order) + pr_evidence = float(self.bn.get_compatible_instantiations_table(evidence, cpt_e)['p']) + res_factor['p'] = res_factor['p'] / pr_evidence + + return res_factor + + def elimination(self, data: pd.DataFrame, var: List[str]) -> pd.DataFrame: + print(data, "initial dataframe") + remaining = data.drop(columns=var) # Drop column thats need to be summed out + rem_list = list(remaining.columns.values)[:-1] # Get remaining dataframe + if len(rem_list) == 0: # If empty return empty frame + print("This was the only variable, thus no data could be returned") + return pd.DataFrame() + eliminated = remaining.groupby( # Else sum of matching values of variables + rem_list).aggregate({'p': 'sum'}) + eliminated.reset_index(inplace=True) + return eliminated + + + def loop_over_children(self,bn, y, parent): + # print("parent: ", parent) + children = BayesNet.get_children(bn, parent) + # print("children: ", children) + if len(children) == 0: + return True + else: + for child in children: + if child == y: + return False + else: + if not self.loop_over_children(bn, y, child): + return False + return True + + def check_independence(self, bn, X, Y, Z): + Not_all_parents_of_X = False + for x in X: + for parent in BayesNet.get_all_variables(bn): + if x in BayesNet.get_children(bn, parent): + if parent not in Z: + Not_all_parents_of_X = True + break + if Not_all_parents_of_X: + break + + if Not_all_parents_of_X: + for y in Y: + for parent in BayesNet.get_all_variables(bn): + if y in BayesNet.get_children(bn, parent): + if parent not in Z: + return False + for y in Y: + # print(y) + for x in X: + # print(self.loop_over_children(bn, x, y)) + if not self.loop_over_children(bn, x, y): + # print(x, "is not a descendent of ", y) + return False + return True + + for x in X: + for y in Y: + if not self.loop_over_children(bn, y, x): + return False + + return True From c312723ec14b3f8bcd6dead9b1e424f067aa355e Mon Sep 17 00:00:00 2001 From: tkaintura <40258112+tkaintura@users.noreply.github.com> Date: Fri, 16 Dec 2022 17:28:06 +0100 Subject: [PATCH 16/16] Add files via upload --- test.py | 72 ++++++++++++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/test.py b/test.py index c71f3e78..653695b5 100644 --- a/test.py +++ b/test.py @@ -8,27 +8,19 @@ warnings.filterwarnings("ignore") if __name__ == "__main__": - print("begin") - - # net = 'testing/lecture_example2.BIFXML' - - net = 'testing/lecture_example.BIFXML' - bn = BayesNet() - bn.load_from_bifxml(net) - bnr = BNReasoner(bn) Pruning = True - check_d_separation = False - Independence = False - Marginalization = False - MaxingOut = False - FactorMultiplication = False - Ordering_min_degree = False - Ordering_min_fill = False - Elimination = False - Marginal_distribution = False - checkMAP = False - checkMEP = False + check_d_separation = True + Independence = True + Marginalization = True + MaxingOut = True + FactorMultiplication = True + Ordering_min_degree = True + Ordering_min_fill = True + Elimination = True + Marginal_distribution = True + checkMAP = True + checkMEP = True ### Test pruning if Pruning: @@ -36,6 +28,7 @@ bn = BayesNet() bn.load_from_bifxml(net) bnr = BNReasoner(bn) + print("#----------------------------------------Pruning---------------------------------------#") outcome = bnr.pruning(["Wet Grass?"],{'Rain?': False,'Winter?':True}) print(outcome) @@ -46,10 +39,12 @@ bn.load_from_bifxml(net) bnr = BNReasoner(bn) #outcome_d_not = bnr.d_separation(["family-out"], ["hear-bark"], ["light-on"]) # Not seperated + print("#-----------------------------------------D-seperation---------------------------------#") outcome_d = bnr.d_separation(["family-out"], ["bowel-problem"], ["light-on"]) # Seperated + print(outcome_d) - ### Test independence + ## Test independence if Independence: net = 'testing/lecture_example.BIFXML' bn = BayesNet() @@ -58,9 +53,11 @@ Y = {"Winter?"} X = {"Slippery Road?"} Z = {} - if bnr.independence(bnr.bn, X,Y,Z): + if bnr.check_independence(bnr.bn, X,Y,Z): + print("#--------------------------------Independence--------------------------------------#") print(X, "is independent from ", Y, "given ", Z) else: + print("#--------------------------------Independence--------------------------------------#") print(X, "is not independent from ", Y, "given ", Z) ### Test marginalization @@ -72,6 +69,7 @@ X = "Wet Grass?" Y = BayesNet.get_cpt(bnr.bn,X) outcome_marg = bnr.sum_out_factors(Y,X) + print("#-------------------------------Marginalization--------------------------------------#") print(outcome_marg) ### Test maxing out @@ -83,6 +81,7 @@ X = "Wet Grass?" Y = BayesNet.get_cpt(bnr.bn,X) outcome_max = bnr.maximise_out(Y,X) + print("#-------------------------------Maxing out-------------------------------------------#") print(outcome_max) ### Test factor multiplication @@ -92,6 +91,7 @@ bn.load_from_bifxml(net) bnr = BNReasoner(bn) outcome_factor = bnr.factor_multiplication(['Rain?', 'Wet Grass?']) + print("#-------------------------------Factor multiplication-------------------------------#") print(outcome_factor) ### Test ordering min @@ -101,8 +101,10 @@ bn.load_from_bifxml(net) bnr = BNReasoner(bn) outcome_min_degree = bnr.min_degree() + print("#-------------------------------Ordering min degree----------------------------------#") print(outcome_min_degree) + ### Test ordering min fill if Ordering_min_fill: net = 'testing/lecture_example.BIFXML' @@ -110,6 +112,7 @@ bn.load_from_bifxml(net) bnr = BNReasoner(bn) outcome_min_fill = bnr.min_fill() + print("#--------------------------------Ordering min fill----------------------------------#") print(outcome_min_fill) ### Elimination @@ -119,6 +122,7 @@ bn.load_from_bifxml(net) bnr = BNReasoner(bn) outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) + print("#-------------------------------Elimination---------------------------------------#") print(outcome_elim) ### Marginal distribution @@ -128,6 +132,7 @@ bn.load_from_bifxml(net) bnr = BNReasoner(bn) outcome_md = bnr.compute_marginal(['Wet Grass?', 'Slippery Road?'], order=bnr.min_degree()) + print("#-------------------------------Marginal distribution-----------------------------#") print(outcome_md) ### MAP @@ -137,34 +142,17 @@ bn.load_from_bifxml(net) bnr = BNReasoner(bn) outcome_map = bnr.MAP(['I', 'J'], pd.Series({'O': True})) + print("#-------------------------------------MAP-----------------------------------------#") print(outcome_map) - ### MPE + ## MPE if checkMEP: net = 'testing/lecture_example2.BIFXML' bn = BayesNet() bn.load_from_bifxml(net) - bnr = BNReasoner(bn) + bnr = BNReasoner(net) outcome_mpe = bnr.MPE(pd.Series({'J': True, 'O': False})) + print("#-------------------------------------MPE-----------------------------------------#") print(outcome_mpe) - # print(outcome) - - - # outcome.draw_structure() - - X = "Wet Grass?" - Y = BayesNet.get_cpt(bnr.bn,X) - # f = bnr.multip_factors(Y) - print(Y) - outcome = bnr.sum_out_factors(Y,X) #bnr.maximise_out(Y,X) - print(outcome) - - ### Elimination - outcome_elim = bnr.elimination(bn.get_cpt('Wet Grass?'), ['Rain?']) - #outcome_elim = bnr.elimination(bn.get_cpt('Winter?'), ['Winter?']) # Empty Dataframe - print(outcome_elim) - - - #python3 test.py