Excelencia Operacional y Decisiones

Ricardo R.Palma \(\dagger^1\) [0000-0002-1864-7625], Fernando A. Lopez \(\ddagger^2\),
Victoria Inés Palma Cieri \(\dagger^3\)[0009-0008-6601-4428]
2025-09-23

Universidad Nacional de Cuyo Facultad de Ingeniería Ingeniería Industrial Mendoza - Argentina \(\dagger^{[1 y 3]}\) [ricardo.palma] [victoria.palma]@ingenieria.uncuyo.edu.ar

Universidad Católica Boliviana Departamento de Ingeniería Industrial La Paz - Bolivia \(\ddagger²\)


Bases para un framework de estrategia de manufactura basado en gemelos digitales

Resumen

Resumen El presente material aborda el uso de un método que aparece muy frecuentemente en la literatura denominado AHP. Fue creado por Tomas L. Saaty y dentro de sus múltiples posibilidades de uso, la más destacada es el ranking de alternativas o la selección de una de ellas. Se ha concebido como paso previo al desarrollo de un gemelo digital y posteriormente la implementación de una sombra digital de una empresa pequeña del centro oeste argentino. parap poder definir la tecnología de la sombra digital se han contemplado tres alternativas (A1-un sistema SAP, A2-Oddo CRM, A3-Un BSC con Power BI) Para realizar este proceso se parte del método de los factores ponderales y a partir de crear un vector de pesos relativos de los criterios de selección se confronta el desempeño de cada alternativa se obtiene un vector columna de ranking que muestra el desempeño de las alternativas A frente de los diferentes escenarios.

En el método de Saaty se agrega un interesante procedimiento basado en el autovector y autovalor de las matrices que intervienen para calcular el grado de inconsistencia del debate de los decisores. Esto elimina el sesgo que los decisores o metodólogos pudiesen inducir en el método de los factores ponderales.

Contexto de la Excelencia Operacional en la Estrategia de Manufactura Global

La excelencia operacional es un enfoque que busca la mejora continua en todos los aspectos de un negocio para lograr una ejecución más eficiente y consistente que la competencia. Esto implica optimizar procesos, reducir costos, mejorar la calidad y fomentar una cultura de innovación. Los gemelos digitales, por su parte, son réplicas virtuales de un objeto o sistema físico que se actualizan en tiempo real con datos de sensores. Su función es simular, analizar y optimizar el rendimiento del sistema real.

La relación entre ambos conceptos, AHP y EO, es directa y simbiótica. Los gemelos digitales se convierten en una herramienta crucial para alcanzar la excelencia operacional. Permiten simular escenarios, identificar cuellos de botella, prever fallos y evaluar el impacto de diferentes decisiones antes de implementarlas en el mundo físico. Esta capacidad de análisis y predicción en tiempo real es clave para la mejora continua y la optimización de procesos, que son los pilares de la excelencia operacional.

En este contexto, el método de Tomás Saaty (Proceso de Jerarquía Analítica o AHP) podría utilizarse como una herramienta para la concepción de alternativas para el gemelo digital. El AHP es un método de toma de decisiones multicriterio que ayuda a estructurar un problema complejo en una jerarquía de objetivos, criterios y alternativas. Se basa en comparaciones por pares para asignar pesos y prioridades a cada elemento.

Análisis de Decisiones usando la Metodología AHP

(Analytic Hierarchy Process de Thomas Saaty)

1. Introducción

Este documento implementa la metodología AHP (Analytic Hierarchy Process) desarrollada por Thomas Saaty para la toma de decisiones multicriterio. Analizaremos 3 alternativas usando 5 criterios de selección. Estos han surgido de un estudio previo basado en el benchmarking de Excelencia Operacional de un sector empresarios que incluye una cadena de abastecimiento que abarca una producción primaria (cosecha), manufactura, logística y distribución y finalmente logística reversa de envases junto a disposición final de residuos (pasivado para relleno sanitario o fertilizante) o uso como insumo en otras cadenas de valor (economía circular)

Problema de Decisión

Objetivo: Seleccionar la mejor alternativa de inversión tecnológica para la empresa mencionada que tiene como fortaleza el “preparedness” para la transformación digital

Alternativas:

Criterios de Evaluación:

2. Configuración del Entorno de R

Funciones y Matrices CR

# Cargar librerías necesarias
library(knitr)
library(ggplot2)
library(dplyr)
library(reshape2)
library(RColorBrewer)

# Función para calcular el vector propio principal
calcular_vector_propio <- function(matriz) {
  eigenvalues <- eigen(matriz)
  max_index <- which.max(eigenvalues$values)
  vector_propio <- abs(eigenvalues$vectors[, max_index])
  return(vector_propio / sum(vector_propio))
}

# Función para calcular el Índice de Consistencia (CI)
calcular_CI <- function(matriz) {
  n <- nrow(matriz)
  eigenvalues <- eigen(matriz)$values
  lambda_max <- max(Re(eigenvalues))
  CI <- (lambda_max - n) / (n - 1)
  return(CI)
}

# Función para calcular el Ratio de Consistencia (CR)
calcular_CR <- function(CI, n) {
  # Índices de consistencia aleatoria según Saaty
  RI <- c(0, 0, 0.58, 0.90, 1.12, 1.24, 1.32, 1.41, 1.45, 1.49)
  if (n <= 10) {
    CR <- CI / RI[n]
  } else {
    CR <- NA
  }
  return(CR)
}

3. Matrices de Comparación por Pares

3.1 Matriz de Comparación de Criterios

# Matriz de comparación por pares de criterios (5x5)
# Escala de Saaty: 1=igual, 3=moderadamente más importante, 5=fuertemente más importante,
#                  7=muy fuertemente más importante, 9=extremadamente más importante

criterios_matriz <- matrix(c(
  1,   1/3, 1/2, 2,   1/4,  # C1: Costo
  3,   1,   2,   3,   1/2,  # C2: Facilidad de uso
  2,   1/2, 1,   3,   1/3,  # C3: Funcionalidad
  1/2, 1/3, 1/3, 1,   1/5,  # C4: Soporte técnico
  4,   2,   3,   5,   1     # C5: Escalabilidad
), nrow = 5, byrow = TRUE)

rownames(criterios_matriz) <- c("Costo", "Facilidad_uso", "Funcionalidad", "Soporte", "Escalabilidad")
colnames(criterios_matriz) <- c("Costo", "Facilidad_uso", "Funcionalidad", "Soporte", "Escalabilidad")

print("Matriz de Comparación de Criterios:")
[1] "Matriz de Comparación de Criterios:"
kable(round(criterios_matriz, 3))
Costo Facilidad_uso Funcionalidad Soporte Escalabilidad
Costo 1.0 0.333 0.500 2 0.250
Facilidad_uso 3.0 1.000 2.000 3 0.500
Funcionalidad 2.0 0.500 1.000 3 0.333
Soporte 0.5 0.333 0.333 1 0.200
Escalabilidad 4.0 2.000 3.000 5 1.000

3.2 Cálculo de Pesos de Criterios

# Calcular vector propio (pesos de criterios)
pesos_criterios <- calcular_vector_propio(criterios_matriz)
names(pesos_criterios) <- rownames(criterios_matriz)

# Calcular consistencia
CI_criterios <- calcular_CI(criterios_matriz)
CR_criterios <- calcular_CR(CI_criterios, 5)

