def get_bayesian_networks(self):
        bayesian_network = GraphUtils.read_graph(self._network_name + '-' + str(self._max_parents))
        bayesian_networks = []

        if bayesian_network == None:
            #  Generate a tree (graph) with required number of nodes.
            bayesian_network = self._generate_initial_graph()
            bayesian_network.name = self._network_name + '-' + str(self._max_parents)
            GraphUtils.write_graph(bayesian_network)
            #  theoretical bound is infinity but this also does well
        num_iterations = 4 * self._num_nodes * self._num_nodes

        #  Since connectedness is only defined for undirected graphs
        #  so we have to keep a copy of the bayesian network
        #  except that all the edges are undirected
        undirected_BN = bayesian_network.to_undirected()
        bayesian_network.name = self._network_name
        #  Repeat for a large number of times.
        for i in xrange(self._num_BNs):
            count, i, j = 0, 0, 0;
            while count < num_iterations:
                edge = (i, j) = GraphUtils.get_random_edge(self._node_names)

                if bayesian_network.has_edge(*edge):
                    #  If (i,j) is in the graph, remove it
                    GraphUtils.apply_action(bayesian_network, undirected_BN, edge, 'remove', self._max_parents)
                else:
                    #  If the edge  (i,j) is not in the graph, add it.
                    GraphUtils.apply_action(bayesian_network, undirected_BN, edge, 'add', self._max_parents)
                count += 1
            bayesian_networks.append(deepcopy(bayesian_network))

        #  Return the obtained graph
        return bayesian_networks
    def _get_feasible_local_solutions(self, bayesian_network, undirected_graph, edge):
        local_solutions_action_pairs = []
        #  Calculate all possible local solutions by applying
        #  all the possible actions.
        temp_bn = deepcopy(bayesian_network)
        temp_graph = deepcopy(undirected_graph)
        for action in self._actions_list:
            #  print action + 'ing', edge, ' in ', bayesian_network.edges()
            is_feasible = GraphUtils.apply_action(temp_bn, temp_graph, (edge), action, 2)

            if not is_feasible:
                #  If the action was not feasible  then try again
                #  print 'Infeasible action.. trying with different action'
                continue

            if self._tabu_list_contains(temp_bn):
                #  If generated solution is already in the tabu list then try again
                #  print 'Solution already in tabu list trying again'
                continue
            #  print 'Got ', temp_bn.edges()
            local_solutions_action_pairs.append((temp_bn, action))
            temp_bn = deepcopy(bayesian_network)
            temp_graph = deepcopy(undirected_graph)
        return local_solutions_action_pairs