2010-01-28 1 views
4

J'ai mis en place (enfin) quelques objectifs qui vont planifier une série de tâches selon un startBy startAfter et durée. L'objectif du planning n'accepte cependant que le nombre de tâches prescrit. Je souhaite étendre la fonctionnalité de l'objectif de planification pour accepter une liste unique et parcourir cette liste lors de la planification.Extension d'un objectif Prolog par récursivité?

malheureusement je pense que cela va exiger plutôt différents objectifs que l'peut exécuter et conflits buts indiqués ci-dessous.

MISE À JOUR: En arrivant à proximité ... can_run/3 renvoie vrai si l'une des paires RT, TT ne se contrarie pas ... ce qui n'est décidément pas ce que je veux, mais je suis proche ... si quelqu'un peut Dites-moi comment éviter cela (peut-être en utilisant l'opérateur!). Ce serait merveilleux.

MISE À JOUR: Eet werkz! Maintenant pour le nettoyage des solutions imparfaites superflues (ne pas programmer une tâche) et les permutations de solution (a, b, c et a, c, b et b, a, c et b, c, a etc ...)

MISE À JOUR: Bah .. d'accord, donc ça ne fonctionne pas ... pour tout ce qui a duré 1 ... mutter mutter Aussi ... il semble que ce soit plutôt un traitement intensif

MISE À JOUR (final) : Nous avons travaillé et implémenté une heuristique "la plus petite fenêtre d'abord" pour améliorer le temps de traitement ... nous avons encore des problèmes à retourner rapidement faux pour les plannings qui ne peuvent pas être résolus, mais trouver une solution arrive assez rapidement.

Voici ce que j'ai jusqu'à présent:

can_run(R,T) :- startAfter(R,TA),startBy(R,TB),between(TA,TB,T). 

conflicts(R,T,RTs) :- duration(R,D),member([RT,TT],RTs),R=\=RT,duration(RT,DT),T<DT+TT,T+D>TT. 

schedule :- findall(R,request(R),Rs),predsort(windowCompare,Rs,Rtn),schedule(Rtn,[]). 

windowCompare(D,R1,R2) :- startAfter(R1,SA1),startBy(R1,SB1),W1=SB1-SA1, 
          startAfter(R2,SA2),startBy(R2,SB2),W2=SB2-SA2, 
          W1>W2->D='>';D='<'. 

schedule(Rs,RTs) :- Rs==[]; 
        (
        member(R,Rs),select(R,Rs,Rst), 
        can_run(R,T),\+conflicts(R,T,RTs), 
        append(RTs,[[R,T]],RTN),schedule(Rst,RTN), 
        writef('%t @ %t\n',[R,T]) 
        ). 

request(1). 
request(2). 
request(3). 
request(4). 
request(5). 
request(6). 
request(7). 
request(8). 
request(9). 

startAfter(1,0). 
startAfter(2,0). 
startAfter(3,0). 
startAfter(4,0). 
startAfter(5,0). 
startAfter(6,0). 
startAfter(7,0). 
startAfter(8,0). 
startAfter(9,0). 

startBy(1,20). 
startBy(2,40). 
startBy(3,15). 
startBy(4,5). 
startBy(5,0). 
startBy(6,35). 
startBy(7,30). 
startBy(8,10). 
startBy(9,25). 

duration(1,5). 
duration(2,5). 
duration(3,5). 
duration(4,5). 
duration(5,5). 
duration(6,5). 
duration(7,5). 
duration(8,5). 
duration(9,5). 

Je pense que je peux avoir besoin de maintenir une structure persistante que chaque itération des mises à jour ...

Répondre

2

Si ce que vous voulez est pour can_run (R, T, Rts) à l'échec si l'une des paires dans les conflits de la liste, puis la clause finale dans votre sous-jacentes devraient être

\+ (member([RT,TT], RTs), conflicts(T, RT,TT)) 

Je ne connais pas le entre/3 prédicat, mais il est important que l'effec t de la solution entre (TA, TB, T) consiste à lier T à une valeur fondamentale avant l'appel à + (...)

+0

excellent! J'ai encore un comportement délicat (montre toutes les permutations du même scénario d'ordonnancement ... c'est-à-dire: 1 @ 0, 2 @ 2, 3 @ 1 (en supposant des faits mis à jour) merci! –