es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obtener identificadores de entidades que violan restricciones.

Mi problema es programar citas en un calendario de N días. Soy consciente de que para algunos casos realmente desfavorables, nunca encontraré una solución sin violar las restricciones.
Lo que me gustaría hacer es ejecutar el solucionador en el problema, obtener las citas que violen las restricciones principales, eliminarlas de la solución y volver a ejecutar el solucionador con esas citas en un calendario de los siguientes N días (es decir, volver a programarlas).
¿Existe alguna manera de obtener los identificadores de las citas que violan las restricciones y eliminarlas de la solución en Java? Leí la documentación pero no encontré nada.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Como experto en IT especializado en Java y OptaPlanner, hay una posible solución para tu problema. OptaPlanner proporciona APIs para acceder a las violaciones de restricciones en la solución. Puedes implementar un calculador de puntuación personalizado que extienda HardSoftScoreCalculator, lo que te permitirá acceder a las coincidencias de restricciones y examinarlas. Una vez que hayas identificado las citas que violan las restricciones, puedes eliminarlas de la solución mediante la actualización de los objetos de dominio y la re-ejecución del solucionador.

    Para eliminar las citas que violan las restricciones de la solución en Java, puedes seguir estos pasos:

    1. Implementa un calculador de puntuación que exponga las violaciones de restricciones. Aquí tienes un ejemplo de código:
    public class MyScoreCalculator extends HardSoftScoreCalculator<mysolution> {
    
        @Override
        public HardSoftScore calculateScore(MySolution solution) {
            int hardScore = 0;
            int softScore = 0;
    
            for (ConstraintMatchTotal matchTotal : getConstraintMatchTotals()) {
                // Check if the constraint is hard
                if (matchTotal.getWeight().isHard()) {
                    hardScore += matchTotal.getScore();
                    // Get the set of violated facts
                    Set<object> violatingFacts = matchTotal.getConstraintMatchSet().getFacts();
                    for (Object fact : violatingFacts) {
                        if (fact instanceof Appointment) {
                            Appointment appointment = (Appointment) fact;
                            // Add your code here to remove the violating appointment
                        }
                    }
                }
                // Soft constraints can be ignored.
            }
    
            return HardSoftScore.of(hardScore, softScore);
        }
    }
    
    1. Crea y configura el solucionador con tu calculador de puntuación personalizado:
    SolverFactory<mysolution> solverFactory = SolverFactory.createFromXmlResource("mySolverConfig.xml");
    Solver<mysolution> solver = solverFactory.buildSolver();
    
    MySolution problem = ... // Create your problem instance
    
    MyScoreCalculator scoreCalculator = new MyScoreCalculator();
    solver.setScoreDirectorFactory(new DroolsScoreDirectorFactory()); // Or another factory that works for your setup
    solver.setScoreCalculator(scoreCalculator);
    
    solver.solve(problem);
    
    1. Actualiza el método removeViolatingAppointment() para eliminar la cita que viola las restricciones de la solución. Puedes utilizar la API de OptaPlanner para actualizar los hechos en el director de puntuación. Aquí tienes un ejemplo de código:
    private void removeViolatingAppointment(Appointment appointment, ScoreDirector<mysolution> scoreDirector) {
        // Retrieve the fact handle of the appointment
        FactHandle handle = scoreDirector.getFactHandle(appointment);
    
        // Revoke the fact handle from the working memory to remove it from the solution
        scoreDirector.retract(handle);
    
        // Update the score and constraint matches
        scoreDirector.triggerVariableListeners();
    }
    

    Ten en cuenta que este ejemplo supone que la clase Appointment es un hecho en tu modelo de dominio. Si no lo es, es posible que necesites utilizar una forma diferente de identificar la cita que viola las restricciones.

    Con estos cambios, deberías ser capaz de identificar y eliminar las citas que violan las restricciones de la solución, y luego volver a resolver el problema con el horario actualizado.

Comments are closed.