搜索启发式累积量

时间:2014-08-06 21:52:38

标签: prolog constraint-programming clpfd sicstus-prolog

我已经通过其他几个问题(Use of cumulativesExpressing setup time with cumulatives)获得了关于cumulatives使用的出色反馈,以及如何帮助搜索达到最佳解决方案。

然而,在这些问题中,我只使用了简化的玩具示例。

当我转向更大的问题时,我仍然很难达到最佳解决方案。

简而言之,我有一些任务可以在一组给定的机器上进行安排:

  • 每项任务的随机持续时间为1-1000
  • 大约20%的任务可以使用全局资源,这意味着不能同时安排使用相同资源的其他任务。
  • 大约20%的任务无法在所有可用计算机上执行。

例如:

  Task| Dur  | Exe on   | Resources
------+------+----------+----------
  t1  | 318  |   All    |          
  t2  | 246  |   All    |          
  t3  | 797  |  m4 m3   |          
  t4  | 238  |  m2 m3   | r1 r2 r3  
  t5  | 251  |   m1     |          
  t6  | 279  |   All    |          
  t7  | 987  | m2 m5 m1 |    r1    
  t8  | 847  |   All    |          
  t9  | 426  |   All    |          
  t10 | 787  |   All    |          
  t11 |   6  |   All    |          
  t12 | 681  |   All    |          
  t13 | 465  |   All    |          
  t14 |  46  |   All    |          
  t15 |   3  |   All    | r1 r3 r2  
  t16 | 427  |   All    | r3 r2    
  t17 | 956  |   All    | r3       
  t18 | 657  |   All    |          
  t19 | 113  |   All    |          
  t20 | 251  |   All    | r3 r2    

在这个小例子中,我们在5台机器上安排了20个任务。 t4,t7,t15使用资源r1即使它们被安排在不同的机器上也不能同时执行。 t4,t15,t16,t20使用r2等 t3只能在m3和m4上运行,t4只能在m2和m3等上运行。

这里给出了一个完整的模型:

:- use_module(library(clpfd)).
:- use_module(library(lists)).


s1(Ss, Es, Ms, Maxspan, Timeout ) :-
    Ss = [S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11,S12,S13,S14,S15,S16,S17,S18,S19,S20],
    Es = [E1,E2,E3,E4,E5,E6,E7,E8,E9,E10,E11,E12,E13,E14,E15,E16,E17,E18,E19,E20],
    Ms = [M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16,M17,M18,M19,M20],
    Ds = [318, 246, 797, 238, 251, 279, 987, 847, 426, 787,6, 681,465,46, 3, 427,956,657,113,251],
    Ds = [D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15,D16,D17,D18,D19,D20],

    domain(Ss, 1, 10000),
    domain(Es, 1, 10000),
    domain(Ms, 1, 5),

    %task( StartTime, Duration, EndTime, ResourceCons, MachineId)
    Tasks = [
        task( S1,  D1, E1, 1, M1),
        task( S2,  D2, E2, 1, M2),
        task( S3,  D3, E3, 1, M3),
        task( S4,  D4, E4, 1, M4),
        task( S5,  D5, E5, 1, M5),
        task( S6,  D6, E6, 1, M6),
        task( S7,  D7, E7, 1, M7),
        task( S8,  D8, E8, 1, M8),
        task( S9,  D9, E9, 1, M9),
        task(S10, D10,E10, 1,M10),
        task(S11, D11,E11, 1,M11),
        task(S12, D12,E12, 1,M12),
        task(S13, D13,E13, 1,M13),
        task(S14, D14,E14, 1,M14),
        task(S15, D15,E15, 1,M15),
        task(S16, D16,E16, 1,M16),
        task(S17, D17,E17, 1,M17),
        task(S18, D18,E18, 1,M18),
        task(S19, D19,E19, 1,M19),
        task(S20, D20,E20, 1,M20)
    ],

    %machine( Id, ResourceBound ),
    Machines = [
        machine( 1, 1),
        machine( 2, 1),
        machine( 3, 1),
        machine( 4, 1),
        machine( 5, 1)
    ],

    %Set up constraints where task can only run on spesific machines:
    %t3  can only run on m3 and m4
    %t4  can only run on m2 and m3
    %t5  can only run on m1
    %t7  can only run on m1, m2 and m5
    %all other can run on any machine
    list_to_fdset( [3,4],  T3RunOn ), 
    list_to_fdset( [2,3],  T4RunOn ), 
    list_to_fdset( [1],    T5RunOn ), 
    list_to_fdset( [1,2,5],T7RunOn ), 
    M3 in_set T3RunOn,
    M4 in_set T4RunOn,
    M5 in_set T5RunOn,
    M7 in_set T7RunOn,

    %Set up constraints of tasks using global resources:
    %t4  use r1,r2,r3
    %t7  use r1
    %t15 use r1,r2,r3
    %t16 use r2,r3
    %t17 use r3
    %t20 use r2,r3

    %r1:
    cumulative( 
        [   
            task(  S4, D4, E4,1,4),
            task(  S7, D7, E7,1,7),
            task( S15,D15,E15,1,15)

        ],
        [limit(1)]),

    %%r2:
    cumulative( 
        [   
            task(  S4, D4, E4,1,4),
            task( S15,D15,E15,1,15),
            task( S20,D20,E20,1,20)
        ],
        [limit(1)]),

    %r3:
    cumulative( 
        [   
            task(  S4, D4, E4,1,4),
            task( S15,D15,E15,1,15),
            task( S16,D16,E16,1,16),
            task( S17,D17,E17,1,17),
            task( S20,D20,E20,1,20)
        ],
        [limit(1)]),


    maximum( Maxspan, Es ),

    cumulatives(Tasks, Machines, [bound(upper), task_intervals(true)] ),

    %Plain order (M1,M2,...M20)
    %MOrder=Ms,
    %Order by task using many resources first, then task only runnon on some machines, then rest
    MOrder=[M4, M15, M16, M20, M7, M17, M5, M3, M10, M1, M2, M6, M8, M9, M11, M12, M13, M14, M18, M19],

    %Order by duration
    %MOrder=[M15, M11, M14, M19, M4, M2, M20, M5, M6, M1, M9, M16, M13, M18, M12, M10, M3, M8, M17, M7],

    %This order (discovered my misstake) gives optimal sollution in less then a second:
    %MOrder=[M4, M15, M20, M16, M17, M5, M3, M7, M10, M1, M2, M6, M8, M9, M11, M12, M13, M14, M18, M19],

    append([MOrder, Ss ], Vars),
    labeling([ minimize(Maxspan), time_out( Timeout, _LabelingResult) ], Vars). 

到目前为止,我最好的启发式方法是按以下顺序订购MachineId变量: 首先使用许多资源执行任务,然后通过任务仅在某台计算机上执行,然后执行其余任务。

| ?- s1(Ss, Es, Ms, Maxspan, 5000 ).                                                                                       
Ss = [1,319,1,1635,1635,798,565,1,848,1077,1552,1,1274,1558,1886,1,428,682,1739,1384],
Es = [319,565,798,1873,1886,1077,1552,848,1274,1864,1558,682,1739,1604,1889,428,1384,1339,1852,1635],
Ms = [2,2,3,2,1,3,2,4,4,3,2,5,4,2,1,1,1,5,4,1],
Maxspan = 1889 ? 

有关更好的搜索启发式和/或对称性破坏的任何建议可以表现得更好吗?

0 个答案:

没有答案