print("Pesos de los Criterios:")
[1] "Pesos de los Criterios:"
kable(data.frame(
  Criterio = names(pesos_criterios),
  Peso = round(pesos_criterios, 4),
  Porcentaje = paste0(round(pesos_criterios * 100, 2), "%")
))
Criterio Peso Porcentaje
Costo Costo 0.0987 9.87%
Facilidad_uso Facilidad_uso 0.2521 25.21%
Funcionalidad Funcionalidad 0.1623 16.23%
Soporte Soporte 0.0665 6.65%
Escalabilidad Escalabilidad 0.4205 42.05%
print(paste("Índice de Consistencia (CI):", round(CI_criterios, 4)))
[1] "Índice de Consistencia (CI): 0.0215"
print(paste("Ratio de Consistencia (CR):", round(CR_criterios, 4)))
[1] "Ratio de Consistencia (CR): 0.0192"
if (CR_criterios < 0.1) {
  print("✓ La matriz de criterios es consistente (CR < 0.10)")
} else {
  print("la matriz de criterios presenta inconsistencias (CR ≥ 0.10)")
}
[1] "✓ La matriz de criterios es consistente (CR < 0.10)"

4. Matrices de Comparación de Alternativas

4.1 Criterio 1: Costo de Implementación

# Matriz de comparación de alternativas respecto al costo
# (menor costo es mejor)
costo_matriz <- matrix(c(
  1,   1/2, 3,    # ERP vs CRM, ERP vs BI
  2,   1,   5,    # CRM vs ERP, CRM vs BI  
  1/3, 1/5, 1     # BI vs ERP, BI vs CRM
), nrow = 3, byrow = TRUE)

rownames(costo_matriz) <- c("ERP", "CRM", "BI")
colnames(costo_matriz) <- c("ERP", "CRM", "BI")

pesos_costo <- calcular_vector_propio(costo_matriz)
names(pesos_costo) <- rownames(costo_matriz)

print("Matriz - Costo de Implementación:")
[1] "Matriz - Costo de Implementación:"
kable(round(costo_matriz, 3))
ERP CRM BI
ERP 1.000 0.5 3
CRM 2.000 1.0 5
BI 0.333 0.2 1
print("Pesos para Costo:")
[1] "Pesos para Costo:"
kable(data.frame(Alternativa = names(pesos_costo), Peso = round(pesos_costo, 4)))
Alternativa Peso
ERP ERP 0.3090
CRM CRM 0.5816
BI BI 0.1095

4.2 Criterio 2: Facilidad de Uso

facilidad_matriz <- matrix(c(
  1,   1/3, 1/2,  # ERP vs CRM, ERP vs BI
  3,   1,   2,    # CRM vs ERP, CRM vs BI
  2,   1/2, 1     # BI vs ERP, BI vs CRM
), nrow = 3, byrow = TRUE)

rownames(facilidad_matriz) <- c("ERP", "CRM", "BI")
colnames(facilidad_matriz) <- c("ERP", "CRM", "BI")

pesos_facilidad <- calcular_vector_propio(facilidad_matriz)
names(pesos_facilidad) <- rownames(facilidad_matriz)

print("Matriz - Facilidad de Uso:")
[1] "Matriz - Facilidad de Uso:"
kable(round(facilidad_matriz, 3))
ERP CRM BI
ERP 1 0.333 0.5
CRM 3 1.000 2.0
BI 2 0.500 1.0
print("Pesos para Facilidad de Uso:")
[1] "Pesos para Facilidad de Uso:"
kable(data.frame(Alternativa = names(pesos_facilidad), Peso = round(pesos_facilidad, 4)))
Alternativa Peso
ERP ERP 0.1634
CRM CRM 0.5396
BI BI 0.2970

4.3 Criterio 3: Funcionalidad

funcionalidad_matriz <- matrix(c(
  1,   2,   1/2,  # ERP vs CRM, ERP vs BI
  1/2, 1,   1/3,  # CRM vs ERP, CRM vs BI
  2,   3,   1     # BI vs ERP, BI vs CRM
), nrow = 3, byrow = TRUE)

rownames(funcionalidad_matriz) <- c("ERP", "CRM", "BI")
colnames(funcionalidad_matriz) <- c("ERP", "CRM", "BI")

pesos_funcionalidad <- calcular_vector_propio(funcionalidad_matriz)
names(pesos_funcionalidad) <- rownames(funcionalidad_matriz)

