Nos hemos trasladado al Londres de la época victoriana para resolver el misterio de la muerte de Agatha y dar así respuesta al Challenge de este mes, al más puro estilo Agatha Christie. Esta es nuestra respuesta al reto planteado por Decision Management Community, Decision Model “Who killed Agatha?”.
«Someone in Dreadsbury Mansion killed Aunt Agatha. Agatha, the butler, and Charles live in Dreadsbury Mansion, and are the only ones to live there. A killer always hates, and is no richer than his victim. Charles hates noone that Agatha hates. Agatha hates everybody except the butler. The butler hates everyone not richer than Aunt Agatha. The butler hates everyone whom Agatha hates. Noone hates everyone. Who killed Agatha?»
Aunque este tipo de problemática está más orientada a técnicas de Optimización e Investigación Operativa, vamos a intentar resolver el misterio con un proyecto de Reglas con la versión 8.6 del producto de IBM ODM.
Aprovechando las nuevas funcionalidades que incorpora la herramienta de desarrollo Rule Designer, para implementar la solución se ha creado un Servicio de Decisión, DreadsburyMansion-Rules, con una única operación DreadsburyMansion-RulesOperation. Se ha optado por esta solución porque los servicios de decisiones, además de dar una definición clara y gestionada de operaciones de servicio de decisiones y configuraciones de despliegue, amplían el entorno colaborativo entre la parte técnica, que trabaja principalmente con Rule Designer, y los usuarios de negocio que trabajan a través de la consola de Decision Center.
Desglosamos la información del enunciado en tres grupos que nos definen:
- Las relaciones de odio entre los habitantes de la mansión.
- La relación de riqueza de cada uno de los habitantes con respecto a la víctima.
- Las restricciones que tiene que cumplir el asesino.
En primer lugar definimos los parámetros de entrada y de salida. La entrada son los habitantes de la Mansión Dreadsbury. Para ello hemos definido un array de tipo Inhabitant, que se corresponde con cada uno de los habitantes de la mansión. La salida es la solución del misterio, por lo que hemos creado un tipo Solution que contiene la lista de asesinos, nadie ha dicho que sea uno solo.
Cada uno de los habitantes de la mansión, tiene una relación de odio con respecto al resto y una relación de riqueza con respecto a la víctima, Agatha. Las relaciones de odio las vamos a definir en la entrada, mientras que las relaciones de riqueza las vamos a determinar con reglas en base a las relaciones de odio de cada uno de los habitantes definidas en la entrada.
También vamos a crear una variable para determinar si los datos de entrada cumplen la restricción de que nadie odia a todo el mundo. Por defecto tendrá valor cierto, y se modificará si se cumple la regla de restricción creada para comprobarlo.
Teniendo en cuenta el desglose del enunciado, y tal y como se observa en la imagen inferior, definimos el flujo de reglas que orquestará la ejecución de las mismas, y que contiene las siguientes tareas:
- 1-Hate Restrictions – Comprobación de que los datos de entrada cumplen la restricción de odio nadie odia a todo el mundo.
- 2-Wealth – Establece si el habitante de la mansión no es más rico que la víctima.
- Initialize the list of suspects – Inicialización de la lista de sospechosos, que serán todos los habitantes de la mansión.
- 3-ResolutionOfTheMystery – Resolución del misterio, es decir, ejecución de las restricciones que tiene que cumplir el asesino.
- #RuleTask1 – Para determinar si la entrada cumple la restricción de odio, utilizamos la siguiente regla:
Si se cumple que alguno de los habitantes odia a todos los demás, la variable ‘Noone hates everyone’ se inicializa a falso y por lo tanto no se seguirán ejecutando el resto de tareas.
- #RuleTask2 – Según el enunciado, un habitante de la mansión es más rico que la víctima si éste no es odiado por el mayordomo, por lo que para establecer si un habitante es más rico que la víctima ejecutamos la siguiente regla:
Esta regla inicializa el atributo isRicherThanTheVictim a falso a cada uno de los habitantes de la mansión a los que odia el mayordomo.
- #ActionTask – Inicialización de la lista de sospechosos. Inicialmente todos los habitantes de la mansión son sospechosos del asesinato de la tía Agatha.
- #RuleTask3 – Aplicamos sobre la lista de sospechosos las restricciones que tiene que cumplir el asesino. El conjunto de reglas que definen estas restricciones son:
#Rule1: A killer always hates
#Rule2: The killer is no richer than his victim
En Decision Center vemos que las reglas están organizadas en el proyecto de reglas en la siguiente estructura de carpetas:
Ya podemos probar nuestro servicio y descubrir quién es el asesino… qué emoción!! Vamos a generar un test basado en un fichero Excel en el que vamos a representar un escenario de prueba.
En la pestaña de Scenarios definimos los habitantes de la mansión, Agatha, Charles y el mayordomo.
En la pestaña de inhabitant establecemos para cada uno de los habitantes de la mansión la relación de odio con el resto, conforme al enunciado del problema. El enunciado es categórico a la hora de establecer a quién odia Agatha y el mayordomo, sin embargo, a quién odia Charles es más ambiguo. Dice que Charles no odia a las personas a las que odia Agatha, pero eso no quiere decir que odie al resto. Nosotros vamos a suponer que odia al mayordomo, es la única persona a la que puede odiar puesto que Agatha se odia a sí misma y a Charles, «Agatha odia a todo el mundo excepto al mayordomo».
En la pestaña Expected Results la lista de asesinos. Supongamos que son Agatha, estaríamos hablando de un suicidio, y Charles.
Para ejecutar la prueba que hemos diseñado, subimos el fichero Excel a Decision Center y ejecutamos.
Comprobamos que la lista de asesinos que nos devuelve el servicio corresponde con los resultados esperados.
Ahora supongamos que Charles no odia a nadie, no queda del todo claro en el enunciado. En nuestra Excel de pruebas modificamos la pestaña inhabitant de la siguiente forma:
Comprobamos que en ese caso Agatha se ha suicidado, y que la lista de asesinos no coincide con los resultados esperados. Charles ha sido eliminado de la lista de sospechosos porque no cumple la restricción de que el asesino siempre odia, es decir, odia a algún habitante de la mansión.
En lugar de suponer que Charles no odia a nadie vamos a meter otra restricción, y es la propia definición de asesinato, porque es eso lo que se ha producido en la mansión Dreadsbury, un asesinato. Una de las características que tienen los sistemas BRMS es poder cambiar las lógicas de decisión de una forma ágil, y como podemos ver en este ejemplo, en un lenguaje natural cercano al usuario. Creamos la siguiente regla:
- #Rule: It is not a suicide
La insertamos en el Rule Task de restricciones del asesino, de forma que el proyecto de reglas queda de la forma:
Modificamos la lista de resultados esperados eliminado a Agatha:
Al insertar esta restricción, vemos que Agatha ha sido eliminada de la lista de asesinos y únicamente nos aparece Charles.
Ya tenemos resuelto el misterio… Charles es el asesino.
____________________________________________________
El grupo de LinkedIn The Decision Model nos ha dicho que la solución no es correcta, y nos ha aclarado una de las restricciones del asesino. La frase del enunciado dice:
‘A killer always hates, and is no richer than his victim.’ Con esta frase, entendimos que el asesino siempre odia, a alguien, no necesariamente a la víctima, y además no es más rico que la víctima. Pues bien, esto no es así. Con esa frase lo que se se quiere decir es que el asesino siempre odia a su victima y no es más rico que su víctima.
Este es otro de los problemas más comunes cuando las especificaciones no son lo suficientemente concisas. Sin embargo, nos va a servir de ejemplo para ver cómo con un sistema BRMS es muy fácil cambiar las lógicas de decisión de una forma ágil.
Los pasos a seguir son:
- Desde Decision Center, eliminamos la regla #It is not a suicide. En el #RuleTask-ResolutionOfTheMistery nos quedan únicamente las Reglas #A killer always hates y #The killer is no richer than his victim.
- Desde Decision Center, modificamos la regla #A killer always hates conforme a la nueva definición.
Una de las nuevas utilidades de Decision Center, es poder comparar versiones de reglas. Si hacemos la comparación de esta regla con la versión anterior, vemos como se ha modificado conforme a las nuevas especificaciones:
- Modificamos la salida esperada de la Excel de pruebas con los resultados esperados y subimos el fichero a Decision Center.
- Desde Decision Center, ejecutamos el nuevo escenario de pruebas.
Vemos como el resultado ha cambiado completamente. No se ha producido un asesinato, Agatha se ha suicidado.
¿Te ha interesado? ¿Quieres conocer más sobre BRMS o plataformas para la toma de decisiones inteligentes como IBM ODM? No dudes en contactar con nosotros. También puedes seguirnos en las redes sociales (Linkedin, Twitter, Youtube).