Skip to content

"AnaHiePro" is a module that allows solving various tasks of systems analysis using the Analytic Hierarchy Process (AHP).

License

Notifications You must be signed in to change notification settings

danylevych/AnaHiePro

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Project logo

AnaHiePro

Status GitHub Issues GitHub Pull Requests License


AnaHiePro is a module that allows solving various tasks of systems analysis using the Analytic Hierarchy Process (AHP).

📝 Content

🧐 About

AnaHiePro is a Python module designed to simplify the decision-making process by using the Analytic Hierarchy Process (AHP) method. This method allows you to structure complex problems in the form of a hierarchical model consisting of goals, criteria, and alternatives. AnaHiePro automatically calculates global priorities for the entire hierarchy.

The module provides a recursive traversal of the hierarchical tree, starting from the leaf nodes and moving up to the root. Each level of the hierarchy is processed by multiplying the matrix of local child vectors by the global parent vector, which allows you to determine the weight of each element at all levels. This makes AnaHiePro an ideal tool for analyzing complex systems and making informed decisions in a variety of fields, including business, project management, scientific research, and more.

🏁 Getting Started

This is simple instruction how to install AnaHiePro on your PC and start to use it.

Installing

Open the terminal window and write the following command:

pip install anahiepro

After loading you can use all AnaHiePro's functionality, down below you can see the simplest way of using AnaHiePro.

from anahiepro.nodes import Problem, Criteria, Alternative
from anahiepro.models.model import Model

problem = Problem("Example Problem")

list_of_criterias = [
    Criteria("Citeria_1"),
    Criteria("Citeria_2"),
    Criteria("Citeria_3")
]

alternatives = [
    Alternative("Alternative_1"),
    Alternative("Alternative_2")
]

model = Model(problem, list_of_criterias, alternatives)

print(model.show())

🎈 Usage

Pairwise matrix

PairwiseComparisonMatrix represents the pairwise comparison matrix. A pairwise comparison matrix is a tool used in decision-making processes. It helps compare different options or criteria by evaluating them in pairs. Each element of the matrix represents the comparison result between two options or criteria.

Methods

Method Name Description
__init__(self, size, matrix) Initialize a pairwise comparison matrix with the given size or given matrix.
set_comparison(self, i, j, value) Set the comparison value for the given indices. Might raise the ValueError exception when you try to set diagonal values to value, that not equal 1.
set_matrix(self, matrix) Set the entire matrix, ensuring it is a valid pairwise comparison matrix. Might raise the ValueError if the matrix is not consistent or not valid.
get_matrix(self) Returns the current pairwise comparison matrix.
calculate_priority_vector(self) Calculate the priority vector from the pairwise comparison matrix.
calculate_consistency_ratio(self) Calculate the consistency ratio of the pairwise comparison matrix.
__getitem__(self, key) Returns the value at the specified index in the matrix.
__setitem__(self, key, value) Set the value at the specified index in the matrix.

Example

from anahiepro.pairwise import PairwiseComparisonMatrix


matrix = [
    [1,   2,   3],
    [1/2, 1,   2],
    [1/3, 1/2, 1] 
]

pairwise_matrix = PairwiseComparisonMatrix(matrix=matrix)

print(pairwise_matrix.get_matrix())
print("Consistency ratio:", pairwise_matrix.calculate_consistency_ratio())
print("Priority vector:", pairwise_matrix.calculate_priority_vector())

Output:

[[1.         2.         3.        ]
 [0.5        1.         2.        ]
 [0.33333333 0.5        1.        ]]
Consistency ratio: 0.007933373029552656
Priority vector: [0.84679693 0.46601031 0.25645536]

Nodes

AnaHiePro has three types of nodes: Problem, Criteria (also DummyCriteria, which use for normalizing a model) and Alternative. All of them is inherited from abstract class Node.

NOTE: And we want to mentioned that each class which is inhereted from Node has an id field.

Node class

As we mentioned before Node is a basic class for Problem, Criteria and Alternative. Down below you can see all Node's methods:

