Skip to main content

Biblioteca Ftopsis Class

Project description

FTOPSIS-Class

A biblioteca FTOPSIS-Class é uma implementação do algoritmo FTOPSIS (Fuzzy Technique for Order Preference by Similarity to Ideal Solution). Este algoritmo é usado para análise de decisão multicritério com dados fuzzy, ou seja, quando os valores dos critérios são imprecisos ou incertos. A biblioteca ajuda na normalização, ponderação e cálculo das soluções ideais, além de calcular distâncias e fornecer os resultados em um formato tabular.

Autores do Projeto



Luiz Henrique
Developer
Linkedin

José Ronaldo
Developer
Linkedin

Mariana Marinho
Developer
Linkedin

Vitória Beatriz
Developer
Linkedin

Aldo Lemos
Developer
Linkedin

Instalação (Download da biblioteca)

Você pode instalar a biblioteca utilizando pip:

pip install ftopsis-class

Esta biblioteca foi desenvolvida como parte de um projeto da cadeira de Sistemas de Apoio a Decisão no CIn-UFPE. Para mais informações sobre o método e a implementação, você pode consultar o artigo original:

A fuzzy hybrid integrated framework for portfolio optimization in private banking

Instalação (Rodar localmente)

Pré-requisitos

  • Python 3.8+
  • Pip (gerenciador de pacotes Python)

Instalação

  1. Clone o repositório:
    git clone git@github.com:adielfilho/SAD.git
    cd SAD/2024.2/FTOPSIS-Class
    
  2. Crie e ative um ambiente virtual:
    python -m venv venv
     # No Linux/Mac:
    source venv/bin/activate
     # No Windows:
    venv\Scripts\activate
    
  3. Instale as dependências:
     pip install -r requirements.txt
    
  4. Execute o sistema
    python3 main.py
    

Personalização dos Arquivos de Entrada

É possível alterar os arquivos JSON de entrada editando o arquivo main.py:

# Na função main(), procure por:
file_path = 'data/json/trapezoidal_input.json'  # ← Altere este caminho

# Você pode substituir por:
file_path = 'caminho/para/seu/arquivo.json'    # Caminho absoluto ou relativo

Dicas importantes:

  • O sistema detectará automaticamente se o JSON contém números triangulares (3 valores) ou trapezoidais (4 valores)
  • Ou seja, após a publicação da biblioteca, deve-se apenas fornecer o json de entrada que ela detectará automaticamente qual caso usar.
  • Mantenha a estrutura do JSON conforme os exemplos fornecidos na pasta data/json

Estrutura do código

main.py - Ponto de Entrada Principal

Responsabilidades:

  • Coordenação do fluxo principal do programa
  • Carregamento e processamento inicial dos dados

Principais Componentes:

class FTOPSISProcessor:
    # Classe utilitária com operações comuns
    @staticmethod
    def load_json_data(file_path)  # Carrega arquivos JSON
    @staticmethod
    def print_results(result)      # Exibe resultados formatados
    @staticmethod
    def detect_fuzzy_type(data)    # Detecta tipo de número fuzzy

def trapezoidal_ftopsis_class(data)  # Fluxo para números trapezoidais
def triangular_ftopsis_class(data)   # Fluxo para números triangulares 
def main()                          # Função principal de execução

triangular_core.py

Responsabilidades:

  • Implementação do algoritmo FTOPSIS para números fuzzy triangulares

Principais Componentes:

class CriteriaType(Enum):
    """Enumera os tipos de critérios"""
    Cost = 0    # Para critérios de custo (menor é melhor)
    Benefit = 1 # Para critérios de benefício (maior é melhor)