print("Matriz - Funcionalidad:")
[1] "Matriz - Funcionalidad:"
kable(round(funcionalidad_matriz, 3))
ERP CRM BI
ERP 1.0 2 0.500
CRM 0.5 1 0.333
BI 2.0 3 1.000
print("Pesos para Funcionalidad:")
[1] "Pesos para Funcionalidad:"
kable(data.frame(Alternativa = names(pesos_funcionalidad), Peso = round(pesos_funcionalidad, 4)))
Alternativa Peso
ERP ERP 0.2970
CRM CRM 0.1634
BI BI 0.5396

4.4 Criterio 4: Soporte Técnico

soporte_matriz <- matrix(c(
  1,   3,   2,    # ERP vs CRM, ERP vs BI
  1/3, 1,   1/2,  # CRM vs ERP, CRM vs BI
  1/2, 2,   1     # BI vs ERP, BI vs CRM
), nrow = 3, byrow = TRUE)

rownames(soporte_matriz) <- c("ERP", "CRM", "BI")
colnames(soporte_matriz) <- c("ERP", "CRM", "BI")

pesos_soporte <- calcular_vector_propio(soporte_matriz)
names(pesos_soporte) <- rownames(soporte_matriz)

print("Matriz - Soporte Técnico:")
[1] "Matriz - Soporte Técnico:"
kable(round(soporte_matriz, 3))
ERP CRM BI
ERP 1.000 3 2.0
CRM 0.333 1 0.5
BI 0.500 2 1.0
print("Pesos para Soporte Técnico:")
[1] "Pesos para Soporte Técnico:"
kable(data.frame(Alternativa = names(pesos_soporte), Peso = round(pesos_soporte, 4)))
Alternativa Peso
ERP ERP 0.5396
CRM CRM 0.1634
BI BI 0.2970

4.5 Criterio 5: Escalabilidad

escalabilidad_matriz <- matrix(c(
  1,   1/2, 2,    # ERP vs CRM, ERP vs BI
  2,   1,   4,    # CRM vs ERP, CRM vs BI
  1/2, 1/4, 1     # BI vs ERP, BI vs CRM
), nrow = 3, byrow = TRUE)

rownames(escalabilidad_matriz) <- c("ERP", "CRM", "BI")
colnames(escalabilidad_matriz) <- c("ERP", "CRM", "BI")

pesos_escalabilidad <- calcular_vector_propio(escalabilidad_matriz)
names(pesos_escalabilidad) <- rownames(escalabilidad_matriz)

print("Matriz - Escalabilidad:")
[1] "Matriz - Escalabilidad:"
kable(round(escalabilidad_matriz, 3))
ERP CRM BI
ERP 1.0 0.50 2
CRM 2.0 1.00 4
BI 0.5 0.25 1
print("Pesos para Escalabilidad:")
[1] "Pesos para Escalabilidad:"
kable(data.frame(Alternativa = names(pesos_escalabilidad), Peso = round(pesos_escalabilidad, 4)))
Alternativa Peso
ERP ERP 0.2857
CRM CRM 0.5714
BI BI 0.1429

5. Cálculo de Puntuaciones Finales

# Crear matriz de decisión
matriz_decision <- cbind(pesos_costo, pesos_facilidad, pesos_funcionalidad, pesos_soporte, pesos_escalabilidad)
colnames(matriz_decision) <- c("Costo", "Facilidad_uso", "Funcionalidad", "Soporte", "Escalabilidad")

print("Matriz de Decisión (Pesos de alternativas por criterio):")
[1] "Matriz de Decisión (Pesos de alternativas por criterio):"
kable(round(matriz_decision, 4))
Costo Facilidad_uso Funcionalidad Soporte Escalabilidad
ERP 0.3090 0.1634 0.2970 0.5396 0.2857
CRM 0.5816 0.5396 0.1634 0.1634 0.5714
BI 0.1095 0.2970 0.5396 0.2970 0.1429
# Calcular puntuaciones finales
puntuaciones_finales <- matriz_decision %*% pesos_criterios
puntuaciones_finales <- as.vector(puntuaciones_finales)
names(puntuaciones_finales) <- c("Sistema ERP", "Plataforma CRM", "Solución BI")

