Declaratieve Talen/alternatiefHuffman: verschil tussen versies

Uit Wina Examenwiki
Naar navigatie springen Naar zoeken springen
Greet (overleg | bijdragen)
Greet (overleg | bijdragen)
 
Regel 142: Regel 142:
   
   
Nog een alternatieve oplossing --[[Gebruiker:Lynn|Lynn]] 15 jan 2011 21:50 (UTC)
Nog een alternatieve oplossing --[[Gebruiker:Lynn|Lynn]] 15 jan 2011 21:50 (UTC)




==Oplossing3==
==Oplossing3==
 
<pre>
decodeer(X,Code,Resultaat):- verdeelcode(X,Code,Res),
decodeer(X,Code,Resultaat):- verdeelcode(X,Code,Res),
                    schrijfNummer(Res,0,Resultaat).
                    schrijfNummer(Res,0,Resultaat).
Regel 193: Regel 194:
minimaal(Rest1,Rest2,KleinsteCode,Voorkomen)
minimaal(Rest1,Rest2,KleinsteCode,Voorkomen)
).
).
 
</pre>
Nog een alternatieve oplossing --[[Gebruiker:Greet|Greet]]
Nog een alternatieve oplossing --[[Gebruiker:Greet|Greet]]

Huidige versie van 18 jan 2011 09:51

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)


Oplossing3

decodeer(X,Code,Resultaat):- verdeelcode(X,Code,Res),
	                     schrijfNummer(Res,0,Resultaat).


verdeelcode(1,Code,[Code]).
verdeelcode(X,Code,[A|Res]):- Y is X-1,
				append(A,NewCode,Code),
				length(A,La),
			       	length(NewCode,Ln),
				La>0,
				Ln>0,
				\+append(A,_,NewCode),
				\+append(NewCode,_,A),
				verdeelcode(Y,NewCode,Res),
				forall(member(Z,Res),
				(
				\+append(A,_,Z),
				 \+append(Z,_,A)
				)).

schrijfNummer([],_,[]).
schrijfNummer([X|Xs],N,[N-X|Res]):-
	M is N+1,
	schrijfNummer(Xs,M,Res).


beste(X,Code,Freqs,Y):- findall(Res1,decodeer(X,Code,Res1),List),
	                  member(Y,List),
			  minimaal(Y,Freqs),!.

minimaal(Code,Freqs):-minimaal(Code,Freqs,0,0).
minimaal([],[],_,_).
minimaal([N-X|Rest1],[N-Y|Rest2],0,0):-length(X,M),
				        minimaal(Rest1,Rest2,M,Y).
minimaal([N-X|Rest1],[N-Y|Rest2],KleinsteCode,Voorkomen):-
	length(X,M),
	(
	M>KleinsteCode->
	(
	Y<Voorkomen->
	minimaal(Rest1,Rest2,M,Y)
	;
	fail
	)
	;
	minimaal(Rest1,Rest2,KleinsteCode,Voorkomen)
	).

Nog een alternatieve oplossing --Greet