Значения ограничений на локальной переменной

В настоящее время я работаю над проблемой планирования с использованием библиотеки:- use_module(library(clpq)). Моя проблема заключается в поиске полного решения моей постановки проблемы.

schedule(BestSchedule, BestTotTime) :-          %BestSchedule of format [test(task,startTime,Duration Task, Core]
    (  findall(T,task(T),Tasks),
       findall(C,core(C),Cores),
       init_time,                               %Retract all facts of bestsofar(_,_)
       const_time(Tasks,Schedule,Cores,TotTime),%Here probably goes something wrong
       assign_processor(Schedule,Cores, TotTime),
       minimize(TotTime),
       update_time(Schedule, TotTime),  
       fail
    ;  bestsofar(BestSchedule,BestTotTime)
    ).

assign_processor([], _, _).  
assign_processor([task(T,S,D,C)|Rest], Cores, TotTime) :-
    assign_processor(Rest,Cores,TotTime),
    core(C),                            %Pick a core
    process_cost(T,C,D),                %Core/Task known, setting Duration (D)
    const_resource(task(T,S,D,C),Rest), %Setting extra constraints on chosen core 
    bestsofar(_,CurrentBestTime),       %Get current best time from fact bestsofar
    {TotTime < CurrentBestTime}.        %Set new constraint based on currentBestTime


const_resource(_,[]).
const_resource(Task,[Task2|Rest]) :- 
    no_data(Task,Task2),
    no_conflict(Task,Task2),            %No overlap on same processor
    const_resource(Task, Rest).         

no_conflict(task(_,S,D,C),task(_,S2,D2,C2)) :-
    C \== C2,!;                         %Tasks not on same processor
    { S+D =< S2;                        %Set no overlapping start/end times
     S2+D2 =< S }.  

no_data(task(T,S,D,C), task(T2,S2,D2,C2)) :-
         %depends_on(T,T2,_) = T2 needs to be finished before T can start
         %channel(C,C2,L,_) = Data transfer between cores generated latency L
         %Set no overlap including the latency if tasks are dependent
    depends_on(T,T2,_),channel(C,C2,L,_),!, { S2 + D2  =< S - L };
    depends_on(T2,T,_),!,channel(C2,C,L,_),!, { S + D   =< S2 - L};
    true.

init_time :-
    retract(bestsofar(_,_)), fail
    ;
    assert(bestsofar(foobar, 1000)).

update_time(Schedule,TotTime) :-
    retract(bestsofar(_,_)),!,
    assert(bestsofar(Schedule,TotTime)).

S = [task(t7, 100, 10, c1), task(t1, 0, 10, c1), task(t6, 75, 10, c1),
     task(t2, _G66, 10, c1), task(t4, 50, 10, c2), task(t3, 25, 10, c1),
     task(t5, 50, 10, c1)],
ET = 110.

Это решение кажется правильным, но у меня нет конкретного значения задачи (t2, _G66, 10, c1) (номер задачи, время запуска, продолжительность, ядро ​​процессора).

Насколько мне известно, это локальная переменная, значения которой должны быть между 25<_G66 <35 ИЛИ 60 <_G66 <75, но я не могу найти способ распечатать эти значения в самом Прологе. Я думал, что при минимизации (TotTime) все переменные будут минимизированы, что, кажется, происходит с остальными.

Редактировать:

Добавлен еще один код, чтобы показать, где проблема должна лежать. Никаких других сбоев не возникает где-то еще. bestsofar/2 используется для хранения текущего лучшего графика решения и времени выполнения. Когда мы находим лучший, более быстрый график, мы заменяем его, используя update_time/2, Этот поиск всегда будет неудачным, таким образом проверяются все возможные решения. Когда мы закончим, мы достигнем bestsofar(BestSchedule,BestTotTime) и вернуть эти значения.

Если я посмотрю на отладчик, прежде чем вернуть результат.B=35-A который поддерживает мой ручной тест 35<B<50 или же 60<B<75, Я не могу сделать вывод сам, потому что я не знаю, как интерпретировать _ Значение в этих ограничениях.

[ task(t7,100,10,c1),
  task(t1,0,10,c1),
  task(t6,75,10,c1),
  task(t2,B,10,c1),
  task(t4,50,10,c2),
  task(t3,25,10,c1),
  task(t5,50,10,c1)
], % with constraints
    {}(_ = -55 - A ',' _ = -40 - A ',' _ = -25 + A ',' _ = -10 + A ',' _ = -30 - A ',' _ = -5 - A ',' A >= -5 ',' A =< 0 ',' _ = -55 - A ',' _ = -25 + A ',' _ = 65 + A ',' B = 35 - A)

Без no_data/2 Мой код работает для примеров, где не используется задержка канала. Поэтому я думаю, что любая проблема должна лежать в этом куске кода.

Запускаемый код, если интересно: http://pastebin.com/3PmRu7Aq

1 ответ

Решение

После некоторых поисков я нашел проблему. Код был в состоянии сгенерировать правильное расписание с самого начала. Проблема заключалась в том, что только начальные "времена начала" задач были сведены к минимуму, если их нужно было minimize(TotTime)

Поэтому, если определенная задача не была критической для критического пути, время запуска не было определено в решении. Это было решено путем итерации по результату и минимизации каждого StartTime

minimize_schedule([]).
minimize_schedule([task(_,Start,_,_)|Rest]) :-
    minimize(Start), 
    minimize_schedule(Rest).
Другие вопросы по тегам