www.mikrocontroller.net

Forum: PC-Programmierung Java Backtracking


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Kurt Tresen (kurtisblow)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,
ich komme bei folgender Aufgabe nicht klar:
Wir sollen einen "Rucksack" durch das Backtrackingverfahren packen, 
sprich
man soll die Gegenstände mit den höchsten Wert finden, die aber eine 
gewisse
Gewichtsschranke nicht überschreiten dürfen.

Nun haben wir folgende Selection Klasse, wo wir die einzelnen
methoden, z.B sum(weights) für das aktuell Gewicht im Rucksack aufrufen 
können.
/**
 * Efficient array of booleans.
 * 
 * The booleans are stored in an integer.  Starting from the less significant bit up to 
 * the index {@link Selection#size()}  the respective boolean is true iff the bit is 1.
 * 
 * The values of all other bits are undefined.
 */
public class Selection {
    private int bits;
    private int size;
 
    /**
     * Create a selection
     * @param size the size of the selection
     * @param bits the values of the booleans encoded as integer
     */
    public Selection(int size, int bits)
    {
        setSize(size);
        setBits(bits);
    }
    
    /**
     * Create a selection with all booleans set to false
     * 
     * @param size the size of the selection. 0 <= size <= 32.
     */
    public Selection(int size) 
    {
        setSize(size);
        setBits(0);
    }
 
    /**
     * Set the boolean values
     * 
     * @param bits the boolean values encoded as integer.
     */
    public void setBits(int bits)
    {
        this.bits = bits;
    }
    
    /**
     * Get the boolean values
     * 
     * @return the boolean values encoded as integer.
     */
    public int bits()
    {
        return bits;
    }
    
    /**
     * Set the size of the selection.
     * 
     * If the size is increased the values of the new booleans are undefined.
     * 
     * @param size the new size of the selection. 0 <= size <= 32
     */
    public void setSize(int size)
    {
        if (size > 32) throw new IllegalArgumentException("a maximum of 32 bits is supported only");
        if (size < 0) throw new IllegalArgumentException("the size must be greater or equal to zero");
        this.size = size;
    }
 
    /**
     * Get the size of the selection
     * @return the size of the selection
     */
    public int size()
    {
        return size;
    }
    
    /**
     * Set a boolean value
     * 
     * @param index the index of the boolean
     * @param value the value of the boolean
     */
    public void set(int index, boolean value)
    {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        if (value) {
            int mask = 1 << index;
            bits = bits | mask;
        } else {
            int mask = ~(1 << index);
            bits = bits & mask;
        }
    }
    
    /**
     * Get a boolean values
     * 
     * @param index the index of the boolean
     * @return the value of the selected boolean
     */
    public boolean get(int index)
    {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        int mask = 1 << index;
        return (bits & mask) != 0;
    }
    
    public String toString()
    {
        StringBuffer buf = new StringBuffer();
        buf.append("[");
        for (int i=0; i<size; i++) {
            if (i != 0) buf.append(", ");
            if (get(i)) {
                buf.append("true");
            } else {
                buf.append("false");
            }
        }
        buf.append("]");
        return buf.toString();
    }
    
    /**
     * Calculates a selected sum
     * @param addends a vector of integers. The vector must be as large as the selection.
     * @return the sum of all addends for which the corresponding booleans are true.
     */
    public int sum(ArrayList<Integer> addends)
    {
        if (addends.size() != size()) throw new IllegalArgumentException("Not enough or too many addends");
        int sum = 0;
        for (int i=0; i<addends.size(); i++) {
            if (get(i)) {
                sum += addends.get(i);
            }
        }
        return sum;
    }
}


Was ich bisher habe:
public class RucksackBacktracking implements IRucksack {

  //Find an optimal solution for the Rucksack problem with "Backtracking"!
  
  public Selection findBest(ArrayList<Integer> values,
      ArrayList<Integer> weights, int maxWeight) 
  { 
    return find(new Selection(values.size(),0),0,values,weights,maxWeight);
  }
  
  public Selection find(Selection s,int i,ArrayList<Integer> values,
      ArrayList<Integer> weights, int maxWeight)
  {
    if(i == values.size()) return s;
    Selection without = new Selection(i,0);
    without = find(without,i + 1,values,weights,maxWeight);
    
    if((s.sum(weights) + weights.get(i)) <= maxWeight) 
    {
      Selection with = new Selection(i,1);
      with.set(i, true);
      with = find(with,i + 1,values,weights,maxWeight);
      if (with.sum(values) >= without.sum(values)) return with;
    }
    return without;
  }
}

Ich finde einfach den Fehler nicht. Vielleicht sieht ihn ja jemand.
Gruss

Autor: Daniel H. (danielch)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi,
Selection without = new Selection(i,0); //erzeugt einen leeren Rucksack
und 
Selection with = new Selection(i,1); //erzeugt einen mit dem 1. Element
überleg dir, ob das Sinn macht. Tipp: Du hast ja schon mit den ersten x 
Elementen probiert, die solltest du also nicht vernachlässigen.

lg dänu

Autor: Kurt Tresen (kurtisblow)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Dann solte es doch so sein:
Selection without = new Selection(values.size(),i);
Selection with = new Selection(values.size(),i);

Also die Grösse ist fest (values.size()) und das jeweilige bit (i) auf 
true oder?

Autor: Daniel H. (danielch)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ja, die Grösse ist konstant, aber der Konstruktor initialisiert dir 
deine ganze Selection, welche ja als Int repräsentiert wird.

Du musst also dass, was du schon in früheren "Rekursionen" gemacht hast 
benutzen. So in etwa without = new Selection(values.size(), sel.bits())
damit du die ersten n-Elemente berücksichtigst.
Das "jeweilige" Bit setzt du dann ja mit dem: with.set(i, true);

lg

Autor: Kurt Tresen (kurtisblow)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Super, danke, hat geklappt.

Autor: Nayyar (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Poste doch mal, damit Leute die über eine Suche hier landen mit einem 
ähnlichen Problem auch was davon haben :)

Autor: D. I. (grotesque)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Und damit das Programm auch schnell läuft für größere Eingaben, sollte 
man mal über dynamische Programmierung nachdenken ;) sonst läuft das 
Teil in exponentieller Laufzeit

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net