class FTOPSISClass:
    """Implementação completa do FTOPSIS para números triangulares"""

    @staticmethod
    def normalize_matrix(matrix, criteria_type):
        """
        Normaliza a matriz de decisão conforme o tipo de critério
        - Para critérios Benefit: divide cada valor pelo máximo da coluna
        - Para critérios Cost: divide o mínimo da coluna por cada valor
        Retorna: DataFrame normalizado
        """

    @staticmethod
    def weigh_matrix(df_normalized_matrix, df_vector_weights):
        """
        Aplica os pesos à matriz normalizada
        - Multiplica cada valor pelo peso correspondente
        - Arredonda os resultados para 4 casas decimais
        Retorna: DataFrame ponderado
        """

    @staticmethod
    def round_weighted_normalized_matrix(df_weighted_matrix):
        """
        Arredonda os valores da matriz ponderada
        - Padroniza a precisão numérica
        Retorna: DataFrame com valores arredondados
        """

    @staticmethod
    def ideal_solution(df_profile_matrix, profile_mapping):
        """
        Calcula as soluções ideais positiva e negativa
        - Baseado no mapeamento de perfis
        Retorna: Tuple (DataFrame solução positiva, DataFrame solução negativa)
        """

    @staticmethod
    def distance_calculation(matrix, df_positive, df_negative):
        """
        Calcula distâncias euclidianas para ambas as soluções ideais
        - Distância para a solução ideal positiva
        - Distância para a solução ideal negativa
        Retorna: Tuple (DataFrame distâncias positivas, DataFrame distâncias negativas)
        """

    @staticmethod
    def euclidean_distance(v1, v2):
        """
        Calcula distância euclidiana entre dois vetores
        - Implementação vetorizada com numpy
        Retorna: Lista de distâncias calculadas
        """

    @staticmethod
    def proximity_coefficient(positive_dist, negative_dist):
        """
        Calcula coeficiente de proximidade relativa
        - Fórmula: CC = negative_dist / (positive_dist + negative_dist)
        - Determina a classificação final
        Retorna: DataFrame com resultados finais
        """

trapezoidal_core.py

Responsabilidades:

  • Implementação do algoritmo FTOPSIS para números fuzzy trapezoidais

Principais Componentes:

class CriteriaType(Enum):
    """Enumera os tipos de critérios"""
    BENEFIT = 1  # Critérios onde maior é melhor
    COST = 0     # Critérios onde menor é melhor

class FuzzyNumber:
    """Representação de números fuzzy trapezoidais"""
    
    def __init__(self, a1: float, a2: float, a3: float, a4: float):
        """
        Inicializa número trapezoidal com:
        - a1: limite inferior esquerdo
        - a2: limite superior esquerdo 
        - a3: limite superior direito
        - a4: limite inferior direito
        """
    
    def distance(self, other: 'FuzzyNumber') -> float:
        """Calcula distância euclidiana entre dois números trapezoidais"""

class FTOPSISClass:
    """Implementação completa do FTOPSIS para números trapezoidais"""

    def __init__(self, linguistic_terms, weights, criteria_type,
                 elements, criteria, fuzzy_decision_matrix, reference_matrix):
        """
        Inicializa o processador FTOPSIS com:
        - linguistic_terms: Dicionário de termos linguísticos
        - weights: Pesos para cada critério
        - criteria_type: Tipo de cada critério (BENEFIT/COST)
        - elements: Lista de elementos a avaliar
        - criteria: Lista de critérios
        - fuzzy_decision_matrix: Matriz de decisão fuzzy
        - reference_matrix: Matriz de referência para perfis
        """

    def _normalize_criteria(self, values: List[FuzzyNumber], criterion: str) -> List[FuzzyNumber]:
        """
        Normaliza valores para um critério específico
        - BENEFIT: divide pelo valor máximo
        - COST: divide o valor mínimo por cada valor
        Retorna: Lista de FuzzyNumbers normalizados
        """

    def normalize_matrix(self) -> Dict:
        """
        Normaliza toda a matriz de decisão
        - Aplica pesos aos valores normalizados
        Retorna: Dicionário com valores normalizados e ponderados
        """

    def calculate_closeness(self) -> Dict:
        """
        Calcula coeficientes de proximidade para todos os elementos
        - Calcula distâncias para soluções ideais
        - Computa CC = d- / (d+ + d-)
        Retorna: Dicionário com CCs para cada perfil
        """

    def classify_funds(self) -> Dict:
        """
        Classifica elementos baseado nos coeficientes de proximidade
        - Seleciona perfil com maior CC para cada elemento
        Retorna: Dicionário com (perfil, CC) para cada elemento
        """

    def run(self) -> Tuple[Dict, Dict]:
        """
        Executa o fluxo completo do FTOPSIS
        Retorna: Tupla com (coeficientes, classificação)
        """

