Declaratieve Talen/alternatiefHuffman: verschil tussen versies
Naar navigatie springen
Naar zoeken springen
Geen bewerkingssamenvatting |
Geen bewerkingssamenvatting |
||
Regel 1: | Regel 1: | ||
==Oplossing1== | |||
Deze oplossing is een alternatief, maar daarom niet beter of minder goed dan de andere oplossing. Hier werd vooral veel commentaar genoteerd. | Deze oplossing is een alternatief, maar daarom niet beter of minder goed dan de andere oplossing. Hier werd vooral veel commentaar genoteerd. | ||
decodeer(N,Mes,Res) :- | decodeer(N,Mes,Res) :- | ||
Regel 63: | Regel 64: | ||
bereken(H,Freqs,Berek), | bereken(H,Freqs,Berek), | ||
Res = [Berek|TRes]. | Res = [Berek|TRes]. | ||
==Oplossing2== | |||
decodeer(N,Code,Res):- | |||
%lijst 0-N-1 | |||
NewN is N-1, | |||
lijst_maken(NewN,[],Lijst), | |||
%geef een opl (niet-rekeninghoudend met N) | |||
geef_opl(Code,[],Opl), | |||
%test of opl voldoet aan N | |||
length(Opl,N), | |||
%zet in juiste vorm | |||
zet_vorm(Opl,Lijst,[],Res). | |||
%maakt een lijst met elementen van 0-N | |||
lijst_maken(-1,L,L). | |||
lijst_maken(N,L,Elem):- | |||
NewN is N-1, | |||
lijst_maken(NewN,[N|L],Elem),!. | |||
geef_opl([],Opl,Opl). | |||
geef_opl(Code,TempOpl,FinalOpl):- | |||
append(L,R,Code), | |||
L \== [], | |||
is_geen_prefix_vorige(L,TempOpl), | |||
\+ is_prefix_volgende(L,R), | |||
append(TempOpl,[L],NewTempOpl), | |||
geef_opl(R,NewTempOpl,FinalOpl). | |||
is_geen_prefix_vorige(_Code,[]). | |||
is_geen_prefix_vorige(Code,[A|Vorige]):- | |||
\+ append(Code,_R,A), | |||
is_geen_prefix_vorige(Code,Vorige). | |||
is_prefix_volgende([],_Volgende). | |||
is_prefix_volgende([C|Code],[C|Volgende]):- | |||
is_prefix_volgende(Code,Volgende). | |||
zet_vorm([],[],Res,Res). | |||
zet_vorm([O|Opl],[L|Lijst],TempRes,FinalRes):- | |||
append(TempRes,[L-O],NewTempRes), | |||
zet_vorm(Opl,Lijst,NewTempRes,FinalRes). | |||
beste(N,Code,Freqs,Res):- | |||
%alle decodaties vinden | |||
findall(Dec,decodeer(N,Code,Dec),Decs), | |||
%voor elke tellen hoeveel cijfers gebruikt | |||
findall(Dec-Cijfer,(member(Dec,Decs),hoeveel_cijfers(Freqs,Dec,0,Cijfer)),Cijfers), | |||
%best=met minste cijfers | |||
minste_cijfers(Cijfers,Res). | |||
hoeveel_cijfers([],[],Cijfer,Cijfer). | |||
hoeveel_cijfers([Symbool-Aantal|Freqs],[Symbool-Code|Dec],TempC,FinalC):- | |||
length(Code,Lengte), | |||
N is Aantal*Lengte, | |||
NewTempC is TempC+N, | |||
hoeveel_cijfers(Freqs,Dec,NewTempC,FinalC). | |||
minste_cijfers([C|Cijfers],Res):- | |||
minste_cijfers2(Cijfers,C,Res). | |||
minste_cijfers2([],Res,Res). | |||
minste_cijfers2([Dec1-N1|Cijfers],Dec2-N2,Res):- | |||
( | |||
N1<N2 -> | |||
minste_cijfers2(Cijfers,Dec1-N1,Res) | |||
; | |||
minste_cijfers2(Cijfers,Dec2-N2,Res) | |||
). | |||
Nog een alternatieve oplossing --[[Gebruiker:Lynn|Lynn]] 15 jan 2011 21:50 (UTC) |
Versie van 15 jan 2011 21:50
Oplossing1
Deze oplossing is een alternatief, maar daarom niet beter of minder goed dan de andere oplossing. Hier werd vooral veel commentaar genoteerd.
decodeer(N,Mes,Res) :- decodeer(0,N,Mes,[],Res). decodeer(N,N,[],Acc,RAcc) :- % Uiteindelijk eindig je. reverse(Acc,RAcc). decodeer(N,M,Mes,Acc,Res) :- length(Mes,MesLen), % Bereken de lengte van het bericht numlist(1,MesLen,MesLL), % Maak een lijst lengtes van deelverz van het bericht member(MesAm,MesLL), % Haal zo'n lengte uit de lijst take(MesAm,Mes,MesPart), % Neem dat aantal elementen uit het bericht delete(MesAm,Mes,MesRest), % Verwijder die ook, zodat er enkel een rest is no_conflict(N-MesPart,Acc), % Kijk of er geen conflict is met reeds berekende NAcc = [N-MesPart|Acc], % Voeg berekende toe aan accumulator, vooraan op het einde reverse Nn is N+1, % Bereken nieuwe N decodeer(Nn,M,MesRest,NAcc,Res). % Decodeer rest bericht no_conflict(_,[]). % Je kan moeilijk conflict hebben met niets no_conflict(MesC-MesP,[_-MesH|T]) :- \+ prefix(MesP,MesH), % Check of geen prefix van elkaar no_conflict(MesC-MesP,T). prefix(_,[]). % Niets is pefix van alles prefix([],_). % Niets is pefix van alles prefix([H|PR],[H|RR]) :- % Controlleer of top lijst gelijk is (prefix) prefix(PR,RR). take(0,_,[]). take(N,[H|T],Res) :- Nn is N-1, take(Nn,T,TRes), Res = [H|TRes]. delete(0,A,A). delete(N,[_|T],Res) :- Nn is N-1, delete(Nn,T,TRes), Res = TRes. bereken([],_,0). % Het gewicht van een lege codering is 0 bereken([Nn-Ms|Rest],Freq,Res) :- % Neem eerste codering member(Nn-W,Freq), % Zoek de frequentie length(Ms,MsLen), % Bereken lengte codering bereken(Rest,Freq,TRes), % Bereken rest van codering Res is TRes + MsLen*W. % Resultaat is berek. rest + lengte cod. * freq-gewicht beste(N,Mes,Freqs,Res) :- findall(Ress,decodeer(N,Mes,Ress),ResList), geef_beste(ResList,Freqs,Res). geef_beste(ResList,Freqs,Res) :- bereken_alle(ResList,Freqs,BResList), min_list(BResList,Min), geef_beste(ResList,BResList,Min,Res). geef_beste([HE|_],[Min|_],Min,HE). % Verwijder 1 voor 1 tot je bij beste komt geef_beste([_|TE],[HB|TB],Min,Res) :- HB > Min, geef_beste(TE,TB,Min,Res). bereken_alle([],_,[]). % Bereken alle coderingen a.d.h.v. frequentie bereken_alle([H|T],Freqs,Res) :- bereken_alle(T,Freqs,TRes), bereken(H,Freqs,Berek), Res = [Berek|TRes].
Oplossing2
decodeer(N,Code,Res):- %lijst 0-N-1 NewN is N-1, lijst_maken(NewN,[],Lijst), %geef een opl (niet-rekeninghoudend met N) geef_opl(Code,[],Opl), %test of opl voldoet aan N length(Opl,N), %zet in juiste vorm zet_vorm(Opl,Lijst,[],Res). %maakt een lijst met elementen van 0-N lijst_maken(-1,L,L). lijst_maken(N,L,Elem):- NewN is N-1, lijst_maken(NewN,[N|L],Elem),!. geef_opl([],Opl,Opl). geef_opl(Code,TempOpl,FinalOpl):- append(L,R,Code), L \== [], is_geen_prefix_vorige(L,TempOpl), \+ is_prefix_volgende(L,R), append(TempOpl,[L],NewTempOpl), geef_opl(R,NewTempOpl,FinalOpl). is_geen_prefix_vorige(_Code,[]). is_geen_prefix_vorige(Code,[A|Vorige]):- \+ append(Code,_R,A), is_geen_prefix_vorige(Code,Vorige). is_prefix_volgende([],_Volgende). is_prefix_volgende([C|Code],[C|Volgende]):- is_prefix_volgende(Code,Volgende). zet_vorm([],[],Res,Res). zet_vorm([O|Opl],[L|Lijst],TempRes,FinalRes):- append(TempRes,[L-O],NewTempRes), zet_vorm(Opl,Lijst,NewTempRes,FinalRes). beste(N,Code,Freqs,Res):- %alle decodaties vinden findall(Dec,decodeer(N,Code,Dec),Decs), %voor elke tellen hoeveel cijfers gebruikt findall(Dec-Cijfer,(member(Dec,Decs),hoeveel_cijfers(Freqs,Dec,0,Cijfer)),Cijfers), %best=met minste cijfers minste_cijfers(Cijfers,Res). hoeveel_cijfers([],[],Cijfer,Cijfer). hoeveel_cijfers([Symbool-Aantal|Freqs],[Symbool-Code|Dec],TempC,FinalC):- length(Code,Lengte), N is Aantal*Lengte, NewTempC is TempC+N, hoeveel_cijfers(Freqs,Dec,NewTempC,FinalC). minste_cijfers([C|Cijfers],Res):- minste_cijfers2(Cijfers,C,Res). minste_cijfers2([],Res,Res). minste_cijfers2([Dec1-N1|Cijfers],Dec2-N2,Res):- ( N1<N2 -> minste_cijfers2(Cijfers,Dec1-N1,Res) ; minste_cijfers2(Cijfers,Dec2-N2,Res) ).
Nog een alternatieve oplossing --Lynn 15 jan 2011 21:50 (UTC)