B a c k t r a c k i n g

Beispielprogramm 1.2:   5coins erweitert



PROGRAM      some_coins_in_a_fountain;  {         "alle Lösungen"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HMO ludens, Warendorf, 27.6.1988, ein Beispiel für  BACKTRACKING.

Teilmengenproblem: Gegeben sind N Münzen mit den Münzwerten
p1 , p2 , .. , pN  und ein Betrag B. Gesucht sind alle Möglichkeiten,
den Betrag B mit möglichst wenig Münzen auszuzahlen. Bei dieser
Übungsaufgabe können die Daten eingegeben werden. }

CONST  Nmax          =  50;         { vorgesehen für maximal 50 Münzen }
       auswahlanfang =  0;
       auswahlende   =  1;
TYPE   vektortyp     =  ARRAY [0..Nmax] OF Integer;
       inhaltstyp    =  RECORD      { Typ für einen Listeneintrag }
                          vektor: vektortyp;
                          anzahl: Integer
                        END;
{$I stackadt.pas}
VAR    pvektor       :  ARRAY [1..Nmax] OF Integer; { Werte }
       vektor        :  vektortyp;
       N             :  Integer;    { Anzahl der Münzen }
       B             :  Integer;    { Zielbetrag }
       i             :  Integer;
       akt_optimum   :  Integer;
       loesungen     :  stacktyp;
       eintrag       :  inhaltstyp;

  { T }
  PROCEDURE try (stufe: Integer; vektor: vektortyp);
  VAR wahl,anzahl,wert: Integer;

    { T.1 }
    PROCEDURE vektor_bewerten;
    VAR j: Integer;
    BEGIN
      anzahl:=0; wert:=0;
      FOR j:=1 TO vektor[0]
      DO BEGIN anzahl:=anzahl+vektor[j]; 
               wert:=wert+vektor[j]*pvektor[j] END
    END;

    { T.2 }
    FUNCTION vollstaendig: Boolean;
    BEGIN  vollstaendig := (vektor[0]=N)  END;

    { T.3 }
    FUNCTION neues_optimum: Boolean;
    BEGIN  neues_optimum := (wert=B) AND (anzahl<=akt_optimum)  END;

    { T.4 }
    FUNCTION lebend: Boolean;
    BEGIN  lebend := (anzahl<=akt_optimum) AND (wert<=B)  END;

    { T.5 }
    PROCEDURE loesung_speichern;
    VAR eintrag: inhaltstyp;
    BEGIN
      akt_optimum:=anzahl;
      eintrag.vektor:=v; eintrag.anzahl:=anzahl;
      push_stack(loesungen,eintrag)
    END;

  BEGIN { T }
    FOR wahl:=auswahlanfang TO auswahlende DO
    BEGIN
      vektor[0]:=stufe;        { Stelligkeit setzen }
      vektor[stufe]:=wahl;     { Auswahl wahl für Objekt stufe treffen }
      vektor_bewerten;         { Anzahl der Münzen, Münzwert berechnen }
      IF vollstaendig
        THEN BEGIN  IF neues_optimum THEN  loesung_speichern   END
        ELSE BEGIN  IF lebend        THEN  try(stufe+1,vektor) END
    END
  END;

  PROCEDURE ein (was: String; unten,oben: Integer; VAR wert: Integer);
  VAR s: String[10];
      c: Integer;
  BEGIN
    REPEAT
      write(was);
      readln(s); IF s='' THEN s:='x';
      val(s,wert,c);
    UNTIL (c=0) AND (wert>=unten) AND (wert<=oben)
  END;

BEGIN
  { Überschrift, kurze Hinweise, Eingabe der Daten }
  Writeln; Writeln('BACKTRACKING :  Teilmengenproblem');
           Writeln('---------------------------------');
  Writeln('Gegeben sind N=',n,' Münzen mit beliebigen Werten.');
  Writeln('und ein Zielbetrag B. Gesucht sind alle Möglichkeiten den');
  Writeln('Betrag B mit möglichst wenig Münzen auszuzahlen.'); Writeln;
  ein('Anzahl Münzen  N = ',1,50,N);
  ein('Zielwert       B = ',0,Maxint,B);
  FOR i:=1 TO N DO
  BEGIN write(i:2,'-'); ein('Wert        P = ',0,Maxint,pvektor[i]) END;
  { Initialisierung, Lösungssuche }
  create_stack(loesungen); { Liste für Lösungen initialisieren }
  vektor[0]:=0;            { Start mit 0-stelligem Vektor }
  akt_optimum:=N+1;        { Ergebnis N+1 1 Münzen bedeutet keine Lösung }
  try(1,vektor);           { rekursive Lösungssuche }
  { Ausgabe der Lösungen }
  writeln;
  IF akt_optimum>N
    THEN writeln('keine Lösung !')
    ELSE BEGIN
      WHILE NOT empty_stack(loesungen)
      DO BEGIN
        top_stack(loesungen,eintrag); pop_stack(loesungen);
        IF eintrag.anzahl=akt_optimum
        THEN BEGIN
          FOR i:=1 TO N DO
            IF eintrag.vektor[i]=0 THEN Write('-':6)
                                   ELSE Write(pvektor[i]:6);
          Writeln;
        END
      END
    END
END.



HTML-Texte: Münzen 1 Münzen 2 ADT Stack Escher knapsac bunte Reihe salesman HAUPTTEXT
Paket mit Pascal-Dateien laden: BackPac.Zip   (47 K)

zur Informatik-Leitseite


© HMO, Neubearbeitung Januar 1998