# Crear tabla de resultados
resultados <- data.frame(
  Alternativa = names(puntuaciones_finales),
  Puntuacion = round(puntuaciones_finales, 4),
  Porcentaje = paste0(round(puntuaciones_finales * 100, 2), "%"),
  Ranking = rank(-puntuaciones_finales)
)

print("RESULTADOS FINALES:")
[1] "RESULTADOS FINALES:"
kable(resultados[order(-resultados$Puntuacion), ])
Alternativa Puntuacion Porcentaje Ranking
Plataforma CRM Plataforma CRM 0.4711 47.11% 1
Sistema ERP Sistema ERP 0.2759 27.59% 2
Solución BI Solución BI 0.2530 25.3% 3

6. Análisis de Sensibilidad por Criterios

# Crear matriz detallada para análisis
contribuciones <- matriz_decision * matrix(rep(pesos_criterios, each = 3), nrow = 3)
rownames(contribuciones) <- c("Sistema ERP", "Plataforma CRM", "Solución BI")
colnames(contribuciones) <- c("Costo", "Facilidad de Uso", "Funcionalidad", "Soporte", "Escalabilidad")

print("Contribución de cada criterio a la puntuación final:")
[1] "Contribución de cada criterio a la puntuación final:"
kable(round(contribuciones, 4))
Costo Facilidad de Uso Funcionalidad Soporte Escalabilidad
Sistema ERP 0.0305 0.0412 0.0482 0.0359 0.1201
Plataforma CRM 0.0574 0.1361 0.0265 0.0109 0.2403
Solución BI 0.0108 0.0749 0.0876 0.0197 0.0601

7. Visualizaciones

7.1 Gráfico Comparativo de Alternativas

# Preparar datos para visualización
datos_viz <- data.frame(
  Alternativa = rep(names(puntuaciones_finales), 2),
  Valor = c(puntuaciones_finales, puntuaciones_finales),
  Tipo = rep(c("Puntuación Final", "Porcentaje"), each = 3),
  Valor_Pct = c(puntuaciones_finales, puntuaciones_finales * 100)
)

# Gráfico de barras comparativo
p1 <- ggplot(datos_viz[datos_viz$Tipo == "Puntuación Final", ], 
             aes(x = reorder(Alternativa, -Valor), y = Valor, fill = Alternativa)) +
  geom_bar(stat = "identity", alpha = 0.8, width = 0.6) +
  geom_text(aes(label = paste0(round(Valor, 3), "\n(", round(Valor_Pct, 1), "%)")), 
            vjust = -0.5, size = 4, fontface = "bold") +
  scale_fill_brewer(type = "qual", palette = "Set2") +
  labs(title = "Comparación de Alternativas - Metodología AHP",
       subtitle = paste("Ganador:", names(puntuaciones_finales)[which.max(puntuaciones_finales)]),
       x = "Alternativas",
       y = "Puntuación AHP",
       caption = "Metodología: Analytic Hierarchy Process (Thomas Saaty)") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5, size = 12, color = "darkgreen"),
        axis.text.x = element_text(angle = 0, hjust = 0.5),
        legend.position = "none") +
  ylim(0, max(puntuaciones_finales) * 1.2)

print(p1)

7.2 Gráfico de Contribuciones por Criterio

# Preparar datos para gráfico de contribuciones
contrib_long <- melt(contribuciones)
colnames(contrib_long) <- c("Alternativa", "Criterio", "Contribucion")

# Gráfico de barras apiladas
p2 <- ggplot(contrib_long, aes(x = Alternativa, y = Contribucion, fill = Criterio)) +
  geom_bar(stat = "identity", position = "stack") +
  scale_fill_brewer(type = "qual", palette = "Set3") +
  labs(title = "Contribución de cada Criterio por Alternativa",
       subtitle = "Análisis de Sensibilidad - Metodología AHP",
       x = "Alternativas",
       y = "Contribución a la Puntuación Final",
       fill = "Criterios") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5, size = 12),
        axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "bottom") +
  guides(fill = guide_legend(nrow = 1))

