Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PROBLEME PROPAGATION INITIALE #28

Closed
jgFages opened this issue Dec 20, 2011 · 4 comments
Closed

PROBLEME PROPAGATION INITIALE #28

jgFages opened this issue Dec 20, 2011 · 4 comments

Comments

@jgFages
Copy link
Contributor

jgFages commented Dec 20, 2011

Bonjour,

j'ai un gros soucis avec la propagation initiale de deux propagateurs A et B:

supposons que dès la pose de mon modèle, certaines de mes variables soient instanciées, elles ne vont pas générer d'INSTANTIATION EVENT, juste?
Du coup pour les traiter dans le propagateur B je dois itérer sur mes variables instanciées durant la propagation initiale de B.
Malheureusement j'ai propagé A avant B et la propagation initiale de A a générée de nouvelles variables instanciées, lesquelles vont à la fois apparaître dans la propagation initiale de B et dans les "requests" de B...??!!
Du coup je fais le boulot 2 fois et ça ne va pas du tout.
Il me semblerait qu'un propagateur ne devrait se réveiller qu'aux évènements qui sont postérieurs à sa propagation initiale, non?
Si c'est sensé déjà être le cas alors il me semble (je peux me tromper) que ça a été récemment cassé.
Sinon, ... pour quelles raisons n'est-ce pas ainsi?

Merci bien et bonne vacances!

@jgFages
Copy link
Contributor Author

jgFages commented Dec 21, 2011

Plus précisément :

Le delta de mon ArcEventRecorder contient les valeurs déjà traitées dans la propagation initiale
Autrement dit, le CoarseEventRecorder à mal informé l'ArcEventRecorder que ces valeurs avaient déjà été traitées

Ce problème concerne à coup sûr les Variables Graphes mais comme la machinerie des Recorder est la même (en gros seuls le DeltaMonitor change) il est possible que ce problème touche aussi les IntVar

Ceci se produit donc lorsque

  1. Le propagateur est incrémental
  2. Les domaines sont tels que la propagation initiale fait quelque chose

Charles, tu me manques!

@jgFages
Copy link
Contributor Author

jgFages commented Dec 21, 2011

Chers amis,

je vais poursuivre mon monologue avec un exemple simple :
J'ai une variable x={1,2,3} et deux propagateurs unaires P1 et P2 liés à x
P1 est un propagateur qui supprime des valeurs selon une table et P2 sert à maintenir le nombre NB de valeurs
dans le domaine de x. Je note Pi la propagation initiale et Pf une propagation fine

Propagation initiale de P1
Pi(P1) : on supprime la valeur 3
-> On schedule une requête liée au fait que x ait perdu la valeur 3
Propagation initiale de P2, on compte le nombre de valeurs dans le domaine de x
Pi(P2) : x = {1,2} donc NB = 2
Propagation fine on décrémente NB du nombre de valeurs retirées de x
Pf(P2,var=x, delta={3}) : NB = NB-1

=> NB=1 alors que x={1,2}
=> Ca fait n'importe quoi

Je n'ai pas encore codé cet exemple mais d'après ce que j'ai vu dans le code je pense qu'il y a réellement un
problème dans Galak y compris pour les variables entières. En tout cas ce bug se produit pour les variables graphes.

J'en revient donc à ce que j'ai dit précédemment : "un propagateur ne devrait se réveiller qu'aux évènements qui sont postérieurs à sa propagation initiale"

@jgFages
Copy link
Contributor Author

jgFages commented Dec 21, 2011

J'ai pour le moment un moyen de résoudre le problème mais il n'est pas encore très satisfaisant :

j'introduit une nouvelle méthode "initialPropagation()" dans l'interface IDeltaMonitor
qui est implémentée comme suit:

@OverRide //(IntDelta)
public void initialPropagation() {
first = delta.size();
}

@OverRide //(GraphDelta)
public void initialPropagation() {
first[NR] = delta.getNodeRemovalDelta().size();
first[NE] = delta.getNodeEnforcingDelta().size();
first[AR] = delta.getArcRemovalDelta().size();
first[AE] = delta.getArcEnforcingDelta().size();
}

Au début de chaque propagation initiale d'un propagateur Pi, on applique cette méthode sur tous les FineEventRecorders de Pi.
=> Vous voyez l'idée? Lorsqu'on exécutera la request, on iterera sur les valeurs du delta qui sont postérieures à la propagation initiale de Pi.
=> C'est simple et performant mais ça nécessite de modifier le coarseEventRecorder comme suit:
@OverRide
public boolean execute() throws ContradictionException {
if (!propagator.isActive()) {
evtmask |= EventType.FULL_PROPAGATION.strengthened_mask;
propagator.setActive();
}
if (evtmask > 0) {
propagator.coarseERcalls++;
int _evt = evtmask;
evtmask = 0;
// DEBUT MODIF JG
int nbR = propagator.nbRecorders();
IEventRecorder rec;
for(int i=0;i<nbR;i++){
rec = propagator.getRecorder(i);
if(rec instanceof AbstractFineEventRecorder){
for(Variable v:rec.getVariables()){
((AbstractFineEventRecorder) rec).getDeltaMonitor(v).initialPropagation();
}
}
}
// FIN MODIFS JG
propagator.propagate(_evt);
}
return true;
}

Par contre ça ne fonctionne pas tel quel car le "clear()" des deltas des "requêtes" est fait de manière LAZY et uniquement une fois la propagation initiale finie (tant que la propagation initiale n'est pas faite le propagateur n'est pas actif). Donc on remet à 0 l'index "first". Pour le moment ma rustine consiste à ajouter un "if(firstClear())" dans la méthode clear() ce qui n'est pas terrible mais mieux que rien. Mais je pense qu'on pourrait modifier la gestion des clear(). De toutes façons, à termes je rebasculerai sur un clear NON LAZY.

@jgFages
Copy link
Contributor Author

jgFages commented Jan 21, 2012

Problème résolu

  • unfreeze après chaque exécution de FineEvent
  • vitrualize après chaque exécution de CoarseEvent
    -Gestion LAZY et non LAZY correcte sur tout type de variable

Reste le problème de la gestion des vues à domaines qui est discutée dans une autre issue

@jgFages jgFages closed this as completed Jan 21, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant