def _validate_no_group_cycles(member_graph):
     # verify no group cycles (i.e. group A in group B and vice versa)
     group_cycles = nx.recursive_simple_cycles(member_graph)
     if group_cycles:
         raise exceptions.DSLParsingLogicException(
             exceptions.ERROR_GROUP_CYCLE,
             'Illegal group cycles found: {0}'.format(group_cycles))
    def test_bidirectional(self):
        """
         m1 <-> m2 -> m3

        """


        self.g.add_edge('m1','m2')
        self.g.add_edge('m2','m3')
        self.g.add_edge('m3','m2')
        self.g.add_edge('m3','m4')

        # remove any models that done have links
        #for

        # determine cycles
        cycles = n.recursive_simple_cycles(self.g)
        for cycle in cycles:
            # remove edges that form cycles
            self.g.remove_edge(cycle[0],cycle[1])

        # perform toposort
        order = n.topological_sort(self.g)

        # re-add bidirectional dependencies (i.e. cycles)
        for cycle in cycles:
            # find index of inverse link
            for i in xrange(0,len(order)-1):
                if order[i] == cycle[1] and order[i+1] == cycle[0]:
                    order.insert(i+2, cycle[1])
                    order.insert(i+3,cycle[0])
                    break

        self.assertTrue(''.join(order) == 'm1m2m3m2m3m4')
    def update_cycle_counts(self, time_step):
        """ This method makes use of the recursive_simple_cycles() function of
        NetworkX to offload all the work of finding cycles in the graph. Yay!
        The lengths of the cycles are added to the ProductRuleNet's field
        named cycle_counts. NOTE: the list the algorithm returns is of list
        of nodes in the cycle where the last one is dropped because it is the
        same as the first. Thus a (sub) list of length 2 is not a self-loop, 
        but a path from one node to another and back and cycles must be
        of length two or greater. 
        """
        
        cycles = networkx.recursive_simple_cycles(self.net)

        self.cycle_counts = {}
        for i in cycles:
            length = len(i)
            try:
                self.cycle_counts[length] += 1
            except:
                self.cycle_counts[length] = 1
        
        # If there are no cycles, this run is dead and we need to send word
        if len(cycles) == 0:
            self.has_cycles = False
            return False
        else:
            return True
Exemple #4
0
 def test_simple_graph_with_reported_bug(self):
     G = nx.DiGraph()
     edges = [
         (0, 2),
         (0, 3),
         (1, 0),
         (1, 3),
         (2, 1),
         (2, 4),
         (3, 2),
         (3, 4),
         (4, 0),
         (4, 1),
         (4, 5),
         (5, 0),
         (5, 1),
         (5, 2),
         (5, 3),
     ]
     G.add_edges_from(edges)
     cc = sorted(nx.simple_cycles(G))
     assert len(cc) == 26
     rcc = sorted(nx.recursive_simple_cycles(G))
     assert len(cc) == len(rcc)
     for c in cc:
         assert any(self.is_cyclic_permutation(c, rc) for rc in rcc)
     for rc in rcc:
         assert any(self.is_cyclic_permutation(rc, c) for c in cc)
Exemple #5
0
	def get_cycle_complexity(self):
		""" This function looks at the cycles that are longer than two.
		"""

		cycles = networkx.recursive_simple_cycles(self.net)
		complexities = {} # keys are lengths, entries are # of distinct rules.
		rule_owners = {}
		for cycle in cycles:
			if len(cycle) > 2:
				length = len(cycle)
				types = {}
				owners = {}
				for rule in cycle:
					type = str(rule.get_input()) + "-" +str(rule.get_output())
					owner = rule.get_owner()
					try:
						types[type] += 1
					except:
						types[type] = 1
					try:
						owners[owner] +=1
					except:
						owners[owner] = 1

				count_owners = len(owners.keys())
				count_types = len(types.keys())

				try:
					complexities[length].append((count_types,count_owners))
				except:
					complexities[length] = [(count_types,count_owners)]

		return complexities
Exemple #6
0
    def test_bidirectional(self):
        """
         m1 <-> m2 -> m3

        """

        self.g.add_edge('m1', 'm2')
        self.g.add_edge('m2', 'm3')
        self.g.add_edge('m3', 'm2')
        self.g.add_edge('m3', 'm4')

        # remove any models that done have links
        #for

        # determine cycles
        cycles = n.recursive_simple_cycles(self.g)
        for cycle in cycles:
            # remove edges that form cycles
            self.g.remove_edge(cycle[0], cycle[1])

        # perform toposort
        order = n.topological_sort(self.g)

        # re-add bidirectional dependencies (i.e. cycles)
        for cycle in cycles:
            # find index of inverse link
            for i in xrange(0, len(order) - 1):
                if order[i] == cycle[1] and order[i + 1] == cycle[0]:
                    order.insert(i + 2, cycle[1])
                    order.insert(i + 3, cycle[0])
                    break

        self.assertTrue(''.join(order) == 'm1m2m3m2m3m4')
Exemple #7
0
 def test_simple_graph_with_reported_bug(self):
     G = nx.DiGraph()
     edges = [
         (0, 2),
         (0, 3),
         (1, 0),
         (1, 3),
         (2, 1),
         (2, 4),
         (3, 2),
         (3, 4),
         (4, 0),
         (4, 1),
         (4, 5),
         (5, 0),
         (5, 1),
         (5, 2),
         (5, 3),
     ]
     G.add_edges_from(edges)
     cc = sorted(nx.simple_cycles(G))
     assert_equal(len(cc), 26)
     rcc = sorted(nx.recursive_simple_cycles(G))
     assert_equal(len(cc), len(rcc))
     for c in cc:
         assert_true(any(self.is_cyclic_permutation(c, rc) for rc in rcc))
     for rc in rcc:
         assert_true(any(self.is_cyclic_permutation(rc, c) for c in cc))
Exemple #8
0
 def test_recursive_simple_and_not(self):
     for k in range(2,10):
         G=self.worst_case_graph(k)
         cc=sorted(nx.simple_cycles(G))
         rcc=sorted(nx.recursive_simple_cycles(G))
         assert_equal(len(cc),len(rcc))
         for c in cc:
             assert_true(any(self.is_cyclic_permutation(c,rc) for rc in rcc))
    def return_cycles(self):
        """ A direct route to the NetworkX simple cycles finding function.
        This method is only ever used in debugging because the method
        update_cycle_counts() below packages the information in a more
        useful way
        """

        return networkx.recursive_simple_cycles(self.net)
Exemple #10
0
 def elements_graph_topological_sort(self):
     try:
         return nx.topological_sort(self.element_graph)
     except nx.NetworkXUnfeasible:
         # Cycle detected
         cycle = nx.recursive_simple_cycles(self.element_graph)[0]
         names = [str(e.name) for e in cycle]
         names.append(str(names[0]))
         ex = exceptions.DSLParsingLogicException(
             exceptions.ERROR_CODE_CYCLE,
             'Parsing failed. Circular dependency detected: {0}'.format(
                 ' --> '.join(names)))
         ex.circular_dependency = names
         raise ex
Exemple #11
0
 def elements_graph_topological_sort(self):
     try:
         return nx.topological_sort(self.element_graph)
     except nx.NetworkXUnfeasible:
         # Cycle detected
         cycle = nx.recursive_simple_cycles(self.element_graph)[0]
         names = [str(e.name) for e in cycle]
         names.append(str(names[0]))
         ex = exceptions.DSLParsingLogicException(
             exceptions.ERROR_CODE_CYCLE,
             'Parsing failed. Circular dependency detected: {0}'
             .format(' --> '.join(names)))
         ex.circular_dependency = names
         raise ex
Exemple #12
0
    def determine_execution_order(self):
        """
        determines the order in which models will be executed.
         def get_link(self):
        return [self.__from_lc,self.__from_item], [self.__to_lc,self.__to_item]

        """

        g = net.DiGraph()

        # add models as graph nodes
        #for name,model in self.__models.iteritems():
        #    g.add_node(model.get_id())

        # create links between these nodes
        for id, link in self.__links.iteritems():
            f, t = link.get_link()
            from_node = f[0].get_id()
            to_node = t[0].get_id()
            g.add_edge(from_node, to_node)

        # determine cycles
        cycles = net.recursive_simple_cycles(g)
        for cycle in cycles:
            # remove edges that form cycles
            g.remove_edge(cycle[0],cycle[1])

        # perform toposort
        order = net.topological_sort(g)

        # re-add bidirectional dependencies (i.e. cycles)
        for cycle in cycles:
            # find index of inverse link
            for i in xrange(0,len(order)-1):
                if order[i] == cycle[1] and order[i+1] == cycle[0]:
                    order.insert(i+2, cycle[1])
                    order.insert(i+3,cycle[0])
                    break

        # return execution order
        return order
Exemple #13
0
    def determine_execution_order(self):
        """
        determines the order in which models will be executed.
         def get_link(self):
        return [self.__from_lc,self.__from_item], [self.__to_lc,self.__to_item]

        """

        g = net.DiGraph()

        # add models as graph nodes
        #for name,model in self.__models.iteritems():
        #    g.add_node(model.get_id())

        # create links between these nodes
        for id, link in self.__links.iteritems():
            f, t = link.get_link()
            from_node = f[0].get_id()
            to_node = t[0].get_id()
            g.add_edge(from_node, to_node)

        # determine cycles
        cycles = net.recursive_simple_cycles(g)
        for cycle in cycles:
            # remove edges that form cycles
            g.remove_edge(cycle[0], cycle[1])

        # perform toposort
        order = net.topological_sort(g)

        # re-add bidirectional dependencies (i.e. cycles)
        for cycle in cycles:
            # find index of inverse link
            for i in xrange(0, len(order) - 1):
                if order[i] == cycle[1] and order[i + 1] == cycle[0]:
                    order.insert(i + 2, cycle[1])
                    order.insert(i + 3, cycle[0])
                    break

        # return execution order
        return order
    def _create_loops(self):
        points = []
        g_cities = nx.DiGraph()

        for city in self.cities:
            city = self.cities.get(city)
            g_cities.add_node('f-' + str(city.id), bipartite=0)
            g_cities.add_node('t-' + str(city.id), bipartite=1)
            points.append([city.x, city.y])
        points = np.array(points)
        vor = Voronoi(points, incremental=True)

        for point in vor.ridge_points:
            self.cities[point[0]].add_neighbor(self.cities[point[1]])
            self.cities[point[1]].add_neighbor(self.cities[point[0]])
            g_cities.add_edge('f-' + str(self.cities[point[0]]),
                              't-' + str(self.cities[point[1]]))
            g_cities.add_edge('f-' + str(self.cities[point[1]]),
                              't-' + str(self.cities[point[0]]))

        temp = bipartite.maximum_matching(g_cities)
        print(temp)
        del g_cities
        islands = nx.DiGraph()
        i = 0
        for key, value in temp.items():
            # connect cities ...
            self.cities[int(key[2:])].connect_to(self.cities[int(value[2:])])
            islands.add_edge(self.cities[int(key[2:])],
                             self.cities[int(value[2:])])
            i += 1
            if (i >= temp.__len__() / 2):
                break
        for i, c in enumerate(nx.recursive_simple_cycles(islands)):
            # for i, c in enumerate(nx.simple_cycles(islands)):
            loop = Loop(c, i)
            self._loops.append(loop)
            self.loops.add(i)
Exemple #15
0
    node_groups = []
    trues = []
    ands = []

    # Pseudocode

    # Go through graph in reverse order
    # Get all the direct descendants of a node
    # These must be conflicts or dependencies
    # So And([list of direct descendants])
    # Inside the And we also may have Or, which would be the optional dependency groups
    # Then get the direct descendents of these nodes etc. etc.
    # Eventually we will have translated the whole graph structure to a SAT problem, can solve this and get what we need
    # to install

    cycles = nx.recursive_simple_cycles(G)
    for cycle in cycles:
        G.remove_nodes_from(cycle[1:])

    for n in G.nodes(data=True):
        direct_descendants = G[n[0]].keys()
        nodes = G.nodes(data=True)
        node_descendant = []
        var_groups = {}
        for descendant in direct_descendants:
            if 'conflict' in nodes[descendant].keys(
            ) and nodes[descendant]['conflict'] is True:
                v = Bool(descendant)
                node_descendant.append(Not(v))
                var_mapping[descendant] = v
            elif 'required' in nodes[descendant].keys(
Exemple #16
0
# -*- coding:utf8 -*-
import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
edgelist = []
with open('D:\Test\data\GUARANTEECIRCLE.del', mode='rb') as f:
    for line in f:
        data = line.decode('gbk', 'ignore').strip().split("|")
        if data[0] is not None and data[1] is not None and len(
                data[0]) > 0 and len(data[1]) > 0:
            # print(data[0], data[1])
            G.add_edge(data[0], data[1])
            # edgelist.append((data[0], data[1]))

# edgelist = [('a', 'c'), ('a', 'e'), ('b', 'a'), ('c', 'd'), ('d', 'b'), ('e', 'b')]
nx.draw(G, with_labels=True)
plt.show()
G.add_edges_from(edgelist)

print(list(nx.recursive_simple_cycles(G)))