Method Name Description
__init__(self, name, parents, children, id, pcm) Initialize the Node object with given name, list of its parents, list of its children, identifier (id) and pcm.
get_name(self) Returns the name of the node.
get_parents(self) Returns list of parents for the node.
get_children(self) Returns list of childrens for the node.
get_key(self) Returns the tuple object, which consists of name of a node and its id.
add_child(self, child) Add child to the list of children.
show(self) Returns str object which represent all relations between nodes.
compare(self, key: tuple) Compare the node with a given key, where key is a tuple object which has size that equal 2. key[0] is a name of node and key[1] is an identifier of the node.
create_pcm(self) Create a pairwise comparison matrix (PCM) object for the node which shape is equal number of node's childrens.
set_matrix(self, matrix) Attach given PCM to the node. If the self.pcm does not exist call the create_pcm method than checks if the shape of given matrix matchs, raise VlalueError if does not otherwise attach it.
set_comparison(self, i, j, value) Set given value to the right place. Other words it is a wrapper above the PairwiseComparisonMatrix's set_comparison method.
get_priority_vector(self) Wrapper above PairwiseComparisonMatrix's get_priority_vector` method.
get_consistency_ratio(self) Wrapper above PairwiseComparisonMatrix's get_consistency_ratio` method.
get_pcm(self) Returns the pairwise comparison matrix of the node.
__eq__(self, value) Compare two Node's instance.
def show(self) Show the node and its children in a hierarchical structure.
__copy__(self) Copy the node.

Problem class

Problem is a class that represents the ptoblem, which user want to solve. This class inherits form Node and has the same methods as his parrent, except of this it overrides some methods.

Method Name Description
__init__(self, name, children, pcm) Initialize the Problem object with given name, list of its childern and pairwise comparison matrix.

Rest methods are the same as in Node class.

Criteria class

Criteria represents the criteria which will be used for selection. This class inherits form Node and has the same methods as his parrent, except of this it overrides some methods.

Method Name Description
__init__(self, name, children, pcm) Initialize the Criteria object with given name, list of its childern and pairwise comparison matrix.

Rest methods are the same as in Node class.

DummyCriteria class

DummyCriteria class that inherited from Criteria it is used for normalizing problem in VaryDepthModel.

Alternative class

Alternative represents alternatives between which the selection is happened. Scince Alternative is the final node in hierarchy it have not children, so that the self.pcm field for it is deleted.

