Расписание заданий sicstus prolog

Я недавно начал sicstus prolog и мне нужно решить эту домашнюю работу с помощью CLP (программирование логики ограничений), пожалуйста, помогите мне понять проблему, что я должен искать и что я делаю не так. Так,

Строительная компания:

  • Чтобы получить сырье, БК должен арендовать грузовик, который перевозит 25 тонн сырья за 6 дней и стоит 80 долларов в день.
  • Чтобы построить над землей необходимо 15 тонн сырья, это займет 10 дней и стоит 150 долларов за этаж.
  • Для строительства под землей требуется 20 тонн сырья, это занимает 23 дня (из-за земляных работ), стоит 150 долларов и требуется как минимум одна землеройная машина, которая добавляет 75 долларов в день и сокращает время земляных работ на 3 дня (две машины макс. время). (1-> 20 дней, 2-> 17 дней)
  • Если кран арендуется, время постройки сокращается на 25% и стоит 120 долларов в день.
  • Бригада электриков сможет продвигаться вперед только тогда, когда будет построено 75% здания, это займет 5 дней и стоит 200 долларов за этаж. А когда строительство будет завершено, понадобится еще одна неделя, чтобы завершить соединения всех этажей.

BC претендует на строительство небоскребов со 150 надземными этажами и 15 под землей, как должно быть организовано здание так, чтобы прибыль была максимальной, а необходимое время минимизировано?

Определите проблему как проблему удовлетворения ограничений и решите ее с помощью CLP, чтобы можно было решить ее с различными параметрами (больше или меньше этажей или корректировка времени команд).

И что у меня есть на данный момент:

:- use_module(library(clpfd)).

start(Fdigs,Floors,Vars):-
    length(Vars,5),

    %S -> start, E -> end, D -> duration
    %t -> transport, e -> excavating, f -> floor (build)

    Vars=[St,Et,Se,Ee,Cost],

    Se #>= Et,
    Ee #= Se + 10,
    Et #>=6,
    Cost #>= Ee * 80,  %transport cost since it starts at 0 Ee will be the days needed

    domain(Vars,0,2000),
    construct(0,Fdigs,Floors,Vars),
    labeling([minimize(Cost)],Vars).

construct(Stock,0,Floors,Vars).

construct(Stock,Fdigs,Floors,[St,Et,Se,Ee,Cost]):-
    Tasks=[
    task(St,6,Et,0,1),  %transport task
        task(Se,10,Ee,5,2)  %dig task, 5 because I'm digging all then building (20-15)
                %10 because build is 10 so dig is 10
    ],
    cumulative(Tasks,[limit(Stock)]),
    Nfdigs is Fdigs - 1,
    Nstock is Stock + 25,
    construct(Nstock,Nfdigs,[Et,_Et,Ee,_Ee,Cost]).

И это, конечно, не работает, потому что я не могу использовать кумулятивную с задачей, требующей 5 ресурсов, а ограничение в 0 ресурсов - первая из многих проблем, которые я не могу обойти ...


person Vitor Mota    schedule 07.12.2012    source источник
comment
это кумулятивно требуется вообще? Почему бы не указать общую стоимость при других условиях и не минимизировать?   -  person CapelliC    schedule 08.12.2012
comment
Это не имеет особого смысла, поскольку доступные ресурсы постоянно меняются, и ему нужен другой предикат, чтобы оценить, какую задачу объявлять в совокупности ... Итак, я уже начал решать ее с условиями и не использовать ничего из этого дерьма. Я пытался использовать кумулятивную систему, потому что мой учитель предложил, но я не думаю, что он решил эту проблему.   -  person Vitor Mota    schedule 08.12.2012


Ответы (1)


Вот то, что я придумал до сих пор, кажется, намного проще и дает мне ожидаемый результат:

:- use_module(library(clpfd)).

start(Floors,Fdigs,Vars):-
    length(Vars,20),
    domain(Vars,0,999999999),   %all vars must be bounded
    Vars=[                      % S-start,D-duration,E-end,C-cost (money)
    St,Dt,Et,Ct,                % transport vars
    Se,De,Ee,Ce,                % excavation vars
    Sb,Db,Eb,Cb,                % building vars
    Sc,Dc,Ec,Cc,                % electricity vars
    Machines,Crane,Cost,Time],
    Machines in 1..2,
    Crane in 0..1,
    St is 0,
    Dt is ceiling(((Floors*15)+(Fdigs*20))/25)*6,
    Et is Dt,
    Ct is 80 * Dt,
    Se is 0,
    De #= (13 - (Machines*3)) * Fdigs,
    Ee #= De,
    Ce #= De * (75*Machines),
    Sb #>=6 #/\ Sb #>= Ee,
    Db #= ((Fdigs * (10-(Crane*3))) + (Floors * (10-(Crane*3)))),
    Eb #= Sb + Db,
    Cb #= (Fdigs + Floors) * 150 + (Crane*Db*120),
    Sc #= (Eb * 75 / 100),
    Dc #>= (Eb * 25 / 100) + 5 #/\ Dc #=((Floors + Fdigs) * 5) + 5,
    Ec #= Sc + Dc #/\ Ec #> Eb,
    Cc is (Fdigs + Floors) * 200,

    %Costs
    Cost #= (Ct + Ce + Cb + Cc),

    %Times (will be end time of final & nonoverlaping task)
    Time #= Ec,

    %labeling([minimize(Cost)],Vars),       % - cost, + time
    labeling([maximize(Cost)],Vars),        % + cost, - time
    writeVars(Vars).

writeVars([St,Dt,Et,Ct,Se,De,Ee,Ce,Sb,Db,Eb,Cb,Sc,Dc,Ec,Cc,Machines,Crane,Cost,Time]):-
    write('1 '),write(St),write(' '),write(Dt),write(' '),write(Et),write(' '),write(Ct),write('\n'),
    write('2 '),write(Se),write(' '),write(De),write(' '),write(Ee),write(' '),write(Ce),write('\n'),
    write('3 '),write(Sb),write(' '),write(Db),write(' '),write(Eb),write(' '),write(Cb),write('\n'),
    write('4 '),write(Sc),write(' '),write(Dc),write(' '),write(Ec),write(' '),write(Cc),write('\n'),
    write('Cost: '),write(Cost),write('\n'),
    write('Time: '),write(Time),write('\n'),
    write('Crane: '),write(Crane),write('\n'),
    write('Machines: '),write(Machines).
    %write('4 ',St,' ', Dt,' ', Et,' ', Ct),
    %write('5 ',St,' ', Dt,' ', Et,' ', Ct).

Любые предложения, комментарии, улучшающие мой ответ, очень приветствуются.

person Vitor Mota    schedule 08.12.2012
comment
Рассмотрите возможность использования формата / 2 вместо большого количества вызовов записи / 1. Например: format("1 ~w ~w ~w ~w\n", [St,Dt,Et,Ct]) и format("Cost ~w\n", [Cost]). - person mat; 08.12.2012
comment
Подумайте о том, чтобы отделить фактическую маркировку от основного предиката, таким образом вы можете одновременно опробовать альтернативные стратегии маркировки. - person false; 10.12.2012
comment
Спасибо mat и false, я выполню оба предложения по окончательной доставке. знак равно - person Vitor Mota; 10.12.2012