介意帮助Prolog编程?

时间:2012-12-21 02:25:23

标签: prolog

行。这是我第二次发布这个问题,上次我的问题被很少的管理员关闭,因为他们说“我没有做足够的努力来解决它”所以现在我解决了大约70%的问题。我希望这次有人可以给我一个完整代码的答案。

这个问题是作为(Prolog语言程序设计)的作业给我的。

  1. 工作分配。 N个工作将使用N台不同的机器完成。使用成本 机器我做的工作j在下表中给出。

                   1  2  3  4
                  ____________
                1| 6  5  3  6
                2| 5  6  8  12
                3| 8  6  8  9
                4| 3  6  5  8
    
  2. \\上层(1 2 3 4)属于(作业)类别

    \\左侧(1 2 3 4)属于(机器)类别

    编写声明性Prolog程序以确定应将哪些作业分配给哪些作业 机器,以尽量减少总成本。

    我做的第一步是从(作业)的第一个垂直线中选取最低值,并在同一行(3-8),(3-6),(3-6)中的所有其余数字上减去它( 3 - 5)......等等垂直线的其余部分。

    这是我的代码(它尚未完成,所以基本上我正在寻找可以在下周一早上12月23日之前完成它的人)。

     >> initial:- M1=[6,5,3,6],
              M2=[5,6,8,12],
              M3=[8,6,8,9],
              M4=[3,6,5,8],
    
              write('M1= ['),
              printlist(M1),
          write('M2= ['),
              printlist(M2),
          write('M3= ['),
              printlist(M3),
          write('M4= ['),
              printlist(M4),nl,nl,
    
          redrow(M1,L1),
          redrow(M2,L2),
          redrow(M3,L3),
          redrow(M4,L4),
    
          write('L1= ['),
              printlist(L1),
          write('L2= ['),
              printlist(L2),
          write('L3= ['),
              printlist(L3),
          write('L4= ['),
              printlist(L4),nl,nl,
    
          /*Lc1=[],
          Lc2=[],
          Lc3=[],
          Lc4=[],*/
    
          col1(L1,L2,L3,L4,Lc1),
          col2(L1,L2,L3,L4,Lc2),
          col3(L1,L2,L3,L4,Lc3),
          col4(L1,L2,L3,L4,Lc4),          
    
          write('Lc1= ['),
              printlist(Lc1),
          write('Lc2= ['),
              printlist(Lc2),
          write('Lc3= ['),
              printlist(Lc3),
          write('Lc4= ['),
              printlist(Lc4),nl,nl,
    
          redrow(Lc1,Lx1),
          redrow(Lc2,Lx2),
          redrow(Lc3,Lx3),
          redrow(Lc4,Lx4),
    
          write('Lx1= ['),
              printlist(Lx1),
          write('Lx2= ['),
              printlist(Lx2),
          write('Lx3= ['),
              printlist(Lx3),
          write('Lx4= ['),
              printlist(Lx4),nl,nl,
    
          col1(Lx1,Lx2,Lx3,Lx4,Ly1),
          col2(Lx1,Lx2,Lx3,Lx4,Ly2),
          col3(Lx1,Lx2,Lx3,Lx4,Ly3),
          col4(Lx1,Lx2,Lx3,Lx4,Ly4),
    
          write('Ly1= ['),
              printlist(Ly1),
          write('Ly2= ['),
              printlist(Ly2),
          write('Ly3= ['),
              printlist(Ly3),
          write('Ly4= ['),
              printlist(Ly4),nl,nl.
    
    redrow(M1,L1):- minimo(M1,Min), redcopy(M1,L1,Min).
    
    minimo([X], X) :- !.
    minimo([X,Y|Tail], N):-
        ( X > Y ->
            minimo([Y|Tail], N)
        ;
            minimo([X|Tail], N)
        ).
    
    
    
    min1(X,Y,X):- X<Y, write('in min1 X= '), write(X), nl.
    min1(X,Y,Y):- X>Y,write('in min1 Y= '), write(Y), nl.
    min1(X,Y,Y).
    
    redcopy(L,R,V) :- accCp(L,R,V).
    accCp([],[],_).
    accCp([H|T1],[M|T2],V) :- M is H-V, accCp(T1,T2,V).
    
    col1([H1|T1],[H2|T2],[H3|T3],[H4|T4],[H1,H2,H3,H4]).
    col2([H11,H12|T1],[H21,H22|T2],[H31,H32|T3],[H41,H42|T4],[H12,H22,H32,H42]).
    col3([H11,H12,H13|T1],[H21,H22,H23|T2],[H31,H32,H33|T3],[H41,H42,H43|T4],[H13,H23,H33,H43]).
    col4([H11,H12,H13,H14|T1],[H21,H22,H23,H24|T2],[H31,H32,H33,H34|T3],[H41,H42,H43,H44|T4],[H14,H24,H34,H44]).
    
    /*redcopy([],[],_).
    redcopy(Ls,Ld,R):- Ls=[X|Lst],Ld=[X-R|Ld], redcopy(Lst,Ld,R).*/
    
    printlist([]):- write(']'),nl.
    printlist(L):- L=[X|Lt], write(X), write(' , '), printlist(Lt).
    

    我最后需要知道要问计算机给我输出(是,否)的问题。提前谢谢。

    注意:如果我的代码或问题不清楚(请我清楚),请不要关闭我的问题,因为可能有人已经得到了答案。

1 个答案:

答案 0 :(得分:3)

这可能不是您需要的答案,因为不会尝试实现假设缺失的30%。真的,如果你能解释一下如何大胆的陈述

  

我解决了大约70%的问题..

可以评估,我们都可以从你的任务中学到一些东西。但是,唉,你的代码似乎与任何“声明式”解决方案相距甚远。 哪里声明如何解决问题?

让我们从高级别描述开始:

  

确定应将哪些作业分配给哪些机器以最小化总成本

然后可以绘制可重用的解决方案:

assign_jobs_min_cost :-
    MJC =  % machines,jobs,cost
    [[6, 5, 3, 6 ],
     [5, 6, 8, 12],
     [8, 6, 8, 9 ],
     [3, 6, 5, 8 ]],
    assign_jobs_min_cost(MJC, Jobs, Cost),
    writeln(Jobs:Cost).

作业分配可以简单地看作是索引的排列(由于问题数据的友好呈现),然后

assign_jobs_min_cost(MJC, Jobs, Cost) :-
    aggregate_all(min(C, P),
              (permutation([1, 2, 3, 4], P),
               cost_assign(MJC, P, C)),
              min(Cost, Jobs)).

你知道,Prolog和任何其他语言一样,带有,它定义了惯用解决问题的方法。学习如何使用图书馆,这通常是语言学徒的最大部分。

这里我使用SWI-Prolog库(aggregate)以及permutation / 2。根据您的 Prolog(以及您的考试要求),您可以尝试使用自己的定义替换此类调用。

现在我们只剩下cost_assign(MJC, Jobs, Cost)来计算。再次使用库构造,它是一个“单一语句”:

cost_assign(MJC, Jobs, Cost) :-
    aggregate_all(
        sum(C),
        (between(1, 4, Mac),
         nth1(Mac, MJC, RowC),
         nth1(Mac, Jobs, J),
         nth1(J, RowC, C)
        ), Cost)
    % uncomment  below to see all assignments
    %,writeln(Jobs:Cost).
    .

但是你会学到更多写自己的东西......