Exemplo de Entrada (Triangular)

Estrutura do JSON de Entrada

{
  "linguistic_variables_alternatives": {
    "MR": [0.0, 0.0, 2.5],
    "R": [0.0, 2.5, 5.0],
    "M": [2.5, 5.0, 7.5],
    "B": [5.0, 7.5, 10.0],
    "MB": [7.5, 10.0, 10.0]
  },
  "linguistic_variables_weights": {
    "NI": [0.2, 0.2, 0.4],
    "PI": [0.2, 0.4, 0.6],
    "IM": [0.4, 0.6, 0.8],
    "I": [0.6, 0.8, 1.0],
    "MI": [0.8, 0.8, 1.0]
  },
  "decision_matrix": {
    "C1": ["MB", "B", "M", "R", "MR", "MB", "MB", "R", "B"],
    "C2": ["MB", "B", "M", "R", "MR", "R", "MR", "B", "MR"],
    "C3": ["MB", "B", "M", "R", "MR", "B", "B", "B", "R"],
    "C4": ["MB", "B", "M", "R", "MR", "MB", "MB", "B", "MB"]
  },
  "profile_matrix": {
    "C1": ["MB", "B", "R"],
    "C2": ["B", "M", "R"],
    "C3": ["B", "M", "MR"],
    "C4": ["MB", "B", "M"]
  },
  "profile_mapping": {
    "0": "Preferível",
    "1": "Aceitável",
    "2": "Inaceitável"
  },
  "weights": {
    "C1": ["I"],
    "C2": ["IM"],
    "C3": ["IM"],
    "C4": ["I"]
  },
  "criteria_type": {
    "C1": "Benefit",
    "C2": "Benefit",
    "C3": "Benefit",
    "C4": "Benefit"
  },
  "alternatives": [
    "Fornecedor 1", "Fornecedor 2", "Fornecedor 3",
    "Fornecedor 4", "Fornecedor 5", "Fornecedor 6",
    "Fornecedor 7", "Fornecedor 8", "Fornecedor 9"
  ]
}

Exemplo de Saída (Triangular)

Estrutura do JSON de Resultados

{
  "results": {
    "Fornecedor 1": {
      "scores": {
        "Preferível": 0.8937556705796293,
        "Aceitável": 0.6960279609553498,
        "Inaceitável": 0.1062443294203707
      },
      "classification": "Preferível"
    },
    "Fornecedor 2": {
      "scores": {
        "Preferível": 0.8261102660508366,
        "Aceitável": 0.8151905914802051,
        "Inaceitável": 0.17388973394916343
      },
      "classification": "Preferível"
    },
    "Fornecedor 3": {
      "scores": {
        "Preferível": 0.4060976520273939,
        "Aceitável": 0.6156653142793894,
        "Inaceitável": 0.5939023479726061
      },
      "classification": "Aceitável"
    },
    // ... outros
  }
}

Exemplo de Entrada (Trapezoidal)

Estrutura do JSON de Entrada

{
  "linguistic_variables_alternatives": {
    "VL": [0.0, 0.0, 0.1, 0.2],
    "L": [0.1, 0.2, 0.3, 0.4],
    "M": [0.3, 0.4, 0.5, 0.6],
    "H": [0.5, 0.6, 0.7, 0.8],
    "VH": [0.7, 0.8, 0.9, 1.0]
  },
  "linguistic_variables_weights": {
    "U": [0.0, 0.0, 0.1, 0.2],
    "MI": [0.1, 0.2, 0.3, 0.4],
    "I": [0.3, 0.4, 0.5, 0.6],
    "VI": [0.5, 0.6, 0.7, 0.8],
    "EI": [0.7, 0.8, 0.9, 1.0]
  },
  "decision_matrix": {
    "C1": ["VL", "VL", "L", "L", "M", "M", "H", "H", "VH", "VH"],
    "C2": ["VL", "VL", "VL", "VL", "VL", "VL", "H", "L", "VL", "VH"],
    "C3": ["H", "VH", "H", "VH", "VH", "VH", "VH", "VL", "VH", "L"],
    "C4": ["VL", "VL", "L", "L", "M", "M", "H", "H", "VH", "VH"],
    "C5": ["VH", "VH", "H", "H", "M", "M", "L", "L", "VL", "VL"],
    "C6": ["VL", "VL", "L", "L", "M", "M", "H", "H", "VH", "VH"],
    "C7": ["M", "M", "M", "M", "VH", "VH", "VH", "H", "H", "VH"]
  },
  "profile_matrix": {
    "C1": ["L", "L", "H", "VH"],
    "C2": ["VL", "VL", "VL", "VL"],
    "C3": ["VL", "L", "H", "VH"],
    "C4": ["VL", "L", "H", "VH"],
    "C5": ["VH", "H", "L", "VL"],
    "C6": ["VL", "L", "H", "VH"],
    "C7": ["H", "H", "L", "VL"]
  },
  "profile_mapping": {
    "0": "Conservative",
    "1": "Moderate",
    "2": "Bold",
    "3": "Aggressive"
  },
  "weights": {
    "C1": ["I"],
    "C2": ["I"],
    "C3": ["I"],
    "C4": ["I"],
    "C5": ["I"],
    "C6": ["I"],
    "C7": ["I"]
  },
  "criteria_type": {
    "C1": "Benefit",
    "C2": "Benefit",
    "C3": "Benefit",
    "C4": "Benefit",
    "C5": "Benefit",
    "C6": "Benefit",
    "C7": "Benefit"
  },
  "alternatives": [
    "Fornecedor 1", "Fornecedor 2", "Fornecedor 3",
    "Fornecedor 4", "Fornecedor 5", "Fornecedor 6",
    "Fornecedor 7", "Fornecedor 8", "Fornecedor 9",
    "Fornecedor 10"
  ]
}

Exemplo de Saída (Trapezoidal)

Estrutura do JSON de Resultados

{
  "Fornecedor 1": {
    "scores": {
      "Conservative": 0.7924779185497123,
      "Moderate": 0.7316338477777367,
      "Bold": 0.2764522872002296,
      "Aggressive": 0.20752208145028767
    },
    "classification": "Conservative"
  },
  "Fornecedor 2": {
    "scores": {
      "Conservative": 0.7502583468121905,
      "Moderate": 0.6926263567079421,
      "Bold": 0.29903545546785604,
      "Aggressive": 0.24974165318780955
    },
    "classification": "Conservative"
  },
  "Fornecedor 3": {
    "scores": {
      "Conservative": 0.6844564478029598,
      "Moderate": 0.8324520673822401,
      "Bold": 0.43294774451407736,
      "Aggressive": 0.3155435521970403
    },
    "classification": "Moderate"
  },
  // ... outros
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ftopsis_class_cin-0.1.1.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ftopsis_class_cin-0.1.1-py3-none-any.whl (13.7 kB view details)

Uploaded Python 3

File details

Details for the file ftopsis_class_cin-0.1.1.tar.gz.

File metadata

  • Download URL: ftopsis_class_cin-0.1.1.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for ftopsis_class_cin-0.1.1.tar.gz
Algorithm Hash digest
SHA256 d05114837b00b3e99e5114d16e92f09891bfe60c8bcda105b5a34f1f0c20c8f6
MD5 747c36c553847a5482d32837cc9c846e
BLAKE2b-256 fb296ccc0bfc68454aacaa2865785bed02b6dd02d2d1df02c667b3499a40ed04

See more details on using hashes here.

File details

Details for the file ftopsis_class_cin-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for ftopsis_class_cin-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 30aa9d0b1ef2533f6298f5b6c4a59614f4df1afd6f1444eb899d78960938f191
MD5 ef7b6df04194c1c7a43766bc44f4eb8a
BLAKE2b-256 05db035587d687439d962ef487f62d05fa1ff91a919f8a924da61b480fdf4113

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page