├── python-graph ├── tests │ ├── __init__.py │ ├── test_data.py │ ├── testlib.py │ ├── testrunner.py │ ├── unittests-critical.py │ ├── unittests-sorting.py │ ├── unittests-heuristics.py │ ├── unittests-cycles.py │ ├── unittests-pagerank.py │ ├── unittests-readwrite.py │ ├── unittests-searching.py │ └── unittests-filters.py ├── dot │ ├── python_graph_dot.egg-info │ │ ├── dependency_links.txt │ │ ├── namespace_packages.txt │ │ ├── requires.txt │ │ ├── top_level.txt │ │ ├── SOURCES.txt │ │ └── PKG-INFO │ ├── pygraph │ │ ├── __init__.py │ │ ├── readwrite │ │ │ └── __init__.py │ │ └── __init__.pyc │ ├── build │ │ └── lib.linux-i686-2.6 │ │ │ └── pygraph │ │ │ ├── __init__.py │ │ │ └── readwrite │ │ │ └── __init__.py │ ├── distribute_setup.pyc │ ├── distribute-0.6.24.tar.gz │ ├── distribute-0.6.24-py2.6.egg │ ├── dist │ │ └── python_graph_dot-1.8.2-py2.6.egg │ └── setup.py ├── core │ ├── python_graph_core.egg-info │ │ ├── dependency_links.txt │ │ ├── namespace_packages.txt │ │ ├── top_level.txt │ │ ├── PKG-INFO │ │ └── SOURCES.txt │ ├── distribute_setup.pyc │ ├── pygraph │ │ ├── __init__.pyc │ │ ├── classes │ │ │ ├── __init__.py │ │ │ └── exceptions.py │ │ ├── algorithms │ │ │ ├── filters │ │ │ │ ├── __init__.py │ │ │ │ ├── null.py │ │ │ │ ├── find.py │ │ │ │ └── radius.py │ │ │ ├── __init__.py │ │ │ ├── heuristics │ │ │ │ ├── __init__.py │ │ │ │ ├── chow.py │ │ │ │ └── euclidean.py │ │ │ ├── sorting.py │ │ │ ├── traversal.py │ │ │ ├── pagerank.py │ │ │ ├── utils.py │ │ │ ├── cycles.py │ │ │ ├── generators.py │ │ │ ├── searching.py │ │ │ └── critical.py │ │ ├── readwrite │ │ │ └── __init__.py │ │ ├── mixins │ │ │ ├── __init__.py │ │ │ └── basegraph.py │ │ └── __init__.py │ ├── distribute-0.6.24.tar.gz │ ├── distribute-0.6.24-py2.6.egg │ ├── dist │ │ └── python_graph_core-1.8.2-py2.6.egg │ ├── setup.py │ └── build │ │ └── lib.linux-i686-2.6 │ │ └── pygraph │ │ ├── classes │ │ ├── __init__.py │ │ └── exceptions.py │ │ ├── algorithms │ │ ├── filters │ │ │ ├── __init__.py │ │ │ ├── null.py │ │ │ ├── find.py │ │ │ └── radius.py │ │ ├── __init__.py │ │ ├── heuristics │ │ │ ├── __init__.py │ │ │ ├── chow.py │ │ │ └── euclidean.py │ │ ├── sorting.py │ │ ├── traversal.py │ │ ├── pagerank.py │ │ ├── utils.py │ │ ├── cycles.py │ │ ├── generators.py │ │ └── searching.py │ │ ├── readwrite │ │ └── __init__.py │ │ ├── mixins │ │ ├── __init__.py │ │ └── basegraph.py │ │ └── __init__.py ├── .DS_Store ├── misc │ ├── logo.png │ └── logo.txt ├── COPYING ├── Makefile └── README ├── src ├── wcbg.png ├── cluster.png ├── hotpath.png ├── malware1.png ├── malware2.png ├── wcbg.dot ├── hotpath.dot ├── ismalware.py ├── malware1.xml ├── mincs.py ├── malware2.xml ├── mcs.py └── wcbg.py ├── README.md └── malwaresamples └── Test ├── mal3.xml ├── mal4.xml ├── mal1.xml └── mal2.xml /python-graph/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /python-graph/dot/python_graph_dot.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /python-graph/core/python_graph_core.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /python-graph/dot/python_graph_dot.egg-info/namespace_packages.txt: -------------------------------------------------------------------------------- 1 | pygraph 2 | -------------------------------------------------------------------------------- /python-graph/core/python_graph_core.egg-info/namespace_packages.txt: -------------------------------------------------------------------------------- 1 | pygraph 2 | -------------------------------------------------------------------------------- /python-graph/dot/python_graph_dot.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | python-graph-core==1.8.2 2 | pydot -------------------------------------------------------------------------------- /python-graph/dot/python_graph_dot.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | pygraph 2 | pygraph/readwrite 3 | -------------------------------------------------------------------------------- /src/wcbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/src/wcbg.png -------------------------------------------------------------------------------- /python-graph/dot/pygraph/__init__.py: -------------------------------------------------------------------------------- 1 | __import__('pkg_resources').declare_namespace(__name__) 2 | -------------------------------------------------------------------------------- /src/cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/src/cluster.png -------------------------------------------------------------------------------- /src/hotpath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/src/hotpath.png -------------------------------------------------------------------------------- /src/malware1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/src/malware1.png -------------------------------------------------------------------------------- /src/malware2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/src/malware2.png -------------------------------------------------------------------------------- /python-graph/dot/pygraph/readwrite/__init__.py: -------------------------------------------------------------------------------- 1 | __import__('pkg_resources').declare_namespace(__name__) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Malware-Classifier 2 | ================== 3 | 4 | Malware Classification using Graph Clustering -------------------------------------------------------------------------------- /python-graph/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/.DS_Store -------------------------------------------------------------------------------- /python-graph/misc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/misc/logo.png -------------------------------------------------------------------------------- /python-graph/dot/build/lib.linux-i686-2.6/pygraph/__init__.py: -------------------------------------------------------------------------------- 1 | __import__('pkg_resources').declare_namespace(__name__) 2 | -------------------------------------------------------------------------------- /python-graph/dot/build/lib.linux-i686-2.6/pygraph/readwrite/__init__.py: -------------------------------------------------------------------------------- 1 | __import__('pkg_resources').declare_namespace(__name__) -------------------------------------------------------------------------------- /python-graph/core/distribute_setup.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/core/distribute_setup.pyc -------------------------------------------------------------------------------- /python-graph/core/pygraph/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/core/pygraph/__init__.pyc -------------------------------------------------------------------------------- /python-graph/dot/distribute_setup.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/dot/distribute_setup.pyc -------------------------------------------------------------------------------- /python-graph/dot/pygraph/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/dot/pygraph/__init__.pyc -------------------------------------------------------------------------------- /python-graph/dot/distribute-0.6.24.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/dot/distribute-0.6.24.tar.gz -------------------------------------------------------------------------------- /python-graph/core/distribute-0.6.24.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/core/distribute-0.6.24.tar.gz -------------------------------------------------------------------------------- /python-graph/dot/distribute-0.6.24-py2.6.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/dot/distribute-0.6.24-py2.6.egg -------------------------------------------------------------------------------- /python-graph/core/distribute-0.6.24-py2.6.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/core/distribute-0.6.24-py2.6.egg -------------------------------------------------------------------------------- /python-graph/core/python_graph_core.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | pygraph/classes 2 | pygraph/readwrite 3 | pygraph 4 | pygraph/mixins 5 | pygraph/algorithms 6 | -------------------------------------------------------------------------------- /python-graph/dot/dist/python_graph_dot-1.8.2-py2.6.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/dot/dist/python_graph_dot-1.8.2-py2.6.egg -------------------------------------------------------------------------------- /python-graph/core/dist/python_graph_core-1.8.2-py2.6.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahulp0491/Malware-Classifier/HEAD/python-graph/core/dist/python_graph_core-1.8.2-py2.6.egg -------------------------------------------------------------------------------- /python-graph/misc/logo.txt: -------------------------------------------------------------------------------- 1 | LICENCE 2 | 3 | The image is provided under Creative Commons Attribution-Share Alike 3.0 4 | license. Check http://creativecommons.org/licenses/by-sa/3.0/ for more 5 | information. 6 | 7 | ATTRIBUTION: 8 | The artwork for the official logo of python-graph 9 | was designed by Tomaž Kovačič 10 | . 11 | 12 | 13 | -------------------------------------------------------------------------------- /python-graph/dot/python_graph_dot.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | setup.py 2 | pygraph/__init__.py 3 | pygraph/readwrite/__init__.py 4 | pygraph/readwrite/dot.py 5 | python_graph_dot.egg-info/PKG-INFO 6 | python_graph_dot.egg-info/SOURCES.txt 7 | python_graph_dot.egg-info/dependency_links.txt 8 | python_graph_dot.egg-info/namespace_packages.txt 9 | python_graph_dot.egg-info/requires.txt 10 | python_graph_dot.egg-info/top_level.txt -------------------------------------------------------------------------------- /src/wcbg.dot: -------------------------------------------------------------------------------- 1 | digraph graphname { 2 | 1 [nodename=analysis]; 3 | 2 [nodename=process_call]; 4 | 3 [nodename=process_call]; 5 | 5 [nodename=process]; 6 | 6 [nodename=load_image]; 7 | 7 [nodename=load_dll]; 8 | 8 [nodename=load_dll]; 9 | 1 -> 2 [weight="0.5", label="0.5"]; 10 | 1 -> 3 [weight="0.5", label="0.5"]; 11 | 2 -> 5 [weight="0.5", label="0.5"]; 12 | 5 -> 6 [weight="0.5", label="0.5"]; 13 | 5 -> 7 [weight="0.5", label="0.5"]; 14 | 5 -> 8 [weight="0.5", label="0.5"]; 15 | } 16 | -------------------------------------------------------------------------------- /src/hotpath.dot: -------------------------------------------------------------------------------- 1 | digraph graphname { 2 | "(6, 40)" [nodename=load_image]; 3 | "(5, 39)" [nodename=process]; 4 | "(8, 42)" [nodename=load_dll]; 5 | "(1, 36)" [nodename=analysis]; 6 | "(3, 38)" [nodename=process_call]; 7 | "(2, 37)" [nodename=process_call]; 8 | "(7, 41)" [nodename=load_dll]; 9 | "(5, 39)" -> "(6, 40)" [weight=2, label=2]; 10 | "(5, 39)" -> "(7, 41)" [weight=2, label=2]; 11 | "(5, 39)" -> "(8, 42)" [weight=2, label=2]; 12 | "(1, 36)" -> "(2, 37)" [weight=2, label=2]; 13 | "(1, 36)" -> "(3, 38)" [weight=2, label=2]; 14 | "(2, 37)" -> "(5, 39)" [weight=2, label=2]; 15 | } 16 | -------------------------------------------------------------------------------- /python-graph/dot/python_graph_dot.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: python-graph-dot 3 | Version: 1.8.2 4 | Summary: DOT support for python-graph 5 | Home-page: http://code.google.com/p/python-graph/ 6 | Author: Pedro Matiello 7 | Author-email: pmatiello@gmail.com 8 | License: MIT 9 | Description: python-graph is a library for working with graphs in Python. This software provides a suitable data structure for representing graphs and a whole set of important algorithms. 10 | Keywords: python graphs hypergraphs networks library algorithms 11 | Platform: UNKNOWN 12 | Classifier: License :: OSI Approved :: MIT License 13 | Classifier: Topic :: Software Development :: Libraries :: Python Modules 14 | -------------------------------------------------------------------------------- /python-graph/core/python_graph_core.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: python-graph-core 3 | Version: 1.8.2 4 | Summary: A library for working with graphs in Python 5 | Home-page: http://code.google.com/p/python-graph/ 6 | Author: Pedro Matiello 7 | Author-email: pmatiello@gmail.com 8 | License: MIT 9 | Description: python-graph is a library for working with graphs in Python. This software provides a suitable data structure for representing graphs and a whole set of important algorithms. 10 | Keywords: python graphs hypergraphs networks library algorithms 11 | Platform: UNKNOWN 12 | Classifier: License :: OSI Approved :: MIT License 13 | Classifier: Topic :: Software Development :: Libraries :: Python Modules 14 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/classes/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Data structure classes. 27 | """ -------------------------------------------------------------------------------- /python-graph/core/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | 6 | try: 7 | from setuptools import setup, find_packages 8 | except ImportError as ie: 9 | import distribute_setup 10 | distribute_setup.use_setuptools() 11 | from setuptools import setup, find_packages 12 | 13 | # Startup 14 | appname = "python-graph-core" 15 | appversion = "1.8.2" 16 | 17 | setup( 18 | name = appname, 19 | version = appversion, 20 | author = "Pedro Matiello", 21 | namespace_packages = ["pygraph"], 22 | packages = ["pygraph"] + [ os.path.join("pygraph", a) for a in find_packages("pygraph") ], 23 | author_email = "pmatiello@gmail.com", 24 | description = "A library for working with graphs in Python", 25 | license = "MIT", 26 | keywords = "python graphs hypergraphs networks library algorithms", 27 | url = "http://code.google.com/p/python-graph/", 28 | classifiers = ["License :: OSI Approved :: MIT License","Topic :: Software Development :: Libraries :: Python Modules"], 29 | long_description = "python-graph is a library for working with graphs in Python. This software provides a suitable data structure for representing graphs and a whole set of important algorithms.", 30 | ) 31 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/classes/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Data structure classes. 27 | """ -------------------------------------------------------------------------------- /python-graph/core/python_graph_core.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | setup.py 2 | pygraph/__init__.py 3 | pygraph/algorithms/__init__.py 4 | pygraph/algorithms/accessibility.py 5 | pygraph/algorithms/critical.py 6 | pygraph/algorithms/cycles.py 7 | pygraph/algorithms/generators.py 8 | pygraph/algorithms/minmax.py 9 | pygraph/algorithms/pagerank.py 10 | pygraph/algorithms/searching.py 11 | pygraph/algorithms/sorting.py 12 | pygraph/algorithms/traversal.py 13 | pygraph/algorithms/utils.py 14 | pygraph/algorithms/filters/__init__.py 15 | pygraph/algorithms/filters/find.py 16 | pygraph/algorithms/filters/null.py 17 | pygraph/algorithms/filters/radius.py 18 | pygraph/algorithms/heuristics/__init__.py 19 | pygraph/algorithms/heuristics/chow.py 20 | pygraph/algorithms/heuristics/euclidean.py 21 | pygraph/classes/__init__.py 22 | pygraph/classes/digraph.py 23 | pygraph/classes/exceptions.py 24 | pygraph/classes/graph.py 25 | pygraph/classes/hypergraph.py 26 | pygraph/mixins/__init__.py 27 | pygraph/mixins/basegraph.py 28 | pygraph/mixins/common.py 29 | pygraph/mixins/labeling.py 30 | pygraph/readwrite/__init__.py 31 | pygraph/readwrite/markup.py 32 | python_graph_core.egg-info/PKG-INFO 33 | python_graph_core.egg-info/SOURCES.txt 34 | python_graph_core.egg-info/dependency_links.txt 35 | python_graph_core.egg-info/namespace_packages.txt 36 | python_graph_core.egg-info/top_level.txt -------------------------------------------------------------------------------- /python-graph/dot/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | 6 | 7 | try: 8 | from setuptools import setup, find_packages 9 | except ImportError as ie: 10 | import distribute_setup 11 | distribute_setup.use_setuptools() 12 | from setuptools import setup, find_packages 13 | 14 | # Startup 15 | appname = "python-graph-dot" 16 | appversion = "1.8.2" 17 | 18 | setup( 19 | name = appname, 20 | version = appversion, 21 | namespace_packages = ["pygraph"], 22 | packages = ["pygraph"] + [ os.path.join("pygraph", a) for a in find_packages("pygraph") ], 23 | install_requires = [ 'python-graph-core==%s' % appversion, 'pydot' ], 24 | author = "Pedro Matiello", 25 | author_email = "pmatiello@gmail.com", 26 | description = "DOT support for python-graph", 27 | license = "MIT", 28 | keywords = "python graphs hypergraphs networks library algorithms", 29 | url = "http://code.google.com/p/python-graph/", 30 | classifiers = ["License :: OSI Approved :: MIT License","Topic :: Software Development :: Libraries :: Python Modules"], 31 | long_description = "python-graph is a library for working with graphs in Python. This software provides a suitable data structure for representing graphs and a whole set of important algorithms.", 32 | ) 33 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/filters/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Set of searching filters. 27 | """ 28 | 29 | __import__('pkg_resources').declare_namespace(__name__) 30 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/filters/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Set of searching filters. 27 | """ 28 | 29 | __import__('pkg_resources').declare_namespace(__name__) 30 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/readwrite/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Readwrite algorithms. 27 | 28 | Algorithms for reading and writing graphs. 29 | """ 30 | 31 | __import__('pkg_resources').declare_namespace(__name__) -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/readwrite/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Readwrite algorithms. 27 | 28 | Algorithms for reading and writing graphs. 29 | """ 30 | 31 | __import__('pkg_resources').declare_namespace(__name__) -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Algorithms 27 | 28 | This subpackage contains a set of modules, each one of them containing some algorithms. 29 | """ 30 | 31 | __import__('pkg_resources').declare_namespace(__name__) 32 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Algorithms 27 | 28 | This subpackage contains a set of modules, each one of them containing some algorithms. 29 | """ 30 | 31 | __import__('pkg_resources').declare_namespace(__name__) 32 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/mixins/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Mixins. 27 | 28 | Base classes used to compose the the graph classes. 29 | 30 | The classes in this namespace should not be used directly. 31 | """ 32 | 33 | __import__('pkg_resources').declare_namespace(__name__) 34 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/mixins/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Mixins. 27 | 28 | Base classes used to compose the the graph classes. 29 | 30 | The classes in this namespace should not be used directly. 31 | """ 32 | 33 | __import__('pkg_resources').declare_namespace(__name__) 34 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/heuristics/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Set of search heuristics. 28 | 29 | These are to be used with the C{heuristic_search()} function. 30 | """ 31 | 32 | __import__('pkg_resources').declare_namespace(__name__) 33 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/heuristics/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Set of search heuristics. 28 | 29 | These are to be used with the C{heuristic_search()} function. 30 | """ 31 | 32 | __import__('pkg_resources').declare_namespace(__name__) 33 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/mixins/basegraph.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | class basegraph( object ): 27 | """ 28 | An abstract class intended as a common ancestor to all graph classes. This allows the user 29 | to test isinstance(X, basegraph) to determine if the object is one of any of the python-graph 30 | main classes. 31 | """ 32 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/mixins/basegraph.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | class basegraph( object ): 27 | """ 28 | An abstract class intended as a common ancestor to all graph classes. This allows the user 29 | to test isinstance(X, basegraph) to determine if the object is one of any of the python-graph 30 | main classes. 31 | """ 32 | -------------------------------------------------------------------------------- /python-graph/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2012 Pedro Matiello 2 | Christian Muise 3 | Eugen Zagorodniy 4 | Johannes Reinhardt 5 | Nathan Davis 6 | Paul Harrison 7 | Rhys Ulerich 8 | Roy Smith 9 | Salim Fadhley 10 | Tomaz Kovacic 11 | Zsolt Haraszti 12 | 13 | Permission is hereby granted, free of charge, to any person 14 | obtaining a copy of this software and associated documentation 15 | files (the "Software"), to deal in the Software without 16 | restriction, including without limitation the rights to use, 17 | copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the 19 | Software is furnished to do so, subject to the following 20 | conditions: 21 | 22 | The above copyright notice and this permission notice shall be 23 | included in all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 27 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 29 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 30 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 31 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 32 | OTHER DEALINGS IN THE SOFTWARE. 33 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/sorting.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007-2009 Pedro Matiello 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 | """ 26 | Sorting algorithms. 27 | 28 | @sort: topological_sorting 29 | """ 30 | 31 | 32 | # Imports 33 | from pygraph.algorithms.searching import depth_first_search 34 | 35 | # Topological sorting 36 | def topological_sorting(graph): 37 | """ 38 | Topological sorting. 39 | 40 | @attention: Topological sorting is meaningful only for directed acyclic graphs. 41 | 42 | @type graph: digraph 43 | @param graph: Graph. 44 | 45 | @rtype: list 46 | @return: Topological sorting for the graph. 47 | """ 48 | # The topological sorting of a DAG is equivalent to its reverse postordering. 49 | order = depth_first_search(graph)[2] 50 | order.reverse() 51 | return order 52 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/sorting.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007-2009 Pedro Matiello 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 | """ 26 | Sorting algorithms. 27 | 28 | @sort: topological_sorting 29 | """ 30 | 31 | 32 | # Imports 33 | from pygraph.algorithms.searching import depth_first_search 34 | 35 | # Topological sorting 36 | def topological_sorting(graph): 37 | """ 38 | Topological sorting. 39 | 40 | @attention: Topological sorting is meaningful only for directed acyclic graphs. 41 | 42 | @type graph: digraph 43 | @param graph: Graph. 44 | 45 | @rtype: list 46 | @return: Topological sorting for the graph. 47 | """ 48 | # The topological sorting of a DAG is equivalent to its reverse postordering. 49 | order = depth_first_search(graph)[2] 50 | order.reverse() 51 | return order 52 | -------------------------------------------------------------------------------- /python-graph/tests/test_data.py: -------------------------------------------------------------------------------- 1 | """ 2 | Misc functions used for testing, including the generation of test-data. 3 | """ 4 | 5 | EDGES = [ 6 | ("China", "Russia"), 7 | ("Afghanistan", "Iran"), 8 | ("China", "Russia"), 9 | ("China", "Mongolia"), 10 | ("Mongolia", "Russia"), 11 | ("Mongolia", "China"), 12 | ("Nepal", "China"), 13 | ("India", "Pakistan"), 14 | ("India", "Nepal"), 15 | ("Afghanistan", "Pakistan"), 16 | ("North Korea", "China"), 17 | ("Romania", "Bulgaria"), 18 | ("Romania", "Moldova"), 19 | ("Romania", "Ukraine"), 20 | ("Romania", "Hungary"), 21 | ("North Korea", "South Korea"), 22 | ("Portugal", "Spain"), 23 | ("Spain","France"), 24 | ("France","Belgium"), 25 | ("France","Germany"), 26 | ("France","Italy",), 27 | ("Belgium","Netherlands"), 28 | ("Germany","Belgium"), 29 | ("Germany","Netherlands"), 30 | ("Germany","Denmark"), 31 | ("Germany","Luxembourg"), 32 | ("Germany","Czech Republic"), 33 | ("Belgium","Luxembourg"), 34 | ("France","Luxembourg"), 35 | ("England","Wales"), 36 | ("England","Scotland"), 37 | ("England","France"), 38 | ("Scotland","Wales"), 39 | ("Scotland","Ireland"), 40 | ("England","Ireland"), 41 | ("Switzerland","Austria"), 42 | ("Switzerland","Germany"), 43 | ("Switzerland","France"), 44 | ("Switzerland","Italy"), 45 | ("Austria","Germany"), 46 | ("Austria","Italy"), 47 | ("Austria","Czech Republic"), 48 | ("Austria","Slovakia"), 49 | ("Austria","Hungary"), 50 | ("Austria","Slovenia"), 51 | ("Denmark","Germany"), 52 | ("Poland","Czech Republic"), 53 | ("Poland","Slovakia"), 54 | ("Poland","Germany"), 55 | ("Poland","Russia"), 56 | ("Poland","Ukraine"), 57 | ("Poland","Belarus"), 58 | ("Poland","Lithuania"), 59 | ("Czech Republic","Slovakia"), 60 | ("Czech Republic","Germany"), 61 | ("Slovakia","Hungary")] 62 | 63 | 64 | def nations_of_the_world( G ): 65 | """ 66 | This is intended to simplify the unit-tests. Given a graph add the nations of the world to it. 67 | """ 68 | for a,b in EDGES: 69 | 70 | for n in [a,b,]: 71 | if not n in G.nodes(): 72 | G.add_node(n) 73 | 74 | if (not G.has_edge((a,b))): 75 | G.add_edge( (a,b) ) 76 | 77 | return G 78 | 79 | 80 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/filters/null.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Null searching filter. 27 | """ 28 | 29 | 30 | class null(object): 31 | """ 32 | Null search filter. 33 | """ 34 | 35 | def __init__(self): 36 | """ 37 | Initialize the filter. 38 | """ 39 | self.graph = None 40 | self.spanning_tree = None 41 | 42 | def configure(self, graph, spanning_tree): 43 | """ 44 | Configure the filter. 45 | 46 | @type graph: graph 47 | @param graph: Graph. 48 | 49 | @type spanning_tree: dictionary 50 | @param spanning_tree: Spanning tree. 51 | """ 52 | self.graph = graph 53 | self.spanning_tree = spanning_tree 54 | 55 | def __call__(self, node, parent): 56 | """ 57 | Decide if the given node should be included in the search process. 58 | 59 | @type node: node 60 | @param node: Given node. 61 | 62 | @type parent: node 63 | @param parent: Given node's parent in the spanning tree. 64 | 65 | @rtype: boolean 66 | @return: Whether the given node should be included in the search process. 67 | """ 68 | return True -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/filters/null.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Null searching filter. 27 | """ 28 | 29 | 30 | class null(object): 31 | """ 32 | Null search filter. 33 | """ 34 | 35 | def __init__(self): 36 | """ 37 | Initialize the filter. 38 | """ 39 | self.graph = None 40 | self.spanning_tree = None 41 | 42 | def configure(self, graph, spanning_tree): 43 | """ 44 | Configure the filter. 45 | 46 | @type graph: graph 47 | @param graph: Graph. 48 | 49 | @type spanning_tree: dictionary 50 | @param spanning_tree: Spanning tree. 51 | """ 52 | self.graph = graph 53 | self.spanning_tree = spanning_tree 54 | 55 | def __call__(self, node, parent): 56 | """ 57 | Decide if the given node should be included in the search process. 58 | 59 | @type node: node 60 | @param node: Given node. 61 | 62 | @type parent: node 63 | @param parent: Given node's parent in the spanning tree. 64 | 65 | @rtype: boolean 66 | @return: Whether the given node should be included in the search process. 67 | """ 68 | return True -------------------------------------------------------------------------------- /python-graph/core/pygraph/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007-2012 Pedro Matiello 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 | """ 26 | B{python-graph} 27 | 28 | A library for working with graphs in Python. 29 | 30 | @version: 1.8.2 31 | 32 | L{Data structure} classes are located at C{pygraph.classes}. 33 | 34 | L{Exception} classes are located at C{pygraph.classes.exceptions}. 35 | 36 | L{Search filters} are located at C{pygraph.algorithms.filters}. 37 | 38 | L{Heuristics} for the A* algorithm are exposed in 39 | C{pygraph.algorithms.heuristics}. 40 | 41 | A quick introductory example: 42 | 43 | >>> # Import the module and instantiate a graph object 44 | >>> from pygraph.classes.graph import graph 45 | >>> from pygraph.algorithms.searching import depth_first_search 46 | >>> gr = graph() 47 | >>> # Add nodes 48 | >>> gr.add_nodes(['X','Y','Z']) 49 | >>> gr.add_nodes(['A','B','C']) 50 | >>> # Add edges 51 | >>> gr.add_edge(('X','Y')) 52 | >>> gr.add_edge(('X','Z')) 53 | >>> gr.add_edge(('A','B')) 54 | >>> gr.add_edge(('A','C')) 55 | >>> gr.add_edge(('Y','B')) 56 | >>> # Depth first search rooted on node X 57 | >>> st, pre, post = depth_first_search(gr, root='X') 58 | >>> # Print the spanning tree 59 | >>> print st 60 | {'A': 'B', 'C': 'A', 'B': 'Y', 'Y': 'X', 'X': None, 'Z': 'X'} 61 | """ 62 | 63 | __import__('pkg_resources').declare_namespace(__name__) 64 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007-2012 Pedro Matiello 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 | """ 26 | B{python-graph} 27 | 28 | A library for working with graphs in Python. 29 | 30 | @version: 1.8.2 31 | 32 | L{Data structure} classes are located at C{pygraph.classes}. 33 | 34 | L{Exception} classes are located at C{pygraph.classes.exceptions}. 35 | 36 | L{Search filters} are located at C{pygraph.algorithms.filters}. 37 | 38 | L{Heuristics} for the A* algorithm are exposed in 39 | C{pygraph.algorithms.heuristics}. 40 | 41 | A quick introductory example: 42 | 43 | >>> # Import the module and instantiate a graph object 44 | >>> from pygraph.classes.graph import graph 45 | >>> from pygraph.algorithms.searching import depth_first_search 46 | >>> gr = graph() 47 | >>> # Add nodes 48 | >>> gr.add_nodes(['X','Y','Z']) 49 | >>> gr.add_nodes(['A','B','C']) 50 | >>> # Add edges 51 | >>> gr.add_edge(('X','Y')) 52 | >>> gr.add_edge(('X','Z')) 53 | >>> gr.add_edge(('A','B')) 54 | >>> gr.add_edge(('A','C')) 55 | >>> gr.add_edge(('Y','B')) 56 | >>> # Depth first search rooted on node X 57 | >>> st, pre, post = depth_first_search(gr, root='X') 58 | >>> # Print the spanning tree 59 | >>> print st 60 | {'A': 'B', 'C': 'A', 'B': 'Y', 'Y': 'X', 'X': None, 'Z': 'X'} 61 | """ 62 | 63 | __import__('pkg_resources').declare_namespace(__name__) 64 | -------------------------------------------------------------------------------- /python-graph/tests/testlib.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007-2009 Pedro Matiello 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 | """ 26 | Helper functions for unit-tests. 27 | """ 28 | 29 | 30 | # Imports 31 | from pygraph.algorithms.generators import generate, generate_hypergraph 32 | from random import seed 33 | from time import time 34 | from sys import argv 35 | 36 | # Configuration 37 | random_seed = int(time()) 38 | num_nodes = { 'small': 10, 39 | 'medium': 25, 40 | 'sparse': 40 41 | } 42 | num_edges = { 'small': 18, 43 | 'medium': 120, 44 | 'sparse': 200 45 | } 46 | sizes = ['small', 'medium', 'sparse'] 47 | use_size = 'medium' 48 | 49 | # Init 50 | try: 51 | if (argv[0] != 'testrunner.py'): 52 | print 53 | print ("Random seed: %s" % random_seed) 54 | except: 55 | pass 56 | 57 | 58 | def new_graph(wt_range=(1, 1)): 59 | seed(random_seed) 60 | return generate(num_nodes[use_size], num_edges[use_size], directed=False, weight_range=wt_range) 61 | 62 | def new_digraph(wt_range=(1, 1)): 63 | seed(random_seed) 64 | return generate(num_nodes[use_size], num_edges[use_size], directed=True, weight_range=wt_range) 65 | 66 | def new_hypergraph(): 67 | seed(random_seed) 68 | return generate_hypergraph(num_nodes[use_size], num_edges[use_size]) 69 | 70 | def new_uniform_hypergraph(_r): 71 | seed(random_seed) 72 | return generate_hypergraph(num_nodes[use_size], num_edges[use_size], r = _r) 73 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/classes/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Exceptions. 28 | """ 29 | 30 | # Graph errors 31 | 32 | class GraphError(RuntimeError): 33 | """ 34 | A base-class for the various kinds of errors that occur in the the python-graph class. 35 | """ 36 | pass 37 | 38 | class AdditionError(GraphError): 39 | """ 40 | This error is raised when trying to add a node or edge already added to the graph or digraph. 41 | """ 42 | pass 43 | 44 | class NodeUnreachable(GraphError): 45 | """ 46 | Goal could not be reached from start. 47 | """ 48 | def __init__(self, start, goal): 49 | msg = "Node %s could not be reached from node %s" % ( repr(goal), repr(start) ) 50 | InvalidGraphType.__init__(self, msg) 51 | self.start = start 52 | self.goal = goal 53 | 54 | class InvalidGraphType(GraphError): 55 | """ 56 | Invalid graph type. 57 | """ 58 | pass 59 | 60 | # Algorithm errors 61 | 62 | class AlgorithmError(RuntimeError): 63 | """ 64 | A base-class for the various kinds of errors that occur in the the 65 | algorithms package. 66 | """ 67 | pass 68 | 69 | class NegativeWeightCycleError(AlgorithmError): 70 | """ 71 | Algorithms like the Bellman-Ford algorithm can detect and raise an exception 72 | when they encounter a negative weight cycle. 73 | 74 | @see: pygraph.algorithms.shortest_path_bellman_ford 75 | """ 76 | pass 77 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/classes/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Exceptions. 28 | """ 29 | 30 | # Graph errors 31 | 32 | class GraphError(RuntimeError): 33 | """ 34 | A base-class for the various kinds of errors that occur in the the python-graph class. 35 | """ 36 | pass 37 | 38 | class AdditionError(GraphError): 39 | """ 40 | This error is raised when trying to add a node or edge already added to the graph or digraph. 41 | """ 42 | pass 43 | 44 | class NodeUnreachable(GraphError): 45 | """ 46 | Goal could not be reached from start. 47 | """ 48 | def __init__(self, start, goal): 49 | msg = "Node %s could not be reached from node %s" % ( repr(goal), repr(start) ) 50 | InvalidGraphType.__init__(self, msg) 51 | self.start = start 52 | self.goal = goal 53 | 54 | class InvalidGraphType(GraphError): 55 | """ 56 | Invalid graph type. 57 | """ 58 | pass 59 | 60 | # Algorithm errors 61 | 62 | class AlgorithmError(RuntimeError): 63 | """ 64 | A base-class for the various kinds of errors that occur in the the 65 | algorithms package. 66 | """ 67 | pass 68 | 69 | class NegativeWeightCycleError(AlgorithmError): 70 | """ 71 | Algorithms like the Bellman-Ford algorithm can detect and raise an exception 72 | when they encounter a negative weight cycle. 73 | 74 | @see: pygraph.algorithms.shortest_path_bellman_ford 75 | """ 76 | pass 77 | -------------------------------------------------------------------------------- /python-graph/tests/testrunner.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | import sys 26 | sys.path.append('..') 27 | import pygraph 28 | import unittest 29 | import testlib 30 | import logging 31 | from os import listdir 32 | 33 | log = logging.getLogger(__name__) 34 | 35 | def test_modules(): 36 | modlist = [] 37 | for each in listdir('.'): 38 | if (each[0:9] == "unittests" and each[-3:] == ".py"): 39 | modlist.append(each[0:-3]) 40 | return modlist 41 | 42 | def run_tests(): 43 | for each_size in testlib.sizes: 44 | print ("Testing with %s graphs" % each_size) 45 | 46 | suite = unittest.TestSuite() 47 | testlib.use_size = each_size 48 | 49 | for each_module in test_modules(): 50 | try: 51 | suite.addTests(unittest.TestLoader().loadTestsFromName(each_module)) 52 | except ImportError as ie: 53 | log.exception(ie) 54 | continue 55 | 56 | tr = unittest.TextTestRunner(verbosity=2) 57 | result = tr.run(suite) 58 | del suite 59 | 60 | def main(): 61 | try: 62 | rseed = sys.argv[1] 63 | testlib.random_seed = int(rseed) 64 | except: 65 | pass 66 | print ("") 67 | print ("--------------------------------------------------") 68 | print ("python-graph unit-tests") 69 | print ("Random seed: %s" % testlib.random_seed) 70 | print ("--------------------------------------------------") 71 | print ("") 72 | run_tests() 73 | 74 | if __name__ == "__main__": 75 | main() 76 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/filters/find.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Search filter for finding a specific node. 27 | """ 28 | 29 | 30 | class find(object): 31 | """ 32 | Search filter for finding a specific node. 33 | """ 34 | 35 | def __init__(self, target): 36 | """ 37 | Initialize the filter. 38 | 39 | @type target: node 40 | @param target: Target node. 41 | """ 42 | self.graph = None 43 | self.spanning_tree = None 44 | self.target = target 45 | self.done = False 46 | 47 | def configure(self, graph, spanning_tree): 48 | """ 49 | Configure the filter. 50 | 51 | @type graph: graph 52 | @param graph: Graph. 53 | 54 | @type spanning_tree: dictionary 55 | @param spanning_tree: Spanning tree. 56 | """ 57 | self.graph = graph 58 | self.spanning_tree = spanning_tree 59 | 60 | def __call__(self, node, parent): 61 | """ 62 | Decide if the given node should be included in the search process. 63 | 64 | @type node: node 65 | @param node: Given node. 66 | 67 | @type parent: node 68 | @param parent: Given node's parent in the spanning tree. 69 | 70 | @rtype: boolean 71 | @return: Whether the given node should be included in the search process. 72 | """ 73 | if (not self.done): 74 | if (node == self.target): 75 | self.done = True 76 | return True 77 | else: 78 | return False -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/traversal.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Traversal algorithms. 27 | 28 | @sort: traversal 29 | """ 30 | 31 | 32 | # Minimal spanning tree 33 | 34 | def traversal(graph, node, order): 35 | """ 36 | Graph traversal iterator. 37 | 38 | @type graph: graph, digraph 39 | @param graph: Graph. 40 | 41 | @type node: node 42 | @param node: Node. 43 | 44 | @type order: string 45 | @param order: traversal ordering. Possible values are: 46 | 2. 'pre' - Preordering (default) 47 | 1. 'post' - Postordering 48 | 49 | @rtype: iterator 50 | @return: Traversal iterator. 51 | """ 52 | visited = {} 53 | if (order == 'pre'): 54 | pre = 1 55 | post = 0 56 | elif (order == 'post'): 57 | pre = 0 58 | post = 1 59 | 60 | for each in _dfs(graph, visited, node, pre, post): 61 | yield each 62 | 63 | 64 | def _dfs(graph, visited, node, pre, post): 65 | """ 66 | Depth-first search subfunction for traversals. 67 | 68 | @type graph: graph, digraph 69 | @param graph: Graph. 70 | 71 | @type visited: dictionary 72 | @param visited: List of nodes (visited nodes are marked non-zero). 73 | 74 | @type node: node 75 | @param node: Node to be explored by DFS. 76 | """ 77 | visited[node] = 1 78 | if (pre): yield node 79 | # Explore recursively the connected component 80 | for each in graph[node]: 81 | if (each not in visited): 82 | for other in _dfs(graph, visited, each, pre, post): 83 | yield other 84 | if (post): yield node 85 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/filters/find.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Search filter for finding a specific node. 27 | """ 28 | 29 | 30 | class find(object): 31 | """ 32 | Search filter for finding a specific node. 33 | """ 34 | 35 | def __init__(self, target): 36 | """ 37 | Initialize the filter. 38 | 39 | @type target: node 40 | @param target: Target node. 41 | """ 42 | self.graph = None 43 | self.spanning_tree = None 44 | self.target = target 45 | self.done = False 46 | 47 | def configure(self, graph, spanning_tree): 48 | """ 49 | Configure the filter. 50 | 51 | @type graph: graph 52 | @param graph: Graph. 53 | 54 | @type spanning_tree: dictionary 55 | @param spanning_tree: Spanning tree. 56 | """ 57 | self.graph = graph 58 | self.spanning_tree = spanning_tree 59 | 60 | def __call__(self, node, parent): 61 | """ 62 | Decide if the given node should be included in the search process. 63 | 64 | @type node: node 65 | @param node: Given node. 66 | 67 | @type parent: node 68 | @param parent: Given node's parent in the spanning tree. 69 | 70 | @rtype: boolean 71 | @return: Whether the given node should be included in the search process. 72 | """ 73 | if (not self.done): 74 | if (node == self.target): 75 | self.done = True 76 | return True 77 | else: 78 | return False -------------------------------------------------------------------------------- /python-graph/Makefile: -------------------------------------------------------------------------------- 1 | # python-graph 2 | # Makefile 3 | 4 | 5 | # Module directories ------------------------------------------------- 6 | 7 | CORE_DIR="core/" 8 | DOT_DIR="dot/" 9 | TESTS_DIR="tests/" 10 | DOCS_DIR="docs/" 11 | TEMP="temp/" 12 | PYTHONPATH="`pwd`/core:`pwd`/dot" 13 | 14 | 15 | # General ------------------------------------------------------------ 16 | 17 | nothing: 18 | 19 | sdist: clean sdist-core sdist-dot 20 | rm -rf dist 21 | mkdir dist 22 | cp */dist/* dist 23 | 24 | 25 | # Core --------------------------------------------------------------- 26 | 27 | install-core: 28 | cd ${CORE_DIR} && ./setup.py install 29 | 30 | sdist-core: clean 31 | cd ${CORE_DIR} && ./setup.py sdist 32 | 33 | 34 | # Dot ---------------------------------------------------------------- 35 | 36 | install-dot: 37 | cd ${DOT_DIR} && ./setup.py install 38 | 39 | sdist-dot: clean 40 | cd ${DOT_DIR} && ./setup.py sdist 41 | 42 | 43 | # Docs --------------------------------------------------------------- 44 | 45 | docs: cleanpyc 46 | rm -rf ${DOCS_DIR} ${TEMP} 47 | mkdir -p ${TEMP} 48 | cp -R ${CORE_DIR}/pygraph ${TEMP} 49 | cp -Rn ${DOT_DIR}/pygraph ${TEMP}/pygraph/ 50 | epydoc -v --no-frames --no-sourcecode --name="python-graph" \ 51 | --url="http://code.google.com/p/python-graph/" \ 52 | --inheritance listed --no-private --html \ 53 | --graph classtree \ 54 | --css misc/epydoc.css -o docs ${TEMP}/pygraph/*.py \ 55 | ${TEMP}/pygraph/algorithms/*py \ 56 | ${TEMP}/pygraph/algorithms/heuristics/*.py \ 57 | ${TEMP}/pygraph/algorithms/filters/* \ 58 | ${TEMP}/pygraph/readwrite/* \ 59 | ${TEMP}/pygraph/classes/*.py \ 60 | ${TEMP}/pygraph/mixins/*.py 61 | rm -rf ${TEMP} 62 | 63 | 64 | # Tests -------------------------------------------------------------- 65 | 66 | test-pre: 67 | reset 68 | 69 | test: test-pre 70 | export PYTHONPATH=${PYTHONPATH} && cd ${TESTS_DIR} && python testrunner.py 71 | 72 | test3: test-pre 73 | export PYTHONPATH=${PYTHONPATH} && cd ${TESTS_DIR} && python3 testrunner.py 74 | 75 | tests: test 76 | 77 | 78 | # Tests -------------------------------------------------------------- 79 | 80 | console: 81 | export PYTHONPATH=${PYTHONPATH} && cd ${TESTS_DIR} && python 82 | 83 | console3: 84 | export PYTHONPATH=${PYTHONPATH} && cd ${TESTS_DIR} && python3 85 | 86 | 87 | # Cleaning ----------------------------------------------------------- 88 | 89 | cleanpyc: 90 | find . -name *.pyc -exec rm {} \; 91 | find . -name __pycache__ -exec rm -rf {} \; 92 | 93 | clean: cleanpyc 94 | rm -rf ${DOCS_DIR} 95 | rm -rf */dist 96 | rm -rf */build 97 | rm -rf */*.egg-info 98 | rm -rf dist 99 | 100 | 101 | # Phony rules -------------------------------------------------------- 102 | 103 | .PHONY: clean cleanpyc docs-core 104 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/traversal.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Traversal algorithms. 27 | 28 | @sort: traversal 29 | """ 30 | 31 | 32 | # Minimal spanning tree 33 | 34 | def traversal(graph, node, order): 35 | """ 36 | Graph traversal iterator. 37 | 38 | @type graph: graph, digraph 39 | @param graph: Graph. 40 | 41 | @type node: node 42 | @param node: Node. 43 | 44 | @type order: string 45 | @param order: traversal ordering. Possible values are: 46 | 2. 'pre' - Preordering (default) 47 | 1. 'post' - Postordering 48 | 49 | @rtype: iterator 50 | @return: Traversal iterator. 51 | """ 52 | visited = {} 53 | if (order == 'pre'): 54 | pre = 1 55 | post = 0 56 | elif (order == 'post'): 57 | pre = 0 58 | post = 1 59 | 60 | for each in _dfs(graph, visited, node, pre, post): 61 | yield each 62 | 63 | 64 | def _dfs(graph, visited, node, pre, post): 65 | """ 66 | Depth-first search subfunction for traversals. 67 | 68 | @type graph: graph, digraph 69 | @param graph: Graph. 70 | 71 | @type visited: dictionary 72 | @param visited: List of nodes (visited nodes are marked non-zero). 73 | 74 | @type node: node 75 | @param node: Node to be explored by DFS. 76 | """ 77 | visited[node] = 1 78 | if (pre): yield node 79 | # Explore recursively the connected component 80 | for each in graph[node]: 81 | if (each not in visited): 82 | for other in _dfs(graph, visited, each, pre, post): 83 | yield other 84 | if (post): yield node 85 | -------------------------------------------------------------------------------- /src/ismalware.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import xml.etree.ElementTree as et 3 | from pygraph.classes.digraph import digraph 4 | from pygraph.readwrite.dot import * 5 | from mcs import * 6 | from mincs import * 7 | from wcbg import * 8 | 9 | # Delta function which ckecks the similarity between wcbg and guest malware kobg 10 | def similarity (wcbg, gnew): 11 | wcbg_edges = wcbg.edges () 12 | gnew_edges = gnew.edges () 13 | 14 | sum = 0 15 | for e1 in wcbg_edges: 16 | for e2 in gnew_edges: 17 | w_node1, w_node2 = e1 18 | g_node1, g_node2 = e2 19 | w_node1_attr = wcbg.node_attributes (w_node1) 20 | w_node2_attr = wcbg.node_attributes (w_node2) 21 | w_node1_label = w_node1_attr [0][1] 22 | w_node2_label = w_node2_attr [0][1] 23 | g_node1_attr = gnew.node_attributes (g_node1) 24 | g_node2_attr = gnew.node_attributes (g_node2) 25 | g_node1_label = g_node1_attr [0][1] 26 | g_node2_label = g_node2_attr [0][1] 27 | if g_node1_label == w_node1_label and g_node2_label == w_node2_label: 28 | sum = sum + gnew.edge_weight (e2) 29 | break 30 | 31 | sum = float (sum) 32 | n = min (len (gnew), len (wcbg)) 33 | if n > 0: 34 | return sum/n 35 | else: 36 | return -1 37 | 38 | # Checks if a graph is the subset of other graph 39 | def issubset (hotpath, malware_kobg): 40 | mcs = mcsinit (hotpath, malware_kobg) 41 | if len (mcs.nodes ()) == len (hotpath.nodes ()) and len (mcs.edges ()) == len (hotpath.edges ()): 42 | return True 43 | else: 44 | return False 45 | 46 | # Final check if malware is of the same family 47 | def isMalware (wcbg, hotpath, malware_kobg, gamma): 48 | similarity_index = similarity (wcbg, malware_kobg) 49 | issubset (hotpath, malware_kobg) 50 | if similarity_index > gamma and issubset (hotpath, malware_kobg): 51 | return True 52 | else: 53 | return False 54 | 55 | # Initializes operations on guest malware` 56 | def init_check (hotpath, wcbg, family): 57 | global nodeid 58 | nodeid = 1 59 | malware = sys.argv [3] 60 | malware_kobg = makeMalGraph (malware) 61 | malware = malware.split ('.')[0] 62 | generate_graph_image (malware_kobg, malware) 63 | decision = isMalware (wcbg, hotpath, malware_kobg, GAMMA) 64 | if decision: 65 | print malware + ' is a Malware of the family ' + family 66 | else: 67 | print malware + ' is not a Malware of the family ' + family 68 | 69 | # Init function 70 | if __name__ == '__main__': 71 | wcbg_file = sys.argv [1] 72 | if os.path.isfile (wcbg_file): 73 | pass 74 | else: 75 | raise IOError ('File does not exists') 76 | 77 | f_wcbg = open (wcbg_file, 'r') 78 | dot_wcbg = f_wcbg.read () 79 | f_wcbg.close () 80 | wcbg = read (dot_wcbg) 81 | # print wcbg 82 | hotpath_file = sys.argv [2] 83 | if os.path.isfile (hotpath_file): 84 | pass 85 | else: 86 | raise IOError ('File does not exists') 87 | 88 | f_hotpath = open (hotpath_file, 'r') 89 | dot_hotpath = f_hotpath.read () 90 | f_hotpath.close () 91 | hotpath = read (dot_hotpath) 92 | family = wcbg_file.split ('.')[0] 93 | init_check (hotpath, wcbg, family) 94 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/pagerank.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Pedro Matiello 2 | # Juarez Bochi 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | PageRank algoritm 28 | 29 | @sort: pagerank 30 | """ 31 | 32 | def pagerank(graph, damping_factor=0.85, max_iterations=100, min_delta=0.00001): 33 | """ 34 | Compute and return the PageRank in an directed graph. 35 | 36 | @type graph: digraph 37 | @param graph: Digraph. 38 | 39 | @type damping_factor: number 40 | @param damping_factor: PageRank dumping factor. 41 | 42 | @type max_iterations: number 43 | @param max_iterations: Maximum number of iterations. 44 | 45 | @type min_delta: number 46 | @param min_delta: Smallest variation required to have a new iteration. 47 | 48 | @rtype: Dict 49 | @return: Dict containing all the nodes PageRank. 50 | """ 51 | 52 | nodes = graph.nodes() 53 | graph_size = len(nodes) 54 | if graph_size == 0: 55 | return {} 56 | min_value = (1.0-damping_factor)/graph_size #value for nodes without inbound links 57 | 58 | # itialize the page rank dict with 1/N for all nodes 59 | pagerank = dict.fromkeys(nodes, 1.0/graph_size) 60 | 61 | for i in range(max_iterations): 62 | diff = 0 #total difference compared to last iteraction 63 | # computes each node PageRank based on inbound links 64 | for node in nodes: 65 | rank = min_value 66 | for referring_page in graph.incidents(node): 67 | rank += damping_factor * pagerank[referring_page] / len(graph.neighbors(referring_page)) 68 | 69 | diff += abs(pagerank[node] - rank) 70 | pagerank[node] = rank 71 | 72 | #stop if PageRank has converged 73 | if diff < min_delta: 74 | break 75 | 76 | return pagerank 77 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/pagerank.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Pedro Matiello 2 | # Juarez Bochi 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | PageRank algoritm 28 | 29 | @sort: pagerank 30 | """ 31 | 32 | def pagerank(graph, damping_factor=0.85, max_iterations=100, min_delta=0.00001): 33 | """ 34 | Compute and return the PageRank in an directed graph. 35 | 36 | @type graph: digraph 37 | @param graph: Digraph. 38 | 39 | @type damping_factor: number 40 | @param damping_factor: PageRank dumping factor. 41 | 42 | @type max_iterations: number 43 | @param max_iterations: Maximum number of iterations. 44 | 45 | @type min_delta: number 46 | @param min_delta: Smallest variation required to have a new iteration. 47 | 48 | @rtype: Dict 49 | @return: Dict containing all the nodes PageRank. 50 | """ 51 | 52 | nodes = graph.nodes() 53 | graph_size = len(nodes) 54 | if graph_size == 0: 55 | return {} 56 | min_value = (1.0-damping_factor)/graph_size #value for nodes without inbound links 57 | 58 | # itialize the page rank dict with 1/N for all nodes 59 | pagerank = dict.fromkeys(nodes, 1.0/graph_size) 60 | 61 | for i in range(max_iterations): 62 | diff = 0 #total difference compared to last iteraction 63 | # computes each node PageRank based on inbound links 64 | for node in nodes: 65 | rank = min_value 66 | for referring_page in graph.incidents(node): 67 | rank += damping_factor * pagerank[referring_page] / len(graph.neighbors(referring_page)) 68 | 69 | diff += abs(pagerank[node] - rank) 70 | pagerank[node] = rank 71 | 72 | #stop if PageRank has converged 73 | if diff < min_delta: 74 | break 75 | 76 | return pagerank 77 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/heuristics/chow.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Edmond Chow's heuristic for A*. 28 | """ 29 | 30 | 31 | # Imports 32 | from pygraph.algorithms.minmax import shortest_path 33 | 34 | 35 | class chow(object): 36 | """ 37 | An implementation of the graph searching heuristic proposed by Edmond Chow. 38 | 39 | Remember to call the C{optimize()} method before the heuristic search. 40 | 41 | For details, check: U{http://www.edmondchow.com/pubs/levdiff-aaai.pdf}. 42 | """ 43 | 44 | def __init__(self, *centers): 45 | """ 46 | Initialize a Chow heuristic object. 47 | """ 48 | self.centers = centers 49 | self.nodes = {} 50 | 51 | def optimize(self, graph): 52 | """ 53 | Build a dictionary mapping each pair of nodes to a number (the distance between them). 54 | 55 | @type graph: graph 56 | @param graph: Graph. 57 | """ 58 | for center in self.centers: 59 | shortest_routes = shortest_path(graph, center)[1] 60 | for node, weight in list(shortest_routes.items()): 61 | self.nodes.setdefault(node, []).append(weight) 62 | 63 | def __call__(self, start, end): 64 | """ 65 | Estimate how far start is from end. 66 | 67 | @type start: node 68 | @param start: Start node. 69 | 70 | @type end: node 71 | @param end: End node. 72 | """ 73 | assert len( list(self.nodes.keys()) ) > 0, "You need to optimize this heuristic for your graph before it can be used to estimate." 74 | 75 | cmp_sequence = list(zip( self.nodes[start], self.nodes[end] )) 76 | chow_number = max( abs( a-b ) for a,b in cmp_sequence ) 77 | return chow_number 78 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Roy Smith 3 | # Salim Fadhley 4 | # 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, 9 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following 12 | # conditions: 13 | 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | # OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | 27 | """ 28 | Miscellaneous useful stuff. 29 | """ 30 | 31 | # Imports 32 | from heapq import heappush, heappop, heapify 33 | 34 | 35 | # Priority Queue 36 | class priority_queue: 37 | """ 38 | Priority queue. 39 | """ 40 | 41 | def __init__(self, list=[]): 42 | self.heap = [HeapItem(i, 0) for i in list] 43 | heapify(self.heap) 44 | 45 | def __contains__(self, item): 46 | for heap_item in self.heap: 47 | if item == heap_item.item: 48 | return True 49 | return False 50 | 51 | def __len__(self): 52 | return len(self.heap) 53 | 54 | def empty(self): 55 | return len(self.heap) == 0 56 | 57 | def insert(self, item, priority): 58 | """ 59 | Insert item into the queue, with the given priority. 60 | """ 61 | heappush(self.heap, HeapItem(item, priority)) 62 | 63 | def pop(self): 64 | """ 65 | Return the item with the lowest priority, and remove it from the queue. 66 | """ 67 | return heappop(self.heap).item 68 | 69 | def peek(self): 70 | """ 71 | Return the item with the lowest priority. The queue is unchanged. 72 | """ 73 | return self.heap[0].item 74 | 75 | def discard(self, item): 76 | new_heap = [] 77 | for heap_item in self.heap: 78 | if item != heap_item.item: 79 | new_heap.append(heap_item) 80 | self.heap = new_heap 81 | heapify(self.heap) 82 | 83 | class HeapItem: 84 | def __init__(self, item, priority): 85 | self.item = item 86 | self.priority = priority 87 | 88 | def __cmp__(self, other): 89 | return cmp(self.priority, other.priority) 90 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/heuristics/chow.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Salim Fadhley 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Edmond Chow's heuristic for A*. 28 | """ 29 | 30 | 31 | # Imports 32 | from pygraph.algorithms.minmax import shortest_path 33 | 34 | 35 | class chow(object): 36 | """ 37 | An implementation of the graph searching heuristic proposed by Edmond Chow. 38 | 39 | Remember to call the C{optimize()} method before the heuristic search. 40 | 41 | For details, check: U{http://www.edmondchow.com/pubs/levdiff-aaai.pdf}. 42 | """ 43 | 44 | def __init__(self, *centers): 45 | """ 46 | Initialize a Chow heuristic object. 47 | """ 48 | self.centers = centers 49 | self.nodes = {} 50 | 51 | def optimize(self, graph): 52 | """ 53 | Build a dictionary mapping each pair of nodes to a number (the distance between them). 54 | 55 | @type graph: graph 56 | @param graph: Graph. 57 | """ 58 | for center in self.centers: 59 | shortest_routes = shortest_path(graph, center)[1] 60 | for node, weight in list(shortest_routes.items()): 61 | self.nodes.setdefault(node, []).append(weight) 62 | 63 | def __call__(self, start, end): 64 | """ 65 | Estimate how far start is from end. 66 | 67 | @type start: node 68 | @param start: Start node. 69 | 70 | @type end: node 71 | @param end: End node. 72 | """ 73 | assert len( list(self.nodes.keys()) ) > 0, "You need to optimize this heuristic for your graph before it can be used to estimate." 74 | 75 | cmp_sequence = list(zip( self.nodes[start], self.nodes[end] )) 76 | chow_number = max( abs( a-b ) for a,b in cmp_sequence ) 77 | return chow_number 78 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Roy Smith 3 | # Salim Fadhley 4 | # 5 | # Permission is hereby granted, free of charge, to any person 6 | # obtaining a copy of this software and associated documentation 7 | # files (the "Software"), to deal in the Software without 8 | # restriction, including without limitation the rights to use, 9 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the 11 | # Software is furnished to do so, subject to the following 12 | # conditions: 13 | 14 | # The above copyright notice and this permission notice shall be 15 | # included in all copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | # OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | 27 | """ 28 | Miscellaneous useful stuff. 29 | """ 30 | 31 | # Imports 32 | from heapq import heappush, heappop, heapify 33 | 34 | 35 | # Priority Queue 36 | class priority_queue: 37 | """ 38 | Priority queue. 39 | """ 40 | 41 | def __init__(self, list=[]): 42 | self.heap = [HeapItem(i, 0) for i in list] 43 | heapify(self.heap) 44 | 45 | def __contains__(self, item): 46 | for heap_item in self.heap: 47 | if item == heap_item.item: 48 | return True 49 | return False 50 | 51 | def __len__(self): 52 | return len(self.heap) 53 | 54 | def empty(self): 55 | return len(self.heap) == 0 56 | 57 | def insert(self, item, priority): 58 | """ 59 | Insert item into the queue, with the given priority. 60 | """ 61 | heappush(self.heap, HeapItem(item, priority)) 62 | 63 | def pop(self): 64 | """ 65 | Return the item with the lowest priority, and remove it from the queue. 66 | """ 67 | return heappop(self.heap).item 68 | 69 | def peek(self): 70 | """ 71 | Return the item with the lowest priority. The queue is unchanged. 72 | """ 73 | return self.heap[0].item 74 | 75 | def discard(self, item): 76 | new_heap = [] 77 | for heap_item in self.heap: 78 | if item != heap_item.item: 79 | new_heap.append(heap_item) 80 | self.heap = new_heap 81 | heapify(self.heap) 82 | 83 | class HeapItem: 84 | def __init__(self, item, priority): 85 | self.item = item 86 | self.priority = priority 87 | 88 | def __cmp__(self, other): 89 | return cmp(self.priority, other.priority) 90 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/filters/radius.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Radial search filter. 27 | """ 28 | 29 | 30 | class radius(object): 31 | """ 32 | Radial search filter. 33 | 34 | This will keep searching contained inside a specified limit. 35 | """ 36 | 37 | def __init__(self, radius): 38 | """ 39 | Initialize the filter. 40 | 41 | @type radius: number 42 | @param radius: Search radius. 43 | """ 44 | self.graph = None 45 | self.spanning_tree = None 46 | self.radius = radius 47 | self.done = False 48 | 49 | def configure(self, graph, spanning_tree): 50 | """ 51 | Configure the filter. 52 | 53 | @type graph: graph 54 | @param graph: Graph. 55 | 56 | @type spanning_tree: dictionary 57 | @param spanning_tree: Spanning tree. 58 | """ 59 | self.graph = graph 60 | self.spanning_tree = spanning_tree 61 | 62 | def __call__(self, node, parent): 63 | """ 64 | Decide if the given node should be included in the search process. 65 | 66 | @type node: node 67 | @param node: Given node. 68 | 69 | @type parent: node 70 | @param parent: Given node's parent in the spanning tree. 71 | 72 | @rtype: boolean 73 | @return: Whether the given node should be included in the search process. 74 | """ 75 | 76 | def cost_to_root(node): 77 | if (node is not None): 78 | return cost_to_parent(node, st[node]) + cost_to_root(st[node]) 79 | else: 80 | return 0 81 | 82 | def cost_to_parent(node, parent): 83 | if (parent is not None): 84 | return gr.edge_weight((parent, node)) 85 | else: 86 | return 0 87 | 88 | gr = self.graph 89 | st = self.spanning_tree 90 | 91 | cost = cost_to_parent(node, parent) + cost_to_root(parent) 92 | 93 | if (cost <= self.radius): 94 | return True 95 | else: 96 | return False -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/filters/radius.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Radial search filter. 27 | """ 28 | 29 | 30 | class radius(object): 31 | """ 32 | Radial search filter. 33 | 34 | This will keep searching contained inside a specified limit. 35 | """ 36 | 37 | def __init__(self, radius): 38 | """ 39 | Initialize the filter. 40 | 41 | @type radius: number 42 | @param radius: Search radius. 43 | """ 44 | self.graph = None 45 | self.spanning_tree = None 46 | self.radius = radius 47 | self.done = False 48 | 49 | def configure(self, graph, spanning_tree): 50 | """ 51 | Configure the filter. 52 | 53 | @type graph: graph 54 | @param graph: Graph. 55 | 56 | @type spanning_tree: dictionary 57 | @param spanning_tree: Spanning tree. 58 | """ 59 | self.graph = graph 60 | self.spanning_tree = spanning_tree 61 | 62 | def __call__(self, node, parent): 63 | """ 64 | Decide if the given node should be included in the search process. 65 | 66 | @type node: node 67 | @param node: Given node. 68 | 69 | @type parent: node 70 | @param parent: Given node's parent in the spanning tree. 71 | 72 | @rtype: boolean 73 | @return: Whether the given node should be included in the search process. 74 | """ 75 | 76 | def cost_to_root(node): 77 | if (node is not None): 78 | return cost_to_parent(node, st[node]) + cost_to_root(st[node]) 79 | else: 80 | return 0 81 | 82 | def cost_to_parent(node, parent): 83 | if (parent is not None): 84 | return gr.edge_weight((parent, node)) 85 | else: 86 | return 0 87 | 88 | gr = self.graph 89 | st = self.spanning_tree 90 | 91 | cost = cost_to_parent(node, parent) + cost_to_root(parent) 92 | 93 | if (cost <= self.radius): 94 | return True 95 | else: 96 | return False -------------------------------------------------------------------------------- /python-graph/tests/unittests-critical.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pedro Matiello 2 | # Tomaz Kovacic 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Unittests for pygraph.algorithms.critical 28 | """ 29 | 30 | import unittest 31 | from pygraph.algorithms.critical import critical_path 32 | from pygraph.algorithms.critical import transitive_edges,_intersection 33 | from pygraph.classes.digraph import digraph 34 | 35 | def generate_test_graph(): 36 | ''' 37 | Generates & returns a weighted digraph with 38 | one transitive edge and no cycles. 39 | ''' 40 | G = digraph() 41 | G.add_nodes([1,2,3,4,5,6]) 42 | G.add_edge((1,2), 1) 43 | G.add_edge((2,4), 4) 44 | G.add_edge((1,3), 1)#transitive edge 45 | G.add_edge((2,3), 20) 46 | G.add_edge((3,5), 3) 47 | G.add_edge((4,6), 5) 48 | G.add_edge((5,6), 4) 49 | return G 50 | 51 | class test_critical_path_and_transitive_edges(unittest.TestCase): 52 | 53 | # critical path algorithm 54 | 55 | def test_critical_path_with_cycle(self): 56 | G = generate_test_graph() 57 | G.add_edge((5,2),3)#add cycle 58 | assert critical_path(G) == [] 59 | 60 | def test_critical_path(self): 61 | G = generate_test_graph() 62 | assert critical_path(G) == [1,2,3,5,6] 63 | 64 | # transitive edge detection algorithm 65 | 66 | def test_transitivity_with_cycle(self): 67 | G = generate_test_graph() 68 | G.add_edge((5,2),3)#add cycle 69 | assert transitive_edges(G) == [] 70 | 71 | def test_transitivity(self): 72 | G = generate_test_graph() 73 | G.add_edge((2,5),1)#add another transitive edge 74 | assert transitive_edges(G) == [(1,3),(2,5)] 75 | 76 | # intersection testing (used internally) 77 | 78 | def test_partial_intersection(self): 79 | list1 = [1,2,3,4] 80 | list2 = [3,4,5,6] 81 | assert _intersection(list1, list2) == [3,4] 82 | 83 | def test_empty_intersection(self): 84 | list1 = [1,2,3,4] 85 | list2 = [5,6] 86 | assert _intersection(list1, list2) == [] 87 | 88 | 89 | if __name__ == "__main__": 90 | unittest.main() -------------------------------------------------------------------------------- /python-graph/tests/unittests-sorting.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pedro Matiello 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 | """ 26 | Unittests for graph.algorithms.sorting 27 | """ 28 | 29 | 30 | import unittest 31 | import pygraph.classes 32 | from pygraph.algorithms.sorting import topological_sorting 33 | from pygraph.algorithms.searching import depth_first_search 34 | from sys import getrecursionlimit 35 | import testlib 36 | 37 | 38 | class test_topological_sorting(unittest.TestCase): 39 | 40 | def test_topological_sorting_on_tree(self): 41 | gr = testlib.new_graph() 42 | st, pre, post = depth_first_search(gr) 43 | tree = pygraph.classes.digraph.digraph() 44 | 45 | 46 | for each in st: 47 | if st[each]: 48 | if (each not in tree.nodes()): 49 | tree.add_node(each) 50 | if (st[each] not in tree.nodes()): 51 | tree.add_node(st[each]) 52 | tree.add_edge((st[each], each)) 53 | 54 | ts = topological_sorting(tree) 55 | for each in ts: 56 | if (st[each]): 57 | assert ts.index(each) > ts.index(st[each]) 58 | 59 | def test_topological_sorting_on_digraph(self): 60 | 61 | def is_ordered(node, list): 62 | # Has parent on list 63 | for each in list: 64 | if gr.has_edge((each, node)): 65 | return True 66 | # Has no possible ancestors on list 67 | st, pre, post = depth_first_search(gr, node) 68 | for each in list: 69 | if (each in st): 70 | return False 71 | return True 72 | 73 | gr = testlib.new_digraph() 74 | ts = topological_sorting(gr) 75 | 76 | while (ts): 77 | x = ts.pop() 78 | assert is_ordered(x, ts) 79 | 80 | def test_topological_sort_on_very_deep_graph(self): 81 | gr = pygraph.classes.graph.graph() 82 | gr.add_nodes(range(0,20001)) 83 | for i in range(0,20000): 84 | gr.add_edge((i,i+1)) 85 | recursionlimit = getrecursionlimit() 86 | topological_sorting(gr) 87 | assert getrecursionlimit() == recursionlimit 88 | 89 | if __name__ == "__main__": 90 | unittest.main() -------------------------------------------------------------------------------- /malwaresamples/Test/mal3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/malware1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/mincs.py: -------------------------------------------------------------------------------- 1 | from mcs import * 2 | 3 | # Checks if the edge is in g_subgraph 4 | def notin (edge, g_subgraph_edges, gid): 5 | for e in g_subgraph_edges: 6 | if (e[0][gid-1], e[1][gid-1]) == edge: 7 | return False 8 | return True 9 | 10 | # Returns embedding between a graph and its subgraph 11 | def embedding (subgraph, g, gid): 12 | g_subgraph_edges = subgraph.edges () 13 | g_edges = g.edges () 14 | E = [] 15 | for edge in g_edges: 16 | if notin(edge, g_subgraph_edges, gid): 17 | E.append (edge) 18 | return E 19 | 20 | # Returns diff of two graphs 21 | def diff (g, g_subgraph, gid): 22 | g_subgraph_nodes = g_subgraph.nodes () 23 | g_nodes = g.nodes () 24 | delnodes = [] 25 | for node in g_subgraph_nodes: 26 | if node[gid-1] in g_nodes: 27 | for node_adj in g.incidents (node[gid-1]): 28 | g.del_edge ((node_adj, node[gid-1])) 29 | if node_adj not in delnodes: 30 | delnodes.append (node_adj) 31 | if node[gid-1] not in delnodes: 32 | delnodes.append (node[gid-1]) 33 | for node in delnodes: 34 | g.del_node (node) 35 | return g 36 | 37 | # Get a node in second graph, given a node in the first graph, from the subgraph 38 | def getendpoint (node2, subgraph): 39 | subgraph_nodes = subgraph.nodes () 40 | 41 | for n1, n2 in subgraph_nodes: 42 | if n2 == node2: 43 | return n1 44 | 45 | return None 46 | 47 | # Returns the union of two graphs 48 | def union (g, g_diff, E, subgraph): 49 | g_diff_nodes = g_diff.nodes () 50 | for node in g_diff_nodes: 51 | g.add_node (node, g_diff.node_attributes (node)) 52 | 53 | for n1, n2 in E: 54 | if not (n1 in g_diff and n2 in g_diff): 55 | if n1 in g_diff: 56 | node1 = getendpoint (n2, subgraph) 57 | g.add_edge ((n1, node1)) 58 | elif n2 in g_diff: 59 | node2 = getendpoint (n1, subgraph) 60 | g.add_edge ((node2, n2)) 61 | return g 62 | 63 | # Sets appropriate weights of edges 64 | def setweight (graph, subgraph): 65 | subgraph_edges = subgraph.edges () 66 | for e1, e2 in subgraph_edges: 67 | wt = subgraph.edge_weight ((e1[0], e2[0])) 68 | graph.set_edge_weight ((e1[0], e2[0]), wt + 1) 69 | 70 | # Returns isolated nodes in a graph 71 | def getisolatednodes (graph): 72 | g_nodes = graph.nodes () 73 | nodelist = [] 74 | for e1, e2 in graph.edges (): 75 | if e1 not in nodelist: 76 | nodelist.append (e1) 77 | if e2 not in nodelist: 78 | nodelist.append (e2) 79 | isolatednodes = [] 80 | for node in g_nodes: 81 | if node not in nodelist: 82 | isolatednodes.append (node) 83 | 84 | return isolatednodes 85 | 86 | # Prunes the graph given a threshold 87 | def prunegraph (graph, theta): 88 | g_edges = graph.edges () 89 | for e1, e2 in g_edges: 90 | if graph.edge_weight ((e1, e2)) < theta: 91 | graph.del_edge ((e1, e2)) 92 | 93 | for node in getisolatednodes (graph): 94 | graph.del_node (node) 95 | 96 | return graph 97 | 98 | # Save a graph 99 | def save_graph (g): 100 | g_nodes = g.nodes () 101 | graph = digraph () 102 | 103 | for node in g_nodes: 104 | graph.add_node (node, g.node_attributes (node)) 105 | g_edges = g.edges () 106 | for edge in g_edges: 107 | graph.add_edge (edge) 108 | return graph 109 | 110 | # Return MinCS of two graphs 111 | def mincs (g1, g2): 112 | graph = save_graph (g1) 113 | subgraph = mcsinit (g1, g2) 114 | E1 = embedding (subgraph, g1, 1) 115 | E2 = embedding (subgraph, g2, 2) 116 | U1 = subgraph 117 | U2 = diff (g1, U1, 1) 118 | U3 = diff (g2, U1, 2) 119 | wmincs = union (graph, U3, E2, subgraph) 120 | return wmincs, subgraph 121 | -------------------------------------------------------------------------------- /malwaresamples/Test/mal4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /python-graph/README: -------------------------------------------------------------------------------- 1 | python-graph 2 | A library for working with graphs in Python 3 | -------------------------------------------------------------------------------- 4 | 5 | 6 | SUMMARY 7 | 8 | python-graph is a library for working with graphs in Python. 9 | 10 | This software provides a suitable data structure for representing graphs and a 11 | whole set of important algorithms. 12 | 13 | 14 | INSTALLING 15 | 16 | To install the core module, run: 17 | 18 | make install-core 19 | 20 | To install the dot language support, run: 21 | 22 | make install-dot 23 | 24 | Alternatively, if you don't have make, you can install the modules by running: 25 | 26 | ./setup.py install 27 | 28 | inside the module directory. 29 | 30 | 31 | DOCUMENTATION 32 | 33 | To generate the API documentation for this package, run: 34 | 35 | make docs 36 | 37 | You'll need epydoc installed in your system. 38 | 39 | 40 | WEBSITE 41 | 42 | The latest version of this package can be found at: 43 | 44 | http://code.google.com/p/python-graph/ 45 | 46 | Please report bugs at: 47 | 48 | http://code.google.com/p/python-graph/issues/list 49 | 50 | 51 | PROJECT COMMITTERS 52 | 53 | Pedro Matiello 54 | * Project maintainer/leader; 55 | * Graph, Digraph and Hipergraph classes; 56 | * Accessibility algorithms; 57 | * Cut-node and cut-edge detection; 58 | * Cycle detection; 59 | * Depth-first and Breadth-first searching; 60 | * Minimal Spanning Tree (Prim's algorithm); 61 | * Random graph generation; 62 | * Topological sorting; 63 | * Traversals; 64 | * XML reading/writing; 65 | * Refactoring. 66 | 67 | Christian Muise 68 | * Project commiter; 69 | * Dot file reading/writing; 70 | * Hypergraph class; 71 | * Refactoring. 72 | 73 | Salim Fadhley 74 | * Project commiter; 75 | * Porting of Roy Smith's A* implementation to python-graph; 76 | * Edmond Chow's heuristic for A*; 77 | * Refactoring. 78 | 79 | Tomaz Kovacic 80 | * Project commiter; 81 | * Transitive edge detection; 82 | * Critical path algorithm; 83 | * Bellman-Ford algorithm; 84 | * Logo design. 85 | 86 | 87 | CONTRIBUTORS 88 | 89 | Eugen Zagorodniy 90 | * Mutual Accessibility (Tarjan's Algorithm). 91 | 92 | Johannes Reinhardt 93 | * Maximum-flow algorithm; 94 | * Gomory-Hu cut-tree algorithm; 95 | * Refactoring. 96 | 97 | Juarez Bochi 98 | * Pagerank algorithm. 99 | 100 | Nathan Davis 101 | * Faster node insertion. 102 | 103 | Paul Harrison 104 | * Mutual Accessibility (Tarjan's Algorithm). 105 | 106 | Peter Sagerson 107 | * Performance improvements on shortest path algorithm. 108 | 109 | Rhys Ulerich 110 | * Dijkstra's Shortest path algorithm. 111 | 112 | Roy Smith 113 | * Heuristic Searching (A* algorithm). 114 | 115 | Zsolt Haraszti 116 | * Weighted random generated graphs. 117 | 118 | Anand Jeyahar 119 | * Edge deletion on hypergraphs (bug fix). 120 | 121 | Emanuele Zattin 122 | * Hyperedge relinking (bug fix). 123 | 124 | Jonathan Sternberg 125 | * Graph comparison (bug fix); 126 | * Proper isolation of attribute lists (bug fix). 127 | 128 | Daniel Merritt 129 | * Fixed reading of XML-stored graphs with edge attributes. 130 | 131 | 132 | LICENSE 133 | 134 | This software is provided under the MIT license. See accompanying COPYING file 135 | for details. 136 | -------------------------------------------------------------------------------- /python-graph/tests/unittests-heuristics.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pedro Matiello 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 | """ 26 | Unittests for graph.algorithms.heuristics 27 | """ 28 | 29 | 30 | import unittest 31 | import pygraph 32 | from pygraph.classes.graph import graph 33 | from pygraph.classes.digraph import digraph 34 | from pygraph.algorithms.heuristics.euclidean import euclidean 35 | from pygraph.algorithms.heuristics.chow import chow 36 | from pygraph.classes import exceptions 37 | 38 | from test_data import nations_of_the_world 39 | 40 | 41 | class test_chow(unittest.TestCase): 42 | 43 | def setUp(self): 44 | self.G = graph() 45 | nations_of_the_world(self.G) 46 | 47 | def test_basic(self): 48 | """ 49 | Test some very basic functionality 50 | """ 51 | englands_neighbors = self.G.neighbors("England") 52 | assert set(['Wales', 'Scotland', 'France', 'Ireland']) == set( englands_neighbors ) 53 | 54 | def test_chow(self): 55 | heuristic = chow( "Wales", "North Korea", "Russia" ) 56 | heuristic.optimize(self.G) 57 | result = pygraph.algorithms.minmax.heuristic_search( self.G, "England", "India", heuristic ) 58 | 59 | def test_chow_unreachable(self): 60 | heuristic = chow( "Wales", "North Korea", "Russia" ) 61 | self.G.add_node("Sealand") 62 | self.G.add_edge(("England", "Sealand")) 63 | heuristic.optimize(self.G) 64 | self.G.del_edge(("England", "Sealand")) 65 | 66 | try: 67 | result = pygraph.algorithms.minmax.heuristic_search( self.G, "England", "Sealand" , heuristic ) 68 | except exceptions.NodeUnreachable as _: 69 | return 70 | 71 | assert False, "This test should raise an unreachable error." 72 | 73 | 74 | class test_euclidean(unittest.TestCase): 75 | 76 | def setUp(self): 77 | self.G = pygraph.classes.graph.graph() 78 | self.G.add_node('A', [('position',[0,0])]) 79 | self.G.add_node('B', [('position',[2,0])]) 80 | self.G.add_node('C', [('position',[2,3])]) 81 | self.G.add_node('D', [('position',[1,2])]) 82 | self.G.add_edge(('A', 'B'), wt=4) 83 | self.G.add_edge(('A', 'D'), wt=5) 84 | self.G.add_edge(('B', 'C'), wt=9) 85 | self.G.add_edge(('D', 'C'), wt=2) 86 | 87 | def test_euclidean(self): 88 | heuristic = euclidean() 89 | heuristic.optimize(self.G) 90 | result = pygraph.algorithms.minmax.heuristic_search(self.G, 'A', 'C', heuristic ) 91 | assert result == ['A', 'D', 'C'] 92 | 93 | if __name__ == "__main__": 94 | unittest.main() -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/heuristics/euclidean.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | A* heuristic for euclidean graphs. 27 | """ 28 | 29 | 30 | # Imports 31 | 32 | 33 | class euclidean(object): 34 | """ 35 | A* heuristic for Euclidean graphs. 36 | 37 | This heuristic has three requirements: 38 | 1. All nodes should have the attribute 'position'; 39 | 2. The weight of all edges should be the euclidean distance between the nodes it links; 40 | 3. The C{optimize()} method should be called before the heuristic search. 41 | 42 | A small example for clarification: 43 | 44 | >>> g = graph.graph() 45 | >>> g.add_nodes(['A','B','C']) 46 | >>> g.add_node_attribute('A', ('position',(0,0))) 47 | >>> g.add_node_attribute('B', ('position',(1,1))) 48 | >>> g.add_node_attribute('C', ('position',(0,2))) 49 | >>> g.add_edge('A','B', wt=2) 50 | >>> g.add_edge('B','C', wt=2) 51 | >>> g.add_edge('A','C', wt=4) 52 | >>> h = graph.heuristics.euclidean() 53 | >>> h.optimize(g) 54 | >>> g.heuristic_search('A', 'C', h) 55 | """ 56 | 57 | def __init__(self): 58 | """ 59 | Initialize the heuristic object. 60 | """ 61 | self.distances = {} 62 | 63 | def optimize(self, graph): 64 | """ 65 | Build a dictionary mapping each pair of nodes to a number (the distance between them). 66 | 67 | @type graph: graph 68 | @param graph: Graph. 69 | """ 70 | for start in graph.nodes(): 71 | for end in graph.nodes(): 72 | for each in graph.node_attributes(start): 73 | if (each[0] == 'position'): 74 | start_attr = each[1] 75 | break 76 | for each in graph.node_attributes(end): 77 | if (each[0] == 'position'): 78 | end_attr = each[1] 79 | break 80 | dist = 0 81 | for i in range(len(start_attr)): 82 | dist = dist + (float(start_attr[i]) - float(end_attr[i]))**2 83 | self.distances[(start,end)] = dist 84 | 85 | def __call__(self, start, end): 86 | """ 87 | Estimate how far start is from end. 88 | 89 | @type start: node 90 | @param start: Start node. 91 | 92 | @type end: node 93 | @param end: End node. 94 | """ 95 | assert len(list(self.distances.keys())) > 0, "You need to optimize this heuristic for your graph before it can be used to estimate." 96 | 97 | return self.distances[(start,end)] -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/heuristics/euclidean.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | A* heuristic for euclidean graphs. 27 | """ 28 | 29 | 30 | # Imports 31 | 32 | 33 | class euclidean(object): 34 | """ 35 | A* heuristic for Euclidean graphs. 36 | 37 | This heuristic has three requirements: 38 | 1. All nodes should have the attribute 'position'; 39 | 2. The weight of all edges should be the euclidean distance between the nodes it links; 40 | 3. The C{optimize()} method should be called before the heuristic search. 41 | 42 | A small example for clarification: 43 | 44 | >>> g = graph.graph() 45 | >>> g.add_nodes(['A','B','C']) 46 | >>> g.add_node_attribute('A', ('position',(0,0))) 47 | >>> g.add_node_attribute('B', ('position',(1,1))) 48 | >>> g.add_node_attribute('C', ('position',(0,2))) 49 | >>> g.add_edge('A','B', wt=2) 50 | >>> g.add_edge('B','C', wt=2) 51 | >>> g.add_edge('A','C', wt=4) 52 | >>> h = graph.heuristics.euclidean() 53 | >>> h.optimize(g) 54 | >>> g.heuristic_search('A', 'C', h) 55 | """ 56 | 57 | def __init__(self): 58 | """ 59 | Initialize the heuristic object. 60 | """ 61 | self.distances = {} 62 | 63 | def optimize(self, graph): 64 | """ 65 | Build a dictionary mapping each pair of nodes to a number (the distance between them). 66 | 67 | @type graph: graph 68 | @param graph: Graph. 69 | """ 70 | for start in graph.nodes(): 71 | for end in graph.nodes(): 72 | for each in graph.node_attributes(start): 73 | if (each[0] == 'position'): 74 | start_attr = each[1] 75 | break 76 | for each in graph.node_attributes(end): 77 | if (each[0] == 'position'): 78 | end_attr = each[1] 79 | break 80 | dist = 0 81 | for i in range(len(start_attr)): 82 | dist = dist + (float(start_attr[i]) - float(end_attr[i]))**2 83 | self.distances[(start,end)] = dist 84 | 85 | def __call__(self, start, end): 86 | """ 87 | Estimate how far start is from end. 88 | 89 | @type start: node 90 | @param start: Start node. 91 | 92 | @type end: node 93 | @param end: End node. 94 | """ 95 | assert len(list(self.distances.keys())) > 0, "You need to optimize this heuristic for your graph before it can be used to estimate." 96 | 97 | return self.distances[(start,end)] -------------------------------------------------------------------------------- /python-graph/tests/unittests-cycles.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pedro Matiello 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 | """ 26 | Unittests for graph.algorithms.cycles 27 | """ 28 | 29 | 30 | import unittest 31 | import pygraph 32 | from pygraph.algorithms.cycles import find_cycle 33 | from pygraph.algorithms.searching import depth_first_search 34 | from pygraph.classes.digraph import digraph 35 | from pygraph.classes.graph import graph 36 | from sys import getrecursionlimit 37 | import testlib 38 | 39 | 40 | def verify_cycle(graph, cycle): 41 | for i in range(len(cycle)): 42 | assert graph.has_edge((cycle[i],cycle[(i+1)%len(cycle)])) 43 | 44 | class test_find_cycle(unittest.TestCase): 45 | 46 | # Graph 47 | 48 | def test_find_cycle_on_graph(self): 49 | gr = testlib.new_graph() 50 | cycle = find_cycle(gr) 51 | verify_cycle(gr, cycle) 52 | 53 | def test_find_cycle_on_graph_withot_cycles(self): 54 | gr = testlib.new_graph() 55 | st, pre, post = depth_first_search(gr) 56 | gr = graph() 57 | gr.add_spanning_tree(st) 58 | assert find_cycle(gr) == [] 59 | 60 | # Digraph 61 | 62 | def test_find_cycle_on_digraph(self): 63 | gr = testlib.new_digraph() 64 | cycle = find_cycle(gr) 65 | verify_cycle(gr, cycle) 66 | 67 | def test_find_cycle_on_digraph_without_cycles(self): 68 | gr = testlib.new_digraph() 69 | st, pre, post = depth_first_search(gr) 70 | gr = digraph() 71 | gr.add_spanning_tree(st) 72 | assert find_cycle(gr) == [] 73 | 74 | def test_find_small_cycle_on_digraph(self): 75 | gr = digraph() 76 | gr.add_nodes([1, 2, 3, 4, 5]) 77 | gr.add_edge((1, 2)) 78 | gr.add_edge((2, 3)) 79 | gr.add_edge((2, 4)) 80 | gr.add_edge((4, 5)) 81 | gr.add_edge((2, 1)) 82 | # Cycle: 1-2 83 | assert find_cycle(gr) == [1,2] 84 | 85 | def test_find_cycle_on_very_deep_graph(self): 86 | gr = pygraph.classes.graph.graph() 87 | gr.add_nodes(range(0,20001)) 88 | for i in range(0,20000): 89 | gr.add_edge((i,i+1)) 90 | recursionlimit = getrecursionlimit() 91 | find_cycle(gr) 92 | assert getrecursionlimit() == recursionlimit 93 | 94 | # Regression 95 | 96 | def test_regression1(self): 97 | G = digraph() 98 | G.add_nodes([1, 2, 3, 4, 5]) 99 | G.add_edge((1, 2)) 100 | G.add_edge((2, 3)) 101 | G.add_edge((2, 4)) 102 | G.add_edge((4, 5)) 103 | G.add_edge((3, 5)) 104 | G.add_edge((3, 1)) 105 | assert find_cycle(G) == [1, 2, 3] 106 | 107 | if __name__ == "__main__": 108 | unittest.main() -------------------------------------------------------------------------------- /python-graph/tests/unittests-pagerank.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Pedro Matiello 2 | # Juarez Bochi 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Unittests for pygraph.algorithms.pagerank 28 | """ 29 | 30 | import unittest 31 | from pygraph.classes.digraph import digraph 32 | from pygraph.algorithms.pagerank import pagerank 33 | import testlib 34 | 35 | class test_pagerank(unittest.TestCase): 36 | 37 | # pagerank algorithm 38 | 39 | def test_pagerank_empty(self): 40 | #Test if an empty dict is returned for an empty graph 41 | G = digraph() 42 | self.assertEqual(pagerank(G), {}) 43 | 44 | def test_pagerank_cycle(self): 45 | #Test if all nodes in a cycle graph have the same value 46 | G = digraph() 47 | G.add_nodes([1, 2, 3, 4, 5]) 48 | G.add_edge((1, 2)) 49 | G.add_edge((2, 3)) 50 | G.add_edge((3, 4)) 51 | G.add_edge((4, 5)) 52 | G.add_edge((5, 1)) 53 | self.assertEqual(pagerank(G), {1: 0.2, 2: 0.2, 3: 0.2, 4: 0.2, 5: 0.2}) 54 | 55 | def test_pagerank(self): 56 | #Test example from wikipedia: http://en.wikipedia.org/wiki/File:Linkstruct3.svg 57 | G = digraph() 58 | G.add_nodes([1, 2, 3, 4, 5, 6, 7]) 59 | G.add_edge((1, 2)) 60 | G.add_edge((1, 3)) 61 | G.add_edge((1, 4)) 62 | G.add_edge((1, 5)) 63 | G.add_edge((1, 7)) 64 | G.add_edge((2, 1)) 65 | G.add_edge((3, 1)) 66 | G.add_edge((3, 2)) 67 | G.add_edge((4, 2)) 68 | G.add_edge((4, 3)) 69 | G.add_edge((4, 5)) 70 | G.add_edge((5, 1)) 71 | G.add_edge((5, 3)) 72 | G.add_edge((5, 4)) 73 | G.add_edge((5, 6)) 74 | G.add_edge((6, 1)) 75 | G.add_edge((6, 5)) 76 | G.add_edge((7, 5)) 77 | expected_pagerank = { 78 | 1: 0.280, 79 | 2: 0.159, 80 | 3: 0.139, 81 | 4: 0.108, 82 | 5: 0.184, 83 | 6: 0.061, 84 | 7: 0.069, 85 | } 86 | pr = pagerank(G) 87 | for k in pr: 88 | self.assertAlmostEqual(pr[k], expected_pagerank[k], places=3) 89 | 90 | def test_pagerank_random(self): 91 | G = testlib.new_digraph() 92 | md = 0.00001 93 | df = 0.85 94 | pr = pagerank(G, damping_factor=df, min_delta=md) 95 | min_value = (1.0-df)/len(G) 96 | for node in G: 97 | expected = min_value 98 | for each in G.incidents(node): 99 | expected += (df * pr[each] / len(G.neighbors(each))) 100 | assert abs(pr[node] - expected) < md 101 | 102 | if __name__ == "__main__": 103 | unittest.main() 104 | -------------------------------------------------------------------------------- /malwaresamples/Test/mal1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/cycles.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Cycle detection algorithms. 27 | 28 | @sort: find_cycle 29 | """ 30 | 31 | 32 | # Imports 33 | from pygraph.classes.exceptions import InvalidGraphType 34 | from pygraph.classes.digraph import digraph as digraph_class 35 | from pygraph.classes.graph import graph as graph_class 36 | from sys import getrecursionlimit, setrecursionlimit 37 | 38 | def find_cycle(graph): 39 | """ 40 | Find a cycle in the given graph. 41 | 42 | This function will return a list of nodes which form a cycle in the graph or an empty list if 43 | no cycle exists. 44 | 45 | @type graph: graph, digraph 46 | @param graph: Graph. 47 | 48 | @rtype: list 49 | @return: List of nodes. 50 | """ 51 | 52 | if (isinstance(graph, graph_class)): 53 | directed = False 54 | elif (isinstance(graph, digraph_class)): 55 | directed = True 56 | else: 57 | raise InvalidGraphType 58 | 59 | def find_cycle_to_ancestor(node, ancestor): 60 | """ 61 | Find a cycle containing both node and ancestor. 62 | """ 63 | path = [] 64 | while (node != ancestor): 65 | if (node is None): 66 | return [] 67 | path.append(node) 68 | node = spanning_tree[node] 69 | path.append(node) 70 | path.reverse() 71 | return path 72 | 73 | def dfs(node): 74 | """ 75 | Depth-first search subfunction. 76 | """ 77 | visited[node] = 1 78 | # Explore recursively the connected component 79 | for each in graph[node]: 80 | if (cycle): 81 | return 82 | if (each not in visited): 83 | spanning_tree[each] = node 84 | dfs(each) 85 | else: 86 | if (directed or spanning_tree[node] != each): 87 | cycle.extend(find_cycle_to_ancestor(node, each)) 88 | 89 | recursionlimit = getrecursionlimit() 90 | setrecursionlimit(max(len(graph.nodes())*2,recursionlimit)) 91 | 92 | visited = {} # List for marking visited and non-visited nodes 93 | spanning_tree = {} # Spanning tree 94 | cycle = [] 95 | 96 | # Algorithm outer-loop 97 | for each in graph: 98 | # Select a non-visited node 99 | if (each not in visited): 100 | spanning_tree[each] = None 101 | # Explore node's connected component 102 | dfs(each) 103 | if (cycle): 104 | setrecursionlimit(recursionlimit) 105 | return cycle 106 | 107 | setrecursionlimit(recursionlimit) 108 | return [] 109 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/cycles.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 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 | """ 26 | Cycle detection algorithms. 27 | 28 | @sort: find_cycle 29 | """ 30 | 31 | 32 | # Imports 33 | from pygraph.classes.exceptions import InvalidGraphType 34 | from pygraph.classes.digraph import digraph as digraph_class 35 | from pygraph.classes.graph import graph as graph_class 36 | from sys import getrecursionlimit, setrecursionlimit 37 | 38 | def find_cycle(graph): 39 | """ 40 | Find a cycle in the given graph. 41 | 42 | This function will return a list of nodes which form a cycle in the graph or an empty list if 43 | no cycle exists. 44 | 45 | @type graph: graph, digraph 46 | @param graph: Graph. 47 | 48 | @rtype: list 49 | @return: List of nodes. 50 | """ 51 | 52 | if (isinstance(graph, graph_class)): 53 | directed = False 54 | elif (isinstance(graph, digraph_class)): 55 | directed = True 56 | else: 57 | raise InvalidGraphType 58 | 59 | def find_cycle_to_ancestor(node, ancestor): 60 | """ 61 | Find a cycle containing both node and ancestor. 62 | """ 63 | path = [] 64 | while (node != ancestor): 65 | if (node is None): 66 | return [] 67 | path.append(node) 68 | node = spanning_tree[node] 69 | path.append(node) 70 | path.reverse() 71 | return path 72 | 73 | def dfs(node): 74 | """ 75 | Depth-first search subfunction. 76 | """ 77 | visited[node] = 1 78 | # Explore recursively the connected component 79 | for each in graph[node]: 80 | if (cycle): 81 | return 82 | if (each not in visited): 83 | spanning_tree[each] = node 84 | dfs(each) 85 | else: 86 | if (directed or spanning_tree[node] != each): 87 | cycle.extend(find_cycle_to_ancestor(node, each)) 88 | 89 | recursionlimit = getrecursionlimit() 90 | setrecursionlimit(max(len(graph.nodes())*2,recursionlimit)) 91 | 92 | visited = {} # List for marking visited and non-visited nodes 93 | spanning_tree = {} # Spanning tree 94 | cycle = [] 95 | 96 | # Algorithm outer-loop 97 | for each in graph: 98 | # Select a non-visited node 99 | if (each not in visited): 100 | spanning_tree[each] = None 101 | # Explore node's connected component 102 | dfs(each) 103 | if (cycle): 104 | setrecursionlimit(recursionlimit) 105 | return cycle 106 | 107 | setrecursionlimit(recursionlimit) 108 | return [] 109 | -------------------------------------------------------------------------------- /python-graph/tests/unittests-readwrite.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pedro Matiello 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 | """ 26 | Unittests for graph.algorithms.readwrite 27 | """ 28 | 29 | 30 | import unittest 31 | import pygraph 32 | from pygraph.readwrite import dot, markup 33 | import testlib 34 | 35 | def graph_equality(gr1, gr2): 36 | for each in gr1.nodes(): 37 | assert each in gr2.nodes() 38 | for each in gr2.nodes(): 39 | assert each in gr1.nodes() 40 | for each in gr1.edges(): 41 | assert each in gr2.edges() 42 | for each in gr2.edges(): 43 | assert each in gr1.edges() 44 | 45 | class test_readwrite_dot(unittest.TestCase): 46 | 47 | def test_dot_for_graph(self): 48 | gr = testlib.new_graph() 49 | dotstr = dot.write(gr) 50 | gr1 = dot.read(dotstr) 51 | dotstr = dot.write(gr1) 52 | gr2 = dot.read(dotstr) 53 | graph_equality(gr1, gr2) 54 | assert len(gr.nodes()) == len(gr1.nodes()) 55 | assert len(gr.edges()) == len(gr1.edges()) 56 | 57 | def test_dot_for_digraph(self): 58 | gr = testlib.new_digraph() 59 | dotstr = dot.write(gr) 60 | gr1 = dot.read(dotstr) 61 | dotstr = dot.write(gr1) 62 | gr2 = dot.read(dotstr) 63 | graph_equality(gr1, gr2) 64 | assert len(gr.nodes()) == len(gr1.nodes()) 65 | assert len(gr.edges()) == len(gr1.edges()) 66 | 67 | def test_dot_for_hypergraph(self): 68 | gr = testlib.new_hypergraph() 69 | dotstr = dot.write(gr) 70 | gr1 = dot.read_hypergraph(dotstr) 71 | dotstr = dot.write(gr1) 72 | gr2 = dot.read_hypergraph(dotstr) 73 | graph_equality(gr1, gr2) 74 | 75 | def test_output_names_in_dot(self): 76 | gr1 = testlib.new_graph() 77 | gr1.name = "Some name 1" 78 | gr2 = testlib.new_digraph() 79 | gr2.name = "Some name 2" 80 | gr3 = testlib.new_hypergraph() 81 | gr3.name = "Some name 3" 82 | assert "Some name 1" in dot.write(gr1) 83 | assert "Some name 2" in dot.write(gr2) 84 | assert "Some name 3" in dot.write(gr3) 85 | 86 | class test_readwrite_markup(unittest.TestCase): 87 | 88 | def test_xml_for_graph(self): 89 | gr = testlib.new_graph() 90 | dotstr = markup.write(gr) 91 | gr1 = markup.read(dotstr) 92 | dotstr = markup.write(gr1) 93 | gr2 = markup.read(dotstr) 94 | graph_equality(gr1, gr2) 95 | assert len(gr.nodes()) == len(gr1.nodes()) 96 | assert len(gr.edges()) == len(gr1.edges()) 97 | 98 | def test_xml_digraph(self): 99 | gr = testlib.new_digraph() 100 | dotstr = markup.write(gr) 101 | gr1 = markup.read(dotstr) 102 | dotstr = markup.write(gr1) 103 | gr2 = markup.read(dotstr) 104 | graph_equality(gr1, gr2) 105 | assert len(gr.nodes()) == len(gr1.nodes()) 106 | assert len(gr.edges()) == len(gr1.edges()) 107 | 108 | def test_xml_hypergraph(self): 109 | gr = testlib.new_hypergraph() 110 | dotstr = markup.write(gr) 111 | gr1 = markup.read(dotstr) 112 | dotstr = markup.write(gr1) 113 | gr2 = markup.read(dotstr) 114 | graph_equality(gr1, gr2) 115 | 116 | if __name__ == "__main__": 117 | unittest.main() 118 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/generators.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Zsolt Haraszti 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Random graph generators. 28 | 29 | @sort: generate, generate_hypergraph 30 | """ 31 | 32 | 33 | # Imports 34 | from pygraph.classes.graph import graph 35 | from pygraph.classes.digraph import digraph 36 | from pygraph.classes.hypergraph import hypergraph 37 | from random import randint, choice, shuffle #@UnusedImport 38 | from time import time 39 | 40 | # Generator 41 | 42 | def generate(num_nodes, num_edges, directed=False, weight_range=(1, 1)): 43 | """ 44 | Create a random graph. 45 | 46 | @type num_nodes: number 47 | @param num_nodes: Number of nodes. 48 | 49 | @type num_edges: number 50 | @param num_edges: Number of edges. 51 | 52 | @type directed: bool 53 | @param directed: Whether the generated graph should be directed or not. 54 | 55 | @type weight_range: tuple 56 | @param weight_range: tuple of two integers as lower and upper limits on randomly generated 57 | weights (uniform distribution). 58 | """ 59 | # Graph creation 60 | if directed: 61 | random_graph = digraph() 62 | else: 63 | random_graph = graph() 64 | 65 | # Nodes 66 | nodes = range(num_nodes) 67 | random_graph.add_nodes(nodes) 68 | 69 | # Build a list of all possible edges 70 | edges = [] 71 | edges_append = edges.append 72 | for x in nodes: 73 | for y in nodes: 74 | if ((directed and x != y) or (x > y)): 75 | edges_append((x, y)) 76 | 77 | # Randomize the list 78 | shuffle(edges) 79 | 80 | # Add edges to the graph 81 | min_wt = min(weight_range) 82 | max_wt = max(weight_range) 83 | for i in range(num_edges): 84 | each = edges[i] 85 | random_graph.add_edge((each[0], each[1]), wt = randint(min_wt, max_wt)) 86 | 87 | return random_graph 88 | 89 | 90 | def generate_hypergraph(num_nodes, num_edges, r = 0): 91 | """ 92 | Create a random hyper graph. 93 | 94 | @type num_nodes: number 95 | @param num_nodes: Number of nodes. 96 | 97 | @type num_edges: number 98 | @param num_edges: Number of edges. 99 | 100 | @type r: number 101 | @param r: Uniform edges of size r. 102 | """ 103 | # Graph creation 104 | random_graph = hypergraph() 105 | 106 | # Nodes 107 | nodes = list(map(str, list(range(num_nodes)))) 108 | random_graph.add_nodes(nodes) 109 | 110 | # Base edges 111 | edges = list(map(str, list(range(num_nodes, num_nodes+num_edges)))) 112 | random_graph.add_hyperedges(edges) 113 | 114 | # Connect the edges 115 | if 0 == r: 116 | # Add each edge with 50/50 probability 117 | for e in edges: 118 | for n in nodes: 119 | if choice([True, False]): 120 | random_graph.link(n, e) 121 | 122 | else: 123 | # Add only uniform edges 124 | for e in edges: 125 | # First shuffle the nodes 126 | shuffle(nodes) 127 | 128 | # Then take the first r nodes 129 | for i in range(r): 130 | random_graph.link(nodes[i], e) 131 | 132 | return random_graph 133 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/generators.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2008-2009 Pedro Matiello 2 | # Zsolt Haraszti 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Random graph generators. 28 | 29 | @sort: generate, generate_hypergraph 30 | """ 31 | 32 | 33 | # Imports 34 | from pygraph.classes.graph import graph 35 | from pygraph.classes.digraph import digraph 36 | from pygraph.classes.hypergraph import hypergraph 37 | from random import randint, choice, shuffle #@UnusedImport 38 | from time import time 39 | 40 | # Generator 41 | 42 | def generate(num_nodes, num_edges, directed=False, weight_range=(1, 1)): 43 | """ 44 | Create a random graph. 45 | 46 | @type num_nodes: number 47 | @param num_nodes: Number of nodes. 48 | 49 | @type num_edges: number 50 | @param num_edges: Number of edges. 51 | 52 | @type directed: bool 53 | @param directed: Whether the generated graph should be directed or not. 54 | 55 | @type weight_range: tuple 56 | @param weight_range: tuple of two integers as lower and upper limits on randomly generated 57 | weights (uniform distribution). 58 | """ 59 | # Graph creation 60 | if directed: 61 | random_graph = digraph() 62 | else: 63 | random_graph = graph() 64 | 65 | # Nodes 66 | nodes = range(num_nodes) 67 | random_graph.add_nodes(nodes) 68 | 69 | # Build a list of all possible edges 70 | edges = [] 71 | edges_append = edges.append 72 | for x in nodes: 73 | for y in nodes: 74 | if ((directed and x != y) or (x > y)): 75 | edges_append((x, y)) 76 | 77 | # Randomize the list 78 | shuffle(edges) 79 | 80 | # Add edges to the graph 81 | min_wt = min(weight_range) 82 | max_wt = max(weight_range) 83 | for i in range(num_edges): 84 | each = edges[i] 85 | random_graph.add_edge((each[0], each[1]), wt = randint(min_wt, max_wt)) 86 | 87 | return random_graph 88 | 89 | 90 | def generate_hypergraph(num_nodes, num_edges, r = 0): 91 | """ 92 | Create a random hyper graph. 93 | 94 | @type num_nodes: number 95 | @param num_nodes: Number of nodes. 96 | 97 | @type num_edges: number 98 | @param num_edges: Number of edges. 99 | 100 | @type r: number 101 | @param r: Uniform edges of size r. 102 | """ 103 | # Graph creation 104 | random_graph = hypergraph() 105 | 106 | # Nodes 107 | nodes = list(map(str, list(range(num_nodes)))) 108 | random_graph.add_nodes(nodes) 109 | 110 | # Base edges 111 | edges = list(map(str, list(range(num_nodes, num_nodes+num_edges)))) 112 | random_graph.add_hyperedges(edges) 113 | 114 | # Connect the edges 115 | if 0 == r: 116 | # Add each edge with 50/50 probability 117 | for e in edges: 118 | for n in nodes: 119 | if choice([True, False]): 120 | random_graph.link(n, e) 121 | 122 | else: 123 | # Add only uniform edges 124 | for e in edges: 125 | # First shuffle the nodes 126 | shuffle(nodes) 127 | 128 | # Then take the first r nodes 129 | for i in range(r): 130 | random_graph.link(nodes[i], e) 131 | 132 | return random_graph 133 | -------------------------------------------------------------------------------- /python-graph/tests/unittests-searching.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pedro Matiello 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 | """ 26 | Unittests for graph.algorithms.searching 27 | """ 28 | 29 | 30 | # Imports 31 | import unittest 32 | import pygraph 33 | import pygraph.classes 34 | from pygraph.algorithms.searching import depth_first_search, breadth_first_search 35 | from sys import getrecursionlimit 36 | import testlib 37 | 38 | 39 | class test_depth_first_search(unittest.TestCase): 40 | 41 | def test_dfs_in_empty_graph(self): 42 | gr = pygraph.classes.graph.graph() 43 | st, pre, post = depth_first_search(gr) 44 | assert st == {} 45 | assert pre == [] 46 | assert post == [] 47 | 48 | def test_dfs_in_graph(self): 49 | gr = testlib.new_graph() 50 | st, pre, post = depth_first_search(gr) 51 | for each in gr: 52 | if (st[each] != None): 53 | assert pre.index(each) > pre.index(st[each]) 54 | assert post.index(each) < post.index(st[each]) 55 | for node in st: 56 | assert gr.has_edge((st[node], node)) or st[node] == None 57 | 58 | def test_dfs_in_empty_digraph(self): 59 | gr = pygraph.classes.digraph.digraph() 60 | st, pre, post = depth_first_search(gr) 61 | assert st == {} 62 | assert pre == [] 63 | assert post == [] 64 | 65 | def test_dfs_in_digraph(self): 66 | gr = testlib.new_digraph() 67 | st, pre, post = depth_first_search(gr) 68 | for each in gr: 69 | if (st[each] != None): 70 | assert pre.index(each) > pre.index(st[each]) 71 | assert post.index(each) < post.index(st[each]) 72 | for node in st: 73 | assert gr.has_edge((st[node], node)) or st[node] == None 74 | 75 | def test_dfs_very_deep_graph(self): 76 | gr = pygraph.classes.graph.graph() 77 | gr.add_nodes(range(0,20001)) 78 | for i in range(0,20000): 79 | gr.add_edge((i,i+1)) 80 | recursionlimit = getrecursionlimit() 81 | depth_first_search(gr, 0) 82 | assert getrecursionlimit() == recursionlimit 83 | 84 | class test_breadth_first_search(unittest.TestCase): 85 | 86 | def test_bfs_in_empty_graph(self): 87 | gr = pygraph.classes.graph.graph() 88 | st, lo = breadth_first_search(gr) 89 | assert st == {} 90 | assert lo == [] 91 | 92 | def test_bfs_in_graph(self): 93 | gr = pygraph.classes.graph.graph() 94 | gr = testlib.new_digraph() 95 | st, lo = breadth_first_search(gr) 96 | for each in gr: 97 | if (st[each] != None): 98 | assert lo.index(each) > lo.index(st[each]) 99 | for node in st: 100 | assert gr.has_edge((st[node], node)) or st[node] == None 101 | 102 | def test_bfs_in_empty_digraph(self): 103 | gr = pygraph.classes.digraph.digraph() 104 | st, lo = breadth_first_search(gr) 105 | assert st == {} 106 | assert lo == [] 107 | 108 | def test_bfs_in_digraph(self): 109 | gr = testlib.new_digraph() 110 | st, lo = breadth_first_search(gr) 111 | for each in gr: 112 | if (st[each] != None): 113 | assert lo.index(each) > lo.index(st[each]) 114 | for node in st: 115 | assert gr.has_edge((st[node], node)) or st[node] == None 116 | 117 | if __name__ == "__main__": 118 | unittest.main() -------------------------------------------------------------------------------- /src/malware2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/searching.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007-2009 Pedro Matiello 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 | """ 26 | Search algorithms. 27 | 28 | @sort: breadth_first_search, depth_first_search 29 | """ 30 | 31 | 32 | # Imports 33 | from pygraph.algorithms.filters.null import null 34 | from sys import getrecursionlimit, setrecursionlimit 35 | 36 | 37 | # Depth-first search 38 | 39 | def depth_first_search(graph, root=None, filter=null()): 40 | """ 41 | Depth-first search. 42 | 43 | @type graph: graph, digraph 44 | @param graph: Graph. 45 | 46 | @type root: node 47 | @param root: Optional root node (will explore only root's connected component) 48 | 49 | @rtype: tuple 50 | @return: A tupple containing a dictionary and two lists: 51 | 1. Generated spanning tree 52 | 2. Graph's preordering 53 | 3. Graph's postordering 54 | """ 55 | 56 | recursionlimit = getrecursionlimit() 57 | setrecursionlimit(max(len(graph.nodes())*2,recursionlimit)) 58 | 59 | def dfs(node): 60 | """ 61 | Depth-first search subfunction. 62 | """ 63 | visited[node] = 1 64 | pre.append(node) 65 | # Explore recursively the connected component 66 | for each in graph[node]: 67 | if (each not in visited and filter(each, node)): 68 | spanning_tree[each] = node 69 | dfs(each) 70 | post.append(node) 71 | 72 | visited = {} # List for marking visited and non-visited nodes 73 | spanning_tree = {} # Spanning tree 74 | pre = [] # Graph's preordering 75 | post = [] # Graph's postordering 76 | filter.configure(graph, spanning_tree) 77 | 78 | # DFS from one node only 79 | if (root is not None): 80 | if filter(root, None): 81 | spanning_tree[root] = None 82 | dfs(root) 83 | setrecursionlimit(recursionlimit) 84 | return spanning_tree, pre, post 85 | 86 | # Algorithm loop 87 | for each in graph: 88 | # Select a non-visited node 89 | if (each not in visited and filter(each, None)): 90 | spanning_tree[each] = None 91 | # Explore node's connected component 92 | dfs(each) 93 | 94 | setrecursionlimit(recursionlimit) 95 | 96 | return (spanning_tree, pre, post) 97 | 98 | 99 | # Breadth-first search 100 | 101 | def breadth_first_search(graph, root=None, filter=null()): 102 | """ 103 | Breadth-first search. 104 | 105 | @type graph: graph, digraph 106 | @param graph: Graph. 107 | 108 | @type root: node 109 | @param root: Optional root node (will explore only root's connected component) 110 | 111 | @rtype: tuple 112 | @return: A tuple containing a dictionary and a list. 113 | 1. Generated spanning tree 114 | 2. Graph's level-based ordering 115 | """ 116 | 117 | def bfs(): 118 | """ 119 | Breadth-first search subfunction. 120 | """ 121 | while (queue != []): 122 | node = queue.pop(0) 123 | 124 | for other in graph[node]: 125 | if (other not in spanning_tree and filter(other, node)): 126 | queue.append(other) 127 | ordering.append(other) 128 | spanning_tree[other] = node 129 | 130 | queue = [] # Visiting queue 131 | spanning_tree = {} # Spanning tree 132 | ordering = [] 133 | filter.configure(graph, spanning_tree) 134 | 135 | # BFS from one node only 136 | if (root is not None): 137 | if filter(root, None): 138 | queue.append(root) 139 | ordering.append(root) 140 | spanning_tree[root] = None 141 | bfs() 142 | return spanning_tree, ordering 143 | 144 | # Algorithm 145 | for each in graph: 146 | if (each not in spanning_tree): 147 | if filter(each, None): 148 | queue.append(each) 149 | ordering.append(each) 150 | spanning_tree[each] = None 151 | bfs() 152 | 153 | return spanning_tree, ordering 154 | -------------------------------------------------------------------------------- /python-graph/core/build/lib.linux-i686-2.6/pygraph/algorithms/searching.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2007-2009 Pedro Matiello 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 | """ 26 | Search algorithms. 27 | 28 | @sort: breadth_first_search, depth_first_search 29 | """ 30 | 31 | 32 | # Imports 33 | from pygraph.algorithms.filters.null import null 34 | from sys import getrecursionlimit, setrecursionlimit 35 | 36 | 37 | # Depth-first search 38 | 39 | def depth_first_search(graph, root=None, filter=null()): 40 | """ 41 | Depth-first search. 42 | 43 | @type graph: graph, digraph 44 | @param graph: Graph. 45 | 46 | @type root: node 47 | @param root: Optional root node (will explore only root's connected component) 48 | 49 | @rtype: tuple 50 | @return: A tupple containing a dictionary and two lists: 51 | 1. Generated spanning tree 52 | 2. Graph's preordering 53 | 3. Graph's postordering 54 | """ 55 | 56 | recursionlimit = getrecursionlimit() 57 | setrecursionlimit(max(len(graph.nodes())*2,recursionlimit)) 58 | 59 | def dfs(node): 60 | """ 61 | Depth-first search subfunction. 62 | """ 63 | visited[node] = 1 64 | pre.append(node) 65 | # Explore recursively the connected component 66 | for each in graph[node]: 67 | if (each not in visited and filter(each, node)): 68 | spanning_tree[each] = node 69 | dfs(each) 70 | post.append(node) 71 | 72 | visited = {} # List for marking visited and non-visited nodes 73 | spanning_tree = {} # Spanning tree 74 | pre = [] # Graph's preordering 75 | post = [] # Graph's postordering 76 | filter.configure(graph, spanning_tree) 77 | 78 | # DFS from one node only 79 | if (root is not None): 80 | if filter(root, None): 81 | spanning_tree[root] = None 82 | dfs(root) 83 | setrecursionlimit(recursionlimit) 84 | return spanning_tree, pre, post 85 | 86 | # Algorithm loop 87 | for each in graph: 88 | # Select a non-visited node 89 | if (each not in visited and filter(each, None)): 90 | spanning_tree[each] = None 91 | # Explore node's connected component 92 | dfs(each) 93 | 94 | setrecursionlimit(recursionlimit) 95 | 96 | return (spanning_tree, pre, post) 97 | 98 | 99 | # Breadth-first search 100 | 101 | def breadth_first_search(graph, root=None, filter=null()): 102 | """ 103 | Breadth-first search. 104 | 105 | @type graph: graph, digraph 106 | @param graph: Graph. 107 | 108 | @type root: node 109 | @param root: Optional root node (will explore only root's connected component) 110 | 111 | @rtype: tuple 112 | @return: A tuple containing a dictionary and a list. 113 | 1. Generated spanning tree 114 | 2. Graph's level-based ordering 115 | """ 116 | 117 | def bfs(): 118 | """ 119 | Breadth-first search subfunction. 120 | """ 121 | while (queue != []): 122 | node = queue.pop(0) 123 | 124 | for other in graph[node]: 125 | if (other not in spanning_tree and filter(other, node)): 126 | queue.append(other) 127 | ordering.append(other) 128 | spanning_tree[other] = node 129 | 130 | queue = [] # Visiting queue 131 | spanning_tree = {} # Spanning tree 132 | ordering = [] 133 | filter.configure(graph, spanning_tree) 134 | 135 | # BFS from one node only 136 | if (root is not None): 137 | if filter(root, None): 138 | queue.append(root) 139 | ordering.append(root) 140 | spanning_tree[root] = None 141 | bfs() 142 | return spanning_tree, ordering 143 | 144 | # Algorithm 145 | for each in graph: 146 | if (each not in spanning_tree): 147 | if filter(each, None): 148 | queue.append(each) 149 | ordering.append(each) 150 | spanning_tree[each] = None 151 | bfs() 152 | 153 | return spanning_tree, ordering 154 | -------------------------------------------------------------------------------- /python-graph/tests/unittests-filters.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Pedro Matiello 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 | python-graph 25 | 26 | Unit tests for python-graph 27 | """ 28 | 29 | 30 | # Imports 31 | import unittest 32 | import pygraph 33 | from pygraph.algorithms.searching import depth_first_search, breadth_first_search 34 | from pygraph.classes.graph import graph 35 | 36 | from pygraph.algorithms.filters.radius import radius 37 | from pygraph.algorithms.filters.find import find 38 | import testlib 39 | 40 | 41 | class test_find_filter(unittest.TestCase): 42 | 43 | def test_bfs_in_empty_graph(self): 44 | gr = graph() 45 | st, lo = breadth_first_search(gr, filter=find(5)) 46 | assert st == {} 47 | assert lo == [] 48 | 49 | def test_bfs_in_graph(self): 50 | gr = testlib.new_graph() 51 | gr.add_node('find-me') 52 | gr.add_edge((0, 'find-me')) 53 | st, lo = breadth_first_search(gr, root=0, filter=find('find-me')) 54 | assert st['find-me'] == 0 55 | for each in st: 56 | assert st[each] == None or st[each] == 0 or st[st[each]] == 0 57 | 58 | def test_bfs_in_digraph(self): 59 | gr = testlib.new_digraph() 60 | gr.add_node('find-me') 61 | gr.add_edge((0, 'find-me')) 62 | st, lo = breadth_first_search(gr, root=0, filter=find('find-me')) 63 | assert st['find-me'] == 0 64 | for each in st: 65 | assert st[each] == None or st[each] == 0 or st[st[each]] == 0 66 | 67 | def test_dfs_in_empty_graph(self): 68 | gr = graph() 69 | st, pre, post = depth_first_search(gr) 70 | assert st == {} 71 | assert pre == [] 72 | assert post == [] 73 | 74 | def test_dfs_in_graph(self): 75 | gr = testlib.new_graph() 76 | gr.add_node('find-me') 77 | gr.add_node('dont-find-me') 78 | gr.add_edge((0, 'find-me')) 79 | gr.add_edge(('find-me','dont-find-me')) 80 | st, pre, post = depth_first_search(gr, root=0, filter=find('find-me')) 81 | assert st['find-me'] == 0 82 | assert 'dont-find-me' not in st 83 | 84 | def test_dfs_in_digraph(self): 85 | gr = testlib.new_digraph() 86 | gr.add_node('find-me') 87 | gr.add_node('dont-find-me') 88 | gr.add_edge((0, 'find-me')) 89 | gr.add_edge(('find-me','dont-find-me')) 90 | st, pre, post = depth_first_search(gr, root=0, filter=find('find-me')) 91 | assert st['find-me'] == 0 92 | assert 'dont-find-me' not in st 93 | 94 | 95 | class test_radius_filter(unittest.TestCase): 96 | 97 | def testbfs_in_empty_graph(self): 98 | gr = graph() 99 | st, lo = breadth_first_search(gr, filter=radius(2)) 100 | assert st == {} 101 | assert lo == [] 102 | 103 | def test_bfs_in_graph(self): 104 | gr = testlib.new_graph() 105 | st, lo = breadth_first_search(gr, root=0, filter=radius(3)) 106 | for each in st: 107 | assert (st[each] == None or st[each] == 0 108 | or st[st[each]] == 0 or st[st[st[each]]] == 0) 109 | 110 | def test_bfs_in_digraph(self): 111 | gr = testlib.new_digraph() 112 | st, lo = breadth_first_search(gr, root=0, filter=radius(3)) 113 | for each in st: 114 | assert (st[each] == None or st[each] == 0 115 | or st[st[each]] == 0 or st[st[st[each]]] == 0) 116 | 117 | def test_dfs_in_empty_graph(self): 118 | gr = graph() 119 | st, pre, post = depth_first_search(gr, filter=radius(2)) 120 | assert st == {} 121 | assert pre == [] 122 | assert post == [] 123 | 124 | def test_dfs_in_graph(self): 125 | gr = testlib.new_graph() 126 | st, pre, post = depth_first_search(gr, root=0, filter=radius(3)) 127 | for each in st: 128 | assert (st[each] == None or st[each] == 0 129 | or st[st[each]] == 0 or st[st[st[each]]] == 0) 130 | 131 | def test_dfs_in_digraph(self): 132 | gr = testlib.new_graph() 133 | st, pre, post = depth_first_search(gr, root=0, filter=radius(3)) 134 | for each in st: 135 | assert (st[each] == None or st[each] == 0 136 | or st[st[each]] == 0 or st[st[st[each]]] == 0) 137 | 138 | if __name__ == "__main__": 139 | unittest.main() -------------------------------------------------------------------------------- /src/mcs.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import xml.etree.ElementTree as et 3 | from pygraph.classes.digraph import digraph 4 | 5 | # Global variables 6 | GTable = [] 7 | currentSize = 0 8 | savedmcs = [] 9 | 10 | # Checks if the pair of nodes are legal/feasible 11 | def isFeasiblePair (g1, g2, state, node1, node2): 12 | g_unused = state [1] 13 | if not ((node1, node2) in g_unused): 14 | return False 15 | g_used = state [0] 16 | if (node1, node2) in g_used: 17 | return False 18 | if not (g1.has_node (node1) and g2.has_node (node2)): 19 | return False 20 | if g_used == []: 21 | return True 22 | length = len (g_used) 23 | node1_attr = g1.node_attributes (node1) 24 | node2_attr = g2.node_attributes (node2) 25 | node1_label = node1_attr [0][1] 26 | node2_label = node2_attr [0][1] 27 | if node1_label != node2_label: 28 | return False 29 | i = 0 30 | while i < length: 31 | if (node1, node2) != g_used [i]: 32 | if (g1.has_edge ((g_used [i][0], node1)) ^ g2.has_edge ((g_used [i][1], node2))) or (g1.has_edge ((node1, g_used [i][0])) ^ g2.has_edge ((node2, g_used [i][1]))): 33 | return False 34 | i = i + 1 35 | return True 36 | 37 | # Adds the pair of nodes to the subgraph in the state 38 | def addPair (g1, g2, state, node1, node2): 39 | g_subGraph = state [2] 40 | if g_subGraph == None: 41 | g_subGraph = digraph () 42 | g_subGraph.add_node ((node1, node2), g1.node_attributes (node1)) 43 | state [2] = g_subGraph 44 | state [0].append ((node1, node2)) 45 | return state 46 | g_subGraph.add_node ((node1, node2), g1.node_attributes (node1)) 47 | g_used = state [0] 48 | for g1_node, g2_node in g_used: 49 | if g1.has_edge ((g1_node, node1)) and g2.has_edge ((g2_node, node2)): 50 | g_subGraph_wt = int(g1.edge_weight ((g1_node, node1))) + int(g2.edge_weight ((g2_node, node2))) 51 | g_subGraph.add_edge (((g1_node, g2_node), (node1, node2)), g_subGraph_wt) 52 | elif g1.has_edge ((node1, g1_node)) and g2.has_edge ((node2, g2_node)): 53 | g_subGraph_wt = int(g1.edge_weight ((node1, g1_node))) + int(g2.edge_weight ((node2, g2_node))) 54 | g_subGraph.add_edge (((node1, node2), (g1_node, g2_node)), g_subGraph_wt) 55 | 56 | state [0].append ((node1, node2)) 57 | return state 58 | 59 | # Determines if a state is a leaf 60 | def isLeaf (g1, g2, state): 61 | g_used = state [0] 62 | g1_usedlist = [node1 for node1, node2 in g_used] 63 | g2_usedlist = [node2 for node1, node2 in g_used] 64 | g1_iter = g1.__iter__ () 65 | g2_iter = g2.__iter__ () 66 | for g1_node in g1_iter: 67 | if g1_node not in g1_usedlist: 68 | return False 69 | 70 | for g2_node in g2_iter: 71 | if g2_node not in g2_usedlist: 72 | return False 73 | return True 74 | 75 | # Checks if the pruningCondition has arrived 76 | def pruningCondition (g1, g2, state): 77 | g1_len = len (g1) 78 | g2_len = len (g2) 79 | 80 | global currentSize 81 | subGraph_len = len (state [2]) 82 | states_left = min (g1_len, g2_len) - len (state [0]) 83 | if currentSize >= subGraph_len + states_left: 84 | return True 85 | 86 | # Initializes GTable in each run 87 | def init_GTable (g1, g2): 88 | global GTable 89 | g1_iter = [node for node in g1.__iter__ ()] 90 | g2_iter = [node for node in g2.__iter__ ()] 91 | for g1_node in g1_iter: 92 | for g2_node in g2_iter: 93 | GTable.append ((g1_node, g2_node)) 94 | 95 | # Update state information 96 | def update (state): 97 | if state [1] == None: 98 | state [1] = GTable [:] 99 | return 100 | g_unused = state [1][:] 101 | g_used = state [0] 102 | g1_usedlist = [g1_node for g1_node, g2_node in g_used] 103 | g2_usedlist = [g2_node for g1_node, g2_node in g_used] 104 | 105 | for g1_node, g2_node in g_unused: 106 | if g1_node in g1_usedlist or g2_node in g2_usedlist: 107 | state [1].remove ((g1_node, g2_node)) 108 | 109 | # Saves a state 110 | def savestate (state): 111 | copyof_used = state [0][:] 112 | copyof_unused = state [1][:] 113 | if state [2] == None: 114 | return [copyof_used, copyof_unused, None] 115 | g_subgraph = state [2] 116 | g_subgraph_nodes = g_subgraph.nodes () 117 | g_subgraph_edges = g_subgraph.edges () 118 | g_copy = digraph () 119 | for node in g_subgraph_nodes: 120 | g_copy.add_node (node, g_subgraph.node_attributes(node)) 121 | for edge in g_subgraph_edges: 122 | g_copy.add_edge (edge, g_subgraph.edge_weight (edge)) 123 | 124 | copy = [copyof_used, copyof_unused, g_copy] 125 | return copy 126 | 127 | # McGregor algorithm to find the maximum common subgraph (mcs) of two graphs 128 | def maxCS (g1, g2, state): 129 | update (state) 130 | global currentSize 131 | global savedmcs 132 | g_state = state 133 | for nodePair in g_state [1]: 134 | g1_node, g2_node = nodePair 135 | if isFeasiblePair (g1, g2, g_state, g1_node, g2_node): 136 | g_copy = savestate (g_state) 137 | new_state = addPair (g1, g2, g_copy, g1_node, g2_node) 138 | if len (new_state [2]) > currentSize: 139 | currentSize = len (new_state [2]) 140 | savedmcs.append (new_state [2]) 141 | if not isLeaf (g1, g2, new_state) and not pruningCondition (g1, g2, new_state): 142 | maxCS (g1, g2, new_state) 143 | 144 | # Initializes global variables in each run 145 | def init_globalvar (): 146 | global savedmcs 147 | global currentSize 148 | global GTable 149 | savedmcs = [] 150 | currentSize = 0 151 | GTable = [] 152 | 153 | # Initializes a run of McGregor algo; Returns mcs 154 | def mcsinit (g1, g2): 155 | init_globalvar () 156 | state = [[], None, None] 157 | init_GTable (g1, g2) 158 | maxCS (g1, g2, state) 159 | g_subgraph = savedmcs.pop() 160 | return g_subgraph 161 | 162 | -------------------------------------------------------------------------------- /src/wcbg.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | sys.path.append('/usr/lib/pyshared/python2.6') 3 | import gv 4 | import xml.etree.ElementTree as et 5 | from pygraph.classes.digraph import digraph 6 | from pygraph.readwrite.dot import * 7 | from mcs import * 8 | from mincs import * 9 | 10 | # Thresholds -> THETA for Pruning 11 | # -> GAMMA for Similarity 12 | THETA = 0.3 13 | GAMMA = 0.7 14 | 15 | # Kernel objects 16 | kernelObjects = [ 17 | "process_call", "process", "load_dll", "load_image", "open_file", "open_key", "get_file_attributes", 18 | "create_directory", "set_file_attributes", "set_file_time", "create_file", "create_mutex", "query_value", 19 | "set_value" "check_for_debugger", "get_system_directory", "create_thread", "create_window", "find_window", 20 | "enum_window", "show_window", "destroy_window", "set_windows_hook", "stored_created_file", "vm_protect", 21 | "connection", "ping", "find_file" 22 | ] 23 | 24 | # Gets pid from a list of attributes 25 | def getPidFromAttr (nodeAttr): 26 | for k, v in nodeAttr: 27 | if k == "pid": 28 | return v 29 | return -1 30 | 31 | # Gets process node with given pid 32 | def getProcNodeWithPid (g, nodeList, pid): 33 | for node in nodeList: 34 | nodeAttr = g.node_attributes (node) 35 | nodePid = getPidFromAttr (nodeAttr) 36 | if nodePid == pid: 37 | return node 38 | return None 39 | 40 | # Gets parent node of a process 41 | def getProcParent (g, node): 42 | if len (g) == 0: 43 | print 'In getproc(): Empty graph' 44 | return None 45 | nodeList = g.__iter__() 46 | nodeAttr = node.attrib.items () 47 | if nodeAttr == []: 48 | print 'In getproc(): Empty attribute list' 49 | return None 50 | 51 | pid = getPidFromAttr (nodeAttr) 52 | if pid == -1: 53 | print 'In getproc(): No attribute for pid was not found' 54 | return None 55 | 56 | node = getProcNodeWithPid (g, nodeList, pid) 57 | return node 58 | 59 | # Add nodes in the KOBG 60 | def addNodes (g, root): 61 | global nodeid 62 | parent = nodeid 63 | if len (g) == 0: 64 | nodeAttr = [("nodename", root.tag)] + root.attrib.items () 65 | g.add_node (nodeid, nodeAttr) 66 | 67 | for child in root: 68 | if child.tag in kernelObjects: 69 | if child.tag == "process": 70 | parent = getProcParent (g, child) 71 | 72 | if parent == None: 73 | print 'In addnodes(): Parent node cannot be None' 74 | sys.exit (0) 75 | 76 | attr = [("nodename", child.tag)] + child.attrib.items () 77 | nodeid = nodeid + 1 78 | g.add_node (nodeid, attr) 79 | g.add_edge ((parent, nodeid)) 80 | addNodes (g, child) 81 | 82 | # Initializes KOBG construction 83 | def makeKOBJGraph (filename): 84 | if os.path.isfile (filename): 85 | pass 86 | else: 87 | raise IOError ('File does not exists') 88 | 89 | tree = et.parse (filename) 90 | root = tree.getroot () 91 | g = digraph () 92 | addNodes (g, root) 93 | return g 94 | 95 | # Display graphs 96 | #def display (g): 97 | # l = g.nodes () 98 | # e = g.edges () 99 | # print l 100 | # print e 101 | 102 | # Returns a set of KOBGs 103 | def makeGraphSet (malwareDir): 104 | graphSet = [] 105 | global nodeid 106 | nodeid = 1 107 | for filename in os.listdir (malwareDir): 108 | filename = malwareDir + "/" + filename 109 | g = makeKOBJGraph (filename) 110 | nodeid = nodeid + 1 111 | graphSet.append (g) 112 | return graphSet 113 | 114 | # Function which initiates construction of KOBG of guest malware (only called by ismalware.py) 115 | def makeMalGraph (malwarefile): 116 | global nodeid 117 | nodeid = 1 118 | return makeKOBJGraph (malwarefile) 119 | 120 | # Normalize edge weights 121 | def normalize_weight (g, n): 122 | for edge in g.edges (): 123 | wt = float (g.edge_weight (edge)) 124 | g.set_edge_weight (edge, wt/n) 125 | return g 126 | 127 | # Generate a PNG image of the wcbg 128 | def generate_graph_image (wcbg, png_file): 129 | g = digraph () 130 | g.add_graph (wcbg) 131 | for edge in g.edges (): 132 | g.set_edge_weight (edge, wcbg.edge_weight (edge)) 133 | dot = write (g, True) 134 | gvv = gv.readstring (dot) 135 | gv.layout (gvv, 'dot') 136 | png_file = png_file + '.png' 137 | gv.render (gvv, 'png', png_file) 138 | 139 | # Save wcbg of a family by writing it to a file wcbg.digraph (in DOT language) 140 | def save_graph_in_file (g, filename, wt_flag): 141 | f = open (filename, 'w') 142 | copy = digraph () 143 | copy.add_graph (g) 144 | for node in copy: 145 | copy.add_node_attribute (node, g.node_attributes (node)[0]) 146 | for edge in copy.edges (): 147 | copy.set_edge_weight (edge, g.edge_weight (edge)) 148 | dot = write (copy, wt_flag) 149 | f.write (dot) 150 | f.close () 151 | 152 | 153 | # Init function 154 | if __name__ == '__main__': 155 | malwareDir = sys.argv[1] 156 | if os.path.isdir (malwareDir): 157 | pass 158 | else: 159 | raise IOError ('Directory does not exists') 160 | 161 | if os.listdir (malwareDir) == []: 162 | print 'In main: Directory specified is empty' 163 | sys.exit(0) 164 | 165 | gSet = makeGraphSet (malwareDir) 166 | if not gSet: 167 | print 'In main: Graph set is empty' 168 | sys.exit (0) 169 | 170 | index = 0 171 | length = len (gSet) 172 | g = gSet [0] 173 | while index < length: 174 | g, hotpath = mincs (g, gSet[index]) 175 | index = index + 1 176 | 177 | setweight (g, hotpath) 178 | wcbg = normalize_weight (g, length) 179 | generate_graph_image (wcbg, 'cluster') 180 | prunegraph (wcbg, THETA) 181 | 182 | hotpath_file = sys.argv [3] 183 | if os.path.isfile (hotpath_file): 184 | pass 185 | else: 186 | raise IOError ('File does not exists') 187 | save_graph_in_file (hotpath, hotpath_file, True) 188 | 189 | wcbg_file = sys.argv [2] 190 | if os.path.isfile (wcbg_file): 191 | pass 192 | else: 193 | raise IOError ('File does not exists') 194 | save_graph_in_file (wcbg, wcbg_file, True) 195 | png_file = wcbg_file.split ('.')[0] 196 | generate_graph_image (wcbg, png_file) 197 | generate_graph_image (hotpath, 'hotpath') 198 | 199 | 200 | -------------------------------------------------------------------------------- /malwaresamples/Test/mal2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /python-graph/core/pygraph/algorithms/critical.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2009 Pedro Matiello 2 | # Tomaz Kovacic 3 | # 4 | # Permission is hereby granted, free of charge, to any person 5 | # obtaining a copy of this software and associated documentation 6 | # files (the "Software"), to deal in the Software without 7 | # restriction, including without limitation the rights to use, 8 | # copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the 10 | # Software is furnished to do so, subject to the following 11 | # conditions: 12 | 13 | # The above copyright notice and this permission notice shall be 14 | # included in all copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | # OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | 26 | """ 27 | Critical path algorithms and transitivity detection algorithm. 28 | 29 | @sort: critical_path, transitive_edges 30 | """ 31 | 32 | 33 | # Imports 34 | from pygraph.algorithms.cycles import find_cycle 35 | from pygraph.algorithms.traversal import traversal 36 | from pygraph.algorithms.sorting import topological_sorting 37 | 38 | def _intersection(A,B): 39 | """ 40 | A simple function to find an intersection between two arrays. 41 | 42 | @type A: List 43 | @param A: First List 44 | 45 | @type B: List 46 | @param B: Second List 47 | 48 | @rtype: List 49 | @return: List of Intersections 50 | """ 51 | intersection = [] 52 | for i in A: 53 | if i in B: 54 | intersection.append(i) 55 | return intersection 56 | 57 | def transitive_edges(graph): 58 | """ 59 | Return a list of transitive edges. 60 | 61 | Example of transitivity within graphs: A -> B, B -> C, A -> C 62 | in this case the transitive edge is: A -> C 63 | 64 | @attention: This function is only meaningful for directed acyclic graphs. 65 | 66 | @type graph: digraph 67 | @param graph: Digraph 68 | 69 | @rtype: List 70 | @return: List containing tuples with transitive edges (or an empty array if the digraph 71 | contains a cycle) 72 | """ 73 | #if the graph contains a cycle we return an empty array 74 | if not len(find_cycle(graph)) == 0: 75 | return [] 76 | 77 | tranz_edges = [] # create an empty array that will contain all the tuples 78 | 79 | #run trough all the nodes in the graph 80 | for start in topological_sorting(graph): 81 | #find all the successors on the path for the current node 82 | successors = [] 83 | for a in traversal(graph,start,'pre'): 84 | successors.append(a) 85 | del successors[0] #we need all the nodes in it's path except the start node itself 86 | 87 | for next in successors: 88 | #look for an intersection between all the neighbors of the 89 | #given node and all the neighbors from the given successor 90 | intersect_array = _intersection(graph.neighbors(next), graph.neighbors(start) ) 91 | for a in intersect_array: 92 | if graph.has_edge((start, a)): 93 | ##check for the detected edge and append it to the returned array 94 | tranz_edges.append( (start,a) ) 95 | return tranz_edges # return the final array 96 | 97 | 98 | def critical_path(graph): 99 | """ 100 | Compute and return the critical path in an acyclic directed weighted graph. 101 | 102 | @attention: This function is only meaningful for directed weighted acyclic graphs 103 | 104 | @type graph: digraph 105 | @param graph: Digraph 106 | 107 | @rtype: List 108 | @return: List containing all the nodes in the path (or an empty array if the graph 109 | contains a cycle) 110 | """ 111 | #if the graph contains a cycle we return an empty array 112 | if not len(find_cycle(graph)) == 0: 113 | return [] 114 | 115 | #this empty dictionary will contain a tuple for every single node 116 | #the tuple contains the information about the most costly predecessor 117 | #of the given node and the cost of the path to this node 118 | #(predecessor, cost) 119 | node_tuples = {} 120 | 121 | topological_nodes = topological_sorting(graph) 122 | 123 | #all the tuples must be set to a default value for every node in the graph 124 | for node in topological_nodes: 125 | node_tuples.update( {node :(None, 0)} ) 126 | 127 | #run trough all the nodes in a topological order 128 | for node in topological_nodes: 129 | predecessors =[] 130 | #we must check all the predecessors 131 | for pre in graph.incidents(node): 132 | max_pre = node_tuples[pre][1] 133 | predecessors.append( (pre, graph.edge_weight( (pre, node) ) + max_pre ) ) 134 | 135 | max = 0; max_tuple = (None, 0) 136 | for i in predecessors:#look for the most costly predecessor 137 | if i[1] >= max: 138 | max = i[1] 139 | max_tuple = i 140 | #assign the maximum value to the given node in the node_tuples dictionary 141 | node_tuples[node] = max_tuple 142 | 143 | #find the critical node 144 | max = 0; critical_node = None 145 | for k,v in list(node_tuples.items()): 146 | if v[1] >= max: 147 | max= v[1] 148 | critical_node = k 149 | 150 | 151 | path = [] 152 | #find the critical path with backtracking trought the dictionary 153 | def mid_critical_path(end): 154 | if node_tuples[end][0] != None: 155 | path.append(end) 156 | mid_critical_path(node_tuples[end][0]) 157 | else: 158 | path.append(end) 159 | #call the recursive function 160 | mid_critical_path(critical_node) 161 | 162 | path.reverse() 163 | return path #return the array containing the critical path --------------------------------------------------------------------------------