Method Name Description
__init__(self, name) Initialize the Alternative object with given name.
create_pcm(self) Does not implemented for reasons which were mentioned.
set_matrix(self, matrix) Does not implemented and raise NotImplementedError exception.
`set_comparison(self, i, j, value) Does not implemented and raise NotImplementedError exception.

Rest methods are the same as in Node class.

Example

from anahiepro.nodes import Problem, Criteria, Alternative


# Create instance of each classes.
problem = Problem("Example Problem")

criteria1 = Criteria("Criteria_1")
criteria2 = Criteria("Criteria_2")

alternative1 = Alternative("Alternative_1")
alternative2 = Alternative("Alternative_2")

# Lincing each instances.
problem.add_child(criteria1)
problem.add_child(criteria2)

criteria1.add_child(alternative1)
criteria1.add_child(alternative2)

criteria2.add_child(alternative1)
criteria2.add_child(alternative2)

# Print the problem hierarchy.
print(problem.show())

Output:

+Example Problem
+--Criteria_1
+----Alternative_1
+----Alternative_2
+--Criteria_2
+----Alternative_1
+----Alternative_2

Models

AnaHiePro has two types of models that you can use for automatic solve setted problem - Model and VaryDepthModel.

Differences between Model and VaryDepthModel

This two classes are called for solve different types of problem. To be honest VaryDepthModel is used for problems with different depth such as at the image down below.

example

At that time the Model can solve problems which have hierarchy with the same depth of each children for them (look at the next picture).

example

About Models

Each model classes, which AnaHiePro has, have the methods which is described down below.

Method Name Description
__init__(self, problem: Problem, criterias, alternatives: list) Initialize the model with a problem, criteria, and alternatives. Also checks if the criterias has correct format, type and for Model - if the depth of the criterias hierarchy is the same depth.
get_problem(self) Return the problem instance.
get_alternatives(self) Return the list of alternatives.
get_criterias_name_ids(self) Get the names and IDs of the criteria.
find_criteria(self, key: tuple) Find criteria by (name, id) tuple.
attach_criteria_pcm(self, key: tuple, pcm) Attach a pairwise comparison matrix to the criteria identified by the key.
__getitem__(self, key: tuple) Get the criteria identified by the key.
solve(self, showAlternatives=False) Solve the model to calculate the global priority vector.
show(self) Display the problem.

Examples

Model and VaryDepthModel can take the next format of the criterias in their __init__ method:

criterias = [Criteria(children=[Criteria()]), 
             Criteria(children=[Criteria()]),
             Criteria(children=[Criteria()])]

or

criterias = [
    {Criteria(): [
        {Criteria(): None}
    ]},
    {Criteria(): [
        {Criteria(): None}
    ]},
    {Criteria(): [
        {Criteria(): None}
    ]}
]

Another formats of the criterias param is not added (except of empty list).

Here you can see the simplest way how to create Model instance:

from anahiepro.nodes import Problem, Criteria, Alternative
from anahiepro.models.model import Model

problem = Problem("Example Problem")

list_of_criterias = [
    Criteria("Citeria_1", children=[
        Criteria("Criteria_4")
    ]),
    Criteria("Citeria_2", children=[
        Criteria("Criteria_5")
    ]),
    Criteria("Citeria_3", children=[
        Criteria("Criteria_5")
    ]),
]

alternatives = [
    Alternative("Alternative_1"),
    Alternative("Alternative_2")
]

model = Model(problem, list_of_criterias, alternatives)

print(model.show())

Output:

+Example Problem
+--Citeria_1
+----Criteria_4
+------Alternative_1
+------Alternative_2
+--Citeria_2
+----Criteria_5
+------Alternative_1
+------Alternative_2
+--Citeria_3
+----Criteria_5
+------Alternative_1
+------Alternative_2

Now let's see how it works for VaryDepthModel:

from anahiepro.nodes import Problem, Criteria, Alternative
from anahiepro.models.vary_depth_model import VaryDepthModel

problem = Problem("Example Problem")

list_of_criterias = [
    Criteria("Citeria_1", children=[
        Criteria("Criteria_4")
    ]),
    Criteria("Citeria_2", children=[
        Criteria("Criteria_5")
    ]),
    Criteria("Citeria_3"),  # <- Here Criteria_3 does not have children.
]

alternatives = [
    Alternative("Alternative_1"),
    Alternative("Alternative_2")
]

model = VaryDepthModel(problem, list_of_criterias, alternatives)

print(model.show())

Output:

+Example Problem
+--Citeria_1
+----Criteria_4
+------Alternative_1
+------Alternative_2
+--Citeria_2
+----Criteria_5
+------Alternative_1
+------Alternative_2
+--DummyCriteria0
+----Citeria_3
+------Alternative_1
+------Alternative_2

So, as you can see from the out put VaryDepthModel normalize the hierarchy of problem. And, yes, you can use VaryDepthModel with the example for Model class.

Example with the solving of the hierarchy

from anahiepro.nodes import Problem, Criteria, Alternative
from anahiepro.models.model import Model

problem = Problem("Example Problem", pcm=[[1,   2,   1/2],
                                          [1/2, 1,   1/7],
                                          [2,   7,   1]])

list_of_criterias = [
    Criteria("Citeria_1", pcm=[[1,   2,   4],
                               [1/2, 1,   3],
                               [1/4, 1/3, 1]]),
    
    Criteria("Citeria_2", pcm=[[1,   2,   1/5],
                               [1/2, 1,   3],
                               [5,   1/3, 1]]),
    
    Criteria("Citeria_3", pcm=[[1,   1/3,   3],
                               [3,   1,   3],
                               [1/3, 1/3, 1]]),
]

alternatives = [
    Alternative("Alternative_1"),
    Alternative("Alternative_2"),
    Alternative("Alternative_3")
]

model = Model(problem, list_of_criterias, alternatives)

print("Global vector without alternatives:")
print(model.solve())

print("Global vector with alternatives:")
print(model.solve(showAlternatives=True))

Output:

Global vector without alternatives:
[0.64557092 0.88998852 0.15336415]

Global vector with alternatives:
[(Alternative_1, np.float64(0.6455709201621959)), (Alternative_2, np.float64(0.8899885172373624)), (Alternative_3, np.float64(0.15336414859759606))]

✍️ Authors

About

"AnaHiePro" is a module that allows solving various tasks of systems analysis using the Analytic Hierarchy Process (AHP).

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages