PageRenderTime 165ms CodeModel.GetById 40ms app.highlight 77ms RepoModel.GetById 43ms app.codeStats 1ms

/tests/unittests-accessibility.py

http://python-graph.googlecode.com/
Python | 327 lines | 223 code | 70 blank | 34 comment | 108 complexity | aad3f56f139421a7e0bd581ebeec91bf MD5 | raw file
  1# Copyright (c) Pedro Matiello <pmatiello@gmail.com>
  2#
  3# Permission is hereby granted, free of charge, to any person
  4# obtaining a copy of this software and associated documentation
  5# files (the "Software"), to deal in the Software without
  6# restriction, including without limitation the rights to use,
  7# copy, modify, merge, publish, distribute, sublicense, and/or sell
  8# copies of the Software, and to permit persons to whom the
  9# Software is furnished to do so, subject to the following
 10# conditions:
 11
 12# The above copyright notice and this permission notice shall be
 13# included in all copies or substantial portions of the Software.
 14
 15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 16# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 17# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 18# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 19# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 20# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 21# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 22# OTHER DEALINGS IN THE SOFTWARE.
 23
 24
 25"""
 26Unittests for graph.algorithms.accessibility
 27"""
 28
 29
 30import unittest
 31import pygraph
 32from pygraph.algorithms.searching import depth_first_search
 33from pygraph.algorithms.accessibility import accessibility
 34from pygraph.algorithms.accessibility import mutual_accessibility
 35from pygraph.algorithms.accessibility import connected_components
 36from pygraph.algorithms.accessibility import cut_nodes
 37from pygraph.algorithms.accessibility import cut_edges
 38from pygraph.classes.hypergraph import hypergraph
 39from copy import deepcopy
 40from sys import getrecursionlimit
 41import testlib
 42
 43def number_of_connected_components(cc):
 44    n = 0
 45    for each in cc:
 46        if cc[each] > n:
 47            n = cc[each]
 48    return n
 49
 50class test_accessibility(unittest.TestCase):
 51
 52    def setUp(self):
 53        pass
 54    
 55    def test_accessibility_in_graph(self):
 56        gr = testlib.new_graph()
 57        gr.add_nodes(['a','b','c'])
 58        gr.add_edge(('a','b'))
 59        gr.add_edge(('a','c'))
 60        
 61        ac = accessibility(gr)
 62        
 63        for n in gr:
 64            for m in gr:
 65                if (m in ac[n]):
 66                    assert m in depth_first_search(gr, n)[0]
 67                    assert n in depth_first_search(gr, m)[0]
 68                else:
 69                    assert m not in depth_first_search(gr, n)[0]
 70    
 71    def test_accessibility_in_digraph(self):
 72        gr = testlib.new_digraph()
 73        gr.add_nodes(['a','b','c'])
 74        gr.add_edge(('a','b'))
 75        gr.add_edge(('a','c'))
 76        
 77        ac = accessibility(gr)
 78        
 79        for n in gr:
 80            for m in gr:
 81                if (m in ac[n]):
 82                    assert m in depth_first_search(gr, n)[0]
 83                else:
 84                    assert m not in depth_first_search(gr, n)[0]
 85
 86    
 87    def test_accessibility_on_very_deep_graph(self):
 88        gr = pygraph.classes.graph.graph()
 89        gr.add_nodes(range(0,2001))
 90        for i in range(0,2000):
 91            gr.add_edge((i,i+1))
 92        recursionlimit = getrecursionlimit()
 93        accessibility(gr)
 94        assert getrecursionlimit() == recursionlimit
 95
 96    def test_mutual_accessibility_in_graph(self):
 97        gr = testlib.new_graph()
 98        gr.add_nodes(['a','b','c'])
 99        gr.add_edge(('a','b'))
100        gr.add_edge(('a','c'))
101        
102        ma = mutual_accessibility(gr)
103        for n in gr:
104            for m in gr:
105                if (m in ma[n]):
106                    assert m in depth_first_search(gr, n)[0]
107                    assert n in depth_first_search(gr, m)[0]
108                else:
109                    assert m not in depth_first_search(gr, n)[0] or n not in depth_first_search(gr, m)[0]
110    
111    def test_mutual_accessibility_on_very_deep_graph(self):
112        gr = pygraph.classes.graph.graph()
113        gr.add_nodes(range(0,5001))
114        for i in range(0,5000):
115            gr.add_edge((i,i+1))
116        recursionlimit = getrecursionlimit()
117        mutual_accessibility(gr)
118        assert getrecursionlimit() == recursionlimit
119    
120    def test_mutual_accessibility_in_digraph(self):
121        gr = testlib.new_digraph()
122        gr.add_nodes(['a','b','c'])
123        gr.add_edge(('a','b'))
124        gr.add_edge(('b','a'))
125        gr.add_edge(('a','c'))
126        
127        ma = mutual_accessibility(gr)
128        for n in gr:
129            for m in gr:
130                if (m in ma[n]):
131                    assert m in depth_first_search(gr, n)[0]
132                    assert n in depth_first_search(gr, m)[0]
133                else:
134                    assert m not in depth_first_search(gr, n)[0] or n not in depth_first_search(gr, m)[0]
135                    
136    def test_connected_components_in_graph(self):
137        gr = testlib.new_graph()
138        gr.add_nodes(['a','b','c'])
139        gr.add_edge(('a','b'))
140        
141        cc = connected_components(gr)
142        
143        for n in gr:
144            for m in gr:
145                if (cc[n] == cc[m]):
146                    assert m in depth_first_search(gr, n)[0]
147                else:
148                    assert m not in depth_first_search(gr, n)[0]
149
150    def test_connected_components_on_very_deep_graph(self):
151        gr = pygraph.classes.graph.graph()
152        gr.add_nodes(range(0,5001))
153        for i in range(0,5000):
154            gr.add_edge((i,i+1))
155        recursionlimit = getrecursionlimit()
156        connected_components(gr)
157        assert getrecursionlimit() == recursionlimit
158    
159    def test_cut_nodes_in_graph(self):
160        gr = testlib.new_graph()
161        gr.add_nodes(['x','y'])
162        gr.add_edge(('x','y'))
163        gr.add_edge(('x',0))
164        
165        gr_copy = deepcopy(gr)
166        
167        cn = cut_nodes(gr)
168        
169        for each in cn:
170            before = number_of_connected_components(connected_components(gr))
171            gr.del_node(each)
172            number_of_connected_components(connected_components(gr)) > before
173            gr = gr_copy
174    
175    def test_cut_nodes_on_very_deep_graph(self):
176        gr = pygraph.classes.graph.graph()
177        gr.add_nodes(range(0,5001))
178        for i in range(0,5000):
179            gr.add_edge((i,i+1))
180        recursionlimit = getrecursionlimit()
181        cut_nodes(gr)
182        assert getrecursionlimit() == recursionlimit
183    
184    def test_cut_edges_in_graph(self):
185        gr = testlib.new_graph()
186        gr.add_nodes(['x','y'])
187        gr.add_edge(('x','y'))
188        gr.add_edge(('x',0))
189        
190        gr_copy = deepcopy(gr)
191        
192        ce = cut_edges(gr)
193        
194        for each in ce:
195            before = number_of_connected_components(connected_components(gr))
196            gr.del_edge(each)
197            number_of_connected_components(connected_components(gr)) > before
198            gr = gr_copy
199
200    def test_cut_edges_on_very_deep_graph(self):
201        gr = pygraph.classes.graph.graph()
202        gr.add_nodes(range(0,5001))
203        for i in range(0,5000):
204            gr.add_edge((i,i+1))
205        recursionlimit = getrecursionlimit()
206        cut_edges(gr)
207        assert getrecursionlimit() == recursionlimit
208
209    def test_accessibility_hypergraph(self):
210        gr = hypergraph()
211        
212        # Add some nodes / edges
213        gr.add_nodes(range(8))
214        gr.add_hyperedges(['a', 'b', 'c'])
215        
216        # Connect the 9 nodes with three size-3 hyperedges
217        for node_set in [['a',0,1,2], ['b',2,3,4], ['c',5,6,7]]:
218            for node in node_set[1:]:
219                gr.link(node, node_set[0])
220        
221        access = accessibility(gr)
222        
223        assert 8 == len(access)
224        
225        for i in range(5):
226            assert set(access[i]) == set(range(5))
227        
228        for i in range(5,8):
229            assert set(access[i]) == set(range(5,8))
230        
231    def test_connected_components_hypergraph(self):
232        gr = hypergraph()
233        
234        # Add some nodes / edges
235        gr.add_nodes(range(9))
236        gr.add_hyperedges(['a', 'b', 'c'])
237        
238        # Connect the 9 nodes with three size-3 hyperedges
239        for node_set in [['a',0,1,2], ['b',3,4,5], ['c',6,7,8]]:
240            for node in node_set[1:]:
241                gr.link(node, node_set[0])
242        
243        cc = connected_components(gr)
244        
245        assert 3 == len(set(cc.values()))
246        
247        assert cc[0] == cc[1] and cc[1] == cc[2]
248        assert cc[3] == cc[4] and cc[4] == cc[5]
249        assert cc[6] == cc[7] and cc[7] == cc[8]
250        
251        
252        # Do it again with two components and more than one edge for each
253        gr = hypergraph()
254        gr.add_nodes(range(9))
255        gr.add_hyperedges(['a', 'b', 'c', 'd'])
256        
257        for node_set in [['a',0,1,2], ['b',2,3,4], ['c',5,6,7], ['d',6,7,8]]:
258            for node in node_set[1:]:
259                gr.link(node, node_set[0])
260        
261        cc = connected_components(gr)
262        
263        assert 2 == len(set(cc.values()))
264        
265        for i in [0,1,2,3]:
266            assert cc[i] == cc[i+1]
267        
268        for i in [5,6,7]:
269            assert cc[i] == cc[i+1]
270            
271        assert cc[4] != cc[5]
272    
273    def test_cut_nodes_in_hypergraph(self):
274        gr = hypergraph()
275        
276        # Add some nodes / edges
277        gr.add_nodes(range(9))
278        gr.add_hyperedges(['a', 'b', 'c'])
279        
280        # Connect the 9 nodes with three size-3 hyperedges
281        for node_set in [['a',0,1,2], ['b',3,4,5], ['c',6,7,8]]:
282            for node in node_set[1:]:
283                gr.link(node, node_set[0])
284        
285        # Connect the groups
286        gr.add_hyperedges(['l1','l2'])
287        gr.link(0, 'l1')
288        gr.link(3, 'l1')
289        gr.link(5, 'l2')
290        gr.link(8, 'l2')
291        
292        cn = cut_nodes(gr);
293        
294        assert 0 in cn
295        assert 3 in cn
296        assert 5 in cn
297        assert 8 in cn
298        assert len(cn) == 4
299    
300    def test_cut_edges_in_hypergraph(self):
301        gr = hypergraph()
302        
303        # Add some nodes / edges
304        gr.add_nodes(range(9))
305        gr.add_hyperedges(['a1', 'b1', 'c1'])
306        gr.add_hyperedges(['a2', 'b2', 'c2'])
307        
308        # Connect the 9 nodes with three size-3 hyperedges
309        for node_set in [['a1',0,1,2], ['b1',3,4,5], ['c1',6,7,8], ['a2',0,1,2], ['b2',3,4,5], ['c2',6,7,8]]:
310            for node in node_set[1:]:
311                gr.link(node, node_set[0])
312        
313        # Connect the groups
314        gr.add_hyperedges(['l1','l2'])
315        gr.link(0, 'l1')
316        gr.link(3, 'l1')
317        gr.link(5, 'l2')
318        gr.link(8, 'l2')
319        
320        ce = cut_edges(gr)
321        
322        assert 'l1' in ce
323        assert 'l2' in ce
324        assert len(ce) == 2
325        
326if __name__ == "__main__":
327    unittest.main()