【问题标题】:Constraint Values on Local Variable局部变量的约束值
【发布时间】:2014-12-31 05:32:27
【问题描述】:

我目前正在使用 :- 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.

这个解决方案似乎是正确的,但我没有 task(t2, _G66, 10, c1) 的任何具体值(任务编号、开始时间、持续时间、处理器内核)。

据我所知,这是一个局部变量,其值应介于 25<_g66 prolog>

编辑:

添加了更多代码以显示问题所在。在其他地方不会产生其他故障。 bestsofar/2 用于存储当前最佳调度方案和执行时间。当我们找到更好、更快的时间表时,我们会使用update_time/2 替换它。这种搜索总是会失败,这样所有可能的解决方案都会被测试。完成后,我们到达 bestsofar(BestSchedule,BestTotTime) 并返回这些值。

如果我在返回结果之前查看调试器。B=35-A 确实支持我对 35&lt;B&lt;5060&lt;B&lt;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

【问题讨论】:

  • 您需要添加更多细节,bestsofar/2 到底是什么。无论如何,这些使用副作用的“手写”优化总是有点棘手。我怀疑该变量的约束在失败时会以某种方式丢失(这是肯定的),并且从未在bestsofar/2 中重新发布
  • @false 添加了很多信息,还使用调试器跟踪了我的问题的约束。希望这有助于发现问题。对我来说,似乎没有任何限制。

标签: prolog clpq


【解决方案1】:

经过一番搜索,我发现了问题。该代码能够从一开始就生成正确的时间表。问题是,如果需要minimize(TotTime)

,则仅将任务的“开始时间”最小化

因此,如果某项任务对关键路径不重要,则解决方案中没有定义开始时间。这可以通过遍历结果并最小化每个 StartTime 来解决

minimize_schedule([]).
minimize_schedule([task(_,Start,_,_)|Rest]) :-
    minimize(Start), 
    minimize_schedule(Rest).

【讨论】:

  • 非常好,+1。您可以看到优化谓词仅优化目标函数,但不一定将所有涉及的变量绑定到基本值,例如:?- { X =&lt; 0, Y =&lt; 1, Y &gt;= 0, Expr = X+Y-Y }, maximize(Expr).,产生:Expr = X, X = 0,但没有具体绑定 Y
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多