print(p2)

7.3 Gráfico Radar de Alternativas

# Preparar datos para gráfico radar
radar_data <- as.data.frame(matriz_decision)
radar_data$Alternativa <- rownames(radar_data)

# Convertir a formato largo
radar_long <- melt(radar_data, id.vars = "Alternativa")
colnames(radar_long) <- c("Alternativa", "Criterio", "Valor")

# Gráfico de coordenadas polares (pseudo-radar)
p3 <- ggplot(radar_long, aes(x = Criterio, y = Valor, color = Alternativa, group = Alternativa)) +
  geom_line(size = 1.2, alpha = 0.8) +
  geom_point(size = 3, alpha = 0.9) +
  coord_polar() +
  scale_color_brewer(type = "qual", palette = "Dark2") +
  labs(title = "Perfil de Alternativas por Criterio",
       subtitle = "Gráfico Radar - Análisis Multicriterio AHP",
       y = "Puntuación por Criterio") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
        plot.subtitle = element_text(hjust = 0.5, size = 12),
        axis.text.x = element_text(size = 10),
        legend.position = "bottom")

print(p3)

8. Resumen Ejecutivo

mejor_alternativa <- names(puntuaciones_finales)[which.max(puntuaciones_finales)]
puntuacion_mejor <- max(puntuaciones_finales)


cat("========== RESUMEN EJECUTIVO ==========\n")
========== RESUMEN EJECUTIVO ==========
cat("Metodología: Analytic Hierarchy Process (AHP) - Thomas Saaty\n")
Metodología: Analytic Hierarchy Process (AHP) - Thomas Saaty
cat("Criterios evaluados:", length(pesos_criterios), "\n")
Criterios evaluados: 5 
cat("Alternativas analizadas:", length(puntuaciones_finales), "\n")
Alternativas analizadas: 3 
cat("Consistencia de juicios: CR =", round(CR_criterios, 3), 
    ifelse(CR_criterios < 0.1, "(Aceptable)", "(Revisar)"), "\n\n")
Consistencia de juicios: CR = 0.019 (Aceptable) 
cat("RECOMENDACIÓN:\n")
RECOMENDACIÓN:
cat("La mejor alternativa es:", mejor_alternativa, "\n")
La mejor alternativa es: Plataforma CRM 
cat("Puntuación AHP:", round(puntuacion_mejor, 4), 
    paste0("(", round(puntuacion_mejor * 100, 1), "%)"), "\n\n")
Puntuación AHP: 0.4711 (47.1%) 
cat("RANKING COMPLETO:\n")
RANKING COMPLETO:
for(i in order(-puntuaciones_finales)) {
  cat(paste0(which(order(-puntuaciones_finales) == i), "° ", 
             names(puntuaciones_finales)[i], ": ", 
             round(puntuaciones_finales[i], 4), 
             " (", round(puntuaciones_finales[i] * 100, 1), "%)\n"))
}
1° Plataforma CRM: 0.4711 (47.1%)
2° Sistema ERP: 0.2759 (27.6%)
3° Solución BI: 0.253 (25.3%)
cat("\nCRITERIO MÁS IMPORTANTE:", names(pesos_criterios)[which.max(pesos_criterios)], 
    paste0("(", round(max(pesos_criterios) * 100, 1), "%)"))

CRITERIO MÁS IMPORTANTE: Escalabilidad (42%)

Nota metodológica: Este análisis implementa la metodología AHP desarrollada por Thomas Saaty, utilizando comparaciones por pares con la escala fundamental de 1-9 y verificando la consistencia mediante el Ratio de Consistencia (CR). Se recomienda que CR < 0.10 para considerar los juicios como consistentes.

** link to https://rpubs.com/ricardorpama/1338567**

cite: Palma, R. R. (2025). Excelencia Operacional Bases para un framework de estrategia de manufactura. Zenodo. https://doi.org/10.5281/zenodo.16945306