Erste Schritte Baumstruktur (dynamisch)

Chaya

Mitglied
Guten Tag zusammen,
da schreibe ich jetzt meinen ersten Eintrag und habe gleich eine Frage an euch, weil ich leider keinen Einstiegspunkt finde. :oops:

Und zwar habe ich die Aufgabe das Nutzerverhalten auf einer Website zu analysieren.
Genauer gesagt sollen hier die Klickpfade dargestellt werden (wie häufig wird der gleiche Weg gegangen, ...)

Das ganze möchte ich dann in einer Baumstruktur darstellen.
Die Daten hierzu hole ich mir aus einem Logfile, das in eine Datenbank geschrieben wird. Aber das nur als Hintergrund. Der Prozess läuft ;)
Das ganze soll dann (stark vereinfacht) ungefähr so aussehen:
veranschaulichung.PNG
Hier hätte ich dann folgende Verläufe
Startseite -> Produkte -> TV
Startseite -> Produkte -> Handys
Startseite -> Produkte -> Laptops
Startseite -> Flyer
Startseite -> Suche

Nur... wie bekomme ich das hin?
Es geht mir jetzt erstmal gar nicht um die richtigen Daten aus der Datenbank, sondern es wäre mir schon sehr geholfen, wenn ich einfach einen Baum bauen könnte, der mir den Baum aus dem Bild baut.
Alles andere ist dann das kleinere Problem, das bekomme ich dann selber hin.
Ich habe Google schon durchforstet, allerdings finde ich da großteils nur etwas zu Binärbäumen. Aber das geht ja nicht, wenn ich mehr als 2 Kinderknoten habe oder? Falls doch wäre es cool, wenn mir hier einer eine kleine Hilfe geben könnte.

Danke schon mal und viele Grüße
Chaya


Edit: Achja, was ich vergaß: kein JTree, ich will das nicht grafisch. Das ganze soll dann in eine CSV geschrieben werden.
 
Zuletzt bearbeitet:

Kevin94

Top Contributor
Wenn das ganze ein "echter" Baum ist, d.h. jede Element nur ein übergeordnetes Element besitzt ist es relativ einfach: Jeder Node bekommt als Variablen Parent und eine Liste von Kindern, sowie wie Häufig die Seite aufgerufen wurde.
Wenn eine Seite aber von mehreren anderen Seiten aus aufgerufen werden kann, müssen sowohl Eltern als auch Kinder als List gespeichert werden bzw. als Map<Node,Aufrufe>.
 

Chaya

Mitglied
Wenn das ganze ein "echter" Baum ist, d.h. jede Element nur ein übergeordnetes Element besitzt ist es relativ einfach: Jeder Node bekommt als Variablen Parent und eine Liste von Kindern, sowie wie Häufig die Seite aufgerufen wurde.
Wenn eine Seite aber von mehreren anderen Seiten aus aufgerufen werden kann, müssen sowohl Eltern als auch Kinder als List gespeichert werden bzw. als Map<Node,Aufrufe>.

Danke für deine Antwort :)
Ja, es soll ein echter Baum werden.

Hast du da ein bisschen Code für mich, ich kann mir das leider nicht vorstellen, wie ich das machen muss...
 

eMmiE

Bekanntes Mitglied
Beispiel 1: Aufruf nur von einer Seite

Code:
class Node {

Node parent;
ArrayList<Node> childs = new ArrayList<>();
int klicks;
String name;

public Node(Node Parent,ArrayList<Node> Childs,int Klicks, String Name) {
//übernehmen der Werte
}

//getter
//...

public boolean hasChild(String name) {
for (int i = 0;i < childs.size();i++) {
if (childs.get(i).name.equals(name)) {
return true;
}
}
return false;
}

public void addChild(Node n) {
childs.add(n);
}

public void addKlicks(int i) {
klicks += i;
}
}

class LinkKlickObjekt {
//die Klasse enthält
LinkKlickObjekt Vorgänger;
LinkKlickObjekt[] Nachfolger
String name;

}

class Main {

LinkKlickObjekt[][] pfade;

public Main() {
//Wenn du das jetzt als String[] (Also alle Pfade, die gegangen wurden) im Format "Startseite>Bücher>Autor>..." übergeben bekommst, dann musst //du das natürlich noch ein bisschen cutten, ich gehe von einem LinkKlickObjekt[][] aus

pfade = pfadeAnlegen();

Node root = new Node(null,null,0,hierDerName);
Node n;

for (int i = 0;i < pfade.length;i++) {
n = root;
for (int j = 0;j < pfade[i].length;j++) {

n = n.getChild(pfade[i][j]);


n.addKlicks(1);
if (j < pfade[i].length - 1) {
if (!n.hasChild(pfade[i][j+1])) {
//Neues Childelement anfügen
n.addChild(new Node(n,null,0,pfade[i][j].name));
}
}
}
}
}

}

Das sieht hier jetzt erstmal ein bisschen unübersichtlich aus

1. Du legst eine Liste (LinkKlickObjekt[][]) mit allen Pfaden (LinkKlickObjekt[]) an, die zur Verfügung stehen
2. Die iterierst du durch
Am Anfang eines Pfads steht ja immer die Startseite
Am Anfang jedes Pfads wird der "bearbeitende Node" (n) auf root, den Anfangsknoten gesetzt
Der hat logischerweise keinen Vorgänger

Jedes Mal, wenn dann das nächste LKO aus einem Pfad aufgerufen wird, wird der n zur Referenz auf den jeweiligen Child-Knoten (...getChild())
Er fügt erst dem Objekt einen Klick zu, dann guckt er, ob das Ende des Pfads erreicht ist (Er muss dann keinen Knoten anfügen) oder ob der nächste Child-Knoten noch nicht enthalten ist.
Dann fügt er einen neuen hinzu.

So sollten dann alle Pfade in Knoten und Werte aufgeteilt sein

Gruß eMmiE

P.S.: Ist nur ein Ansatz, also bitte nicht hauen;)
 
Zuletzt bearbeitet:

Chaya

Mitglied
@eMmiE:
ja genau :)

ich habe als Beispiel die folgenden Pfade:
Startseite -> Produkte -> TV
Startseite -> Produkte -> Handys
Startseite -> Produkte -> Laptops
Startseite -> Flyer
Startseite -> Suche

Dann möchte ich, dass mein Oberpunkt die "Startseite" ist, von da aus sollen dann Äste weggehen zu "Produkte", "Flyer" und "Suche". "Produkte" gabelt sich dann wieder auf in "TV", "Handys" und "Laptops".

Gespeichert werden sollte es dann so:

Startseite;Produkte (3);TV (1)
Startseite;Produkte (3);Handys (1)
Startseite;Produkte (3);Laptops (1)
Startseite;Flyer (1)
Startseite;Suche (1)

aber das Speichern ist erst mal nicht so wichtig, eher, dass ich diese Struktur hinbekomme.

Oh je, ich hoffe ich habe das gescheit erklärt :/
 

eMmiE

Bekanntes Mitglied
Siehe oben

(Wird leider nicht mehr angezeigt, wenn ein Beitrag zugefügt wurde, während du einen schreibst...)

Bei mehreren Startseiten natürlich mehrere Bäume
 

Chaya

Mitglied
oh wow, super, ich danke dir :)
Das werde ich mir gleich mal genauer anschauen. Genau sowas habe ich gebraucht! :toll:

Wenn ich dazu noch fragen habe, dann melde ich mich wieder.

Nochmals tausend Dank!
 

eMmiE

Bekanntes Mitglied
Frage: WIE bekommst du deine Pfade?
1. String[] oder String[][]
2. In welchem Format sind die (Bsp. 1: "Start>Bücher.Bücher>Comics.Comics>Superman[...]" o. Bsp. 2: "Start>Bücher>Comics[...]" (Was Anderes fällt mir jetzt gar nicht ein))
3. Am besten mit Codesnippet

Gruß eMmiE
 

Chaya

Mitglied
Guten Morgen :)

Ich habe mich jetzt nochmal mit einem Kollegen zusammen gesetzt und wir sind das ganze durchgegangen (schade, dass ich es nicht alleine schaffen konnte)
Der Ansatz ist jetzt ein bisschen anders, als der von dir @eMmiE
Die Pfade kommen übrigens aus einer Datenbank. Die Zusammengehörigkeit wird durch die SessionID gekennzeichnet.

Demnach habe ich folgende Klassen:


Java:
package tree;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DbConnection {
	String host = "jdbc:mysql://localhost:3306/";
	String dbname = "acceslogs";
	String username = "root";
	String password = "";

	String shorturl = host + dbname;
	
	public Connection getConnection() throws SQLException, ClassNotFoundException {
		Class.forName("com.mysql.jdbc.Driver");
		Connection conn = DriverManager.getConnection(shorturl, username, password);
		return conn;
	}
}


Java:
package tree;

import java.util.ArrayList;

public class Node {
	Node parent;
	ArrayList<Node> children = new ArrayList<Node>();
	int clicks;
	String name;
	
	Node(Node parent, String name){
		this.parent = parent;
		if (parent != null)
			parent.addChild(this);
		this.clicks = 1;
		this.name = name;
	}
	

	
	Node(){
		this.parent = null;
		this.children = null;
		this.clicks = 0;
		this.name = null;
	}
	
	Node(String name) {
		this.clicks = 1;
		this.name =name;
	}



	public Node getParent(){
		return parent;
	}
	
	public int getClicks(){
		return clicks;
	}
	
	public ArrayList<Node> getChildren(){
		return children;
	}
	
	public void setParent(Node parent){
		this.parent = parent;
	}
	
	public void addClicks(){
		this.clicks += 1;
	}
	
	public void addChild(Node child){
		child.setParent(this);
		this.children.add(child);
	}
	
	public boolean hasChild(String child){
		return false;		
	}
	
	
	
	
	public String toString() {
		String ret = "";
		if (parent!= null) {
			ret += parent.toString();
		}
		ret += "/" + name;
		return ret;
	}
	
	public String toStringDown(){
		String ret = name+"("+clicks+")"+"\n";
		int lvl = getHierachyDepth();
		for(Node child: children) {
			for(int i=0;i<lvl;i++) ret +="   ";
			ret += "|--" + child.toStringDown();
		}
		return ret;
	}
	
	public int getHierachyDepth(){
		int ret = 1;
		if(parent!=null)
			ret += parent.getHierachyDepth();
		return ret;
	}

	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Node other = (Node) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	

	public Node getChild(Node newNode) {
		return children.get(children.indexOf(newNode));
	}

}

Java:
package tree;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Run {
	
	
	
	public static void main(String[] args) throws ClassNotFoundException, SQLException, FileNotFoundException, UnsupportedEncodingException{
		DbConnection conn = new DbConnection();
		Statement stmt = conn.getConnection().createStatement();
		
		System.out.println("Query");
		
		ResultSet res = stmt.executeQuery("select accesstime, uripath, sessionid "
				+ "from acceslogs.logs "
				+ "where sessionid is not null "
				+ "order by sessionid,accesstime");
		
		
		
		Node root = new Node(null, "Start");
		String tmp = "";
		Node toAddChild = root;
		System.out.println("Executed. Starting rendering");
		while(res.next()){			
			if(!tmp.equals(res.getString(3))){
				toAddChild=root;
				tmp = res.getString(3);
			}			
			String path = res.getString(2); //substr
			int index = path.indexOf('?');
			if(index > 0)
				path = path.substring(0, index);
			Node newNode = new Node(path); //konstruktor
			if(toAddChild.getChildren().contains(newNode)) {
				newNode = toAddChild.getChild(newNode);
				newNode.addClicks(); //bauen
			} else {
				toAddChild.addChild(newNode);
			}
			toAddChild = newNode;
		}
		
		conn.getConnection().close();
		
		
		System.out.println("Starting to print");
		
		
		PrintWriter writer = new PrintWriter("paths_full.txt", "UTF-8");
		writer.println(root.toStringDown());
		writer.close();
		
		System.out.println("Done");
		
	}

}


Aber ohne deinen Vorschlag wäre ich da auch mit Hilfe nicht durchgestiegen. Danke :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Checkliste mit erweiterbaren Einträgen, Baumstruktur, wie Windows Explorer Navigation Allgemeine Java-Themen 2
G Baumstruktur abspeichern Allgemeine Java-Themen 9
R Baumstruktur aus Term Allgemeine Java-Themen 34
S Baumstruktur/Datenstruktur in Datei speichern Allgemeine Java-Themen 23
Pfirsich TreeModel oder Baumstruktur Allgemeine Java-Themen 10
S Tiefe Kopie einer Baumstruktur als statische Methode Allgemeine Java-Themen 8
D Objekte in Baumstruktur Allgemeine Java-Themen 4
P Baumstruktur aus klassen/ Array Allgemeine Java-Themen 4
berserkerdq2 Jemand einen Tipp wie man ein Javafx-Hintergrund "dynamisch" macht Allgemeine Java-Themen 3
E RMI FWH: RMI- Wie erstelle ich stubs dynamisch, bzw. unterdrücke eine Statisch-Warnung? Allgemeine Java-Themen 0
S Maven Jars dynamisch laden / Plugin-Struktur erstellen Allgemeine Java-Themen 14
T Statisch und dynamisch Allgemeine Java-Themen 1
MiMa Variableninhalte dynamisch abfragen Allgemeine Java-Themen 12
D Methode dynamisch aufrufen Allgemeine Java-Themen 2
S Externe Eclipse Projekte dynamisch einbinden Allgemeine Java-Themen 3
Thallius Externe .jar dynamisch einbinden Allgemeine Java-Themen 5
F JTree: Nodes dynamisch anlegen via LinkedHashMap Allgemeine Java-Themen 2
B Reflection, invoke dynamisch befüllen Allgemeine Java-Themen 3
M Klassen Klasse Dynamisch laden und Konstruktor aufrufen Allgemeine Java-Themen 1
J rxtxserial.dll für 32 oder 64bit dynamisch einbinden Allgemeine Java-Themen 9
F Dynamisch ein Objekt einer bestimmten Subklasse erstellen Allgemeine Java-Themen 7
W Dateinamen dynamisch Parsen Allgemeine Java-Themen 12
T Classpath Klassen dynamisch erstellen Allgemeine Java-Themen 4
F Schlüsselworte Einstellungen dynamisch deserialisieren Allgemeine Java-Themen 5
S LaTeX Code in dynamisch erzeugten PDF's Allgemeine Java-Themen 8
X Dynamisch Konstruktor aufrufen Allgemeine Java-Themen 12
hdi Ressourcen dynamisch zur Laufzeit laden Allgemeine Java-Themen 15
A Klassen dynamisch aus jar-datei laden Allgemeine Java-Themen 5
J instanceof vermeiden und stattdessen dynamisch binden Allgemeine Java-Themen 6
M Konstruktoraufruf dynamisch auswerten und SQL bauen Allgemeine Java-Themen 10
E Variable dynamisch ausgeben Allgemeine Java-Themen 5
Tandibur pattern dynamisch vorkompilieren Allgemeine Java-Themen 9
T Objekt dynamisch neu erstellen/ austauschen Allgemeine Java-Themen 9
T Dynamisch getypte Klasseninstanz? Allgemeine Java-Themen 6
H getText(); bei dynamisch generierten JTextFiled Allgemeine Java-Themen 2
F Wie erfahre ich dynamisch den namen eines aktuellen Objektes Allgemeine Java-Themen 2
S Asymmetrisches Array dynamisch erzeugen Allgemeine Java-Themen 4
T Objekte dynamisch über eine Methode erzeugen Allgemeine Java-Themen 10
R Object Dynamisch erzeugen (Reflection API) Allgemeine Java-Themen 22
P RTF dynamisch machen (IText, Swing) Allgemeine Java-Themen 4
B Listener dynamisch setzen Allgemeine Java-Themen 6
P Klasse Dynamisch laden und zurückgeben Allgemeine Java-Themen 17
P Array Dynamisch vergrößern Allgemeine Java-Themen 7
B objekt einer klasse dynamisch erzeugen Allgemeine Java-Themen 6
G Objekt dynamisch erstellen und Inhalte kopieren Allgemeine Java-Themen 6
C Dynamisch Objekte unterschiedlicher Typen erzeugen Allgemeine Java-Themen 6
D Klassen dynamisch laden Allgemeine Java-Themen 5
E Arrays -> dynamisch Allgemeine Java-Themen 21
K Methoden dynamisch erstellen Allgemeine Java-Themen 12
P Dynamisch casten - möglich? wie? Allgemeine Java-Themen 5
T Klassen dynamisch ausführen Allgemeine Java-Themen 3
N Graphische Oberfläche dynamisch erweitern möglich? Allgemeine Java-Themen 4
B Absolute Paf einer Klasse in dieser dynamisch auslesen? Allgemeine Java-Themen 5
K Klasse dynamisch casten Allgemeine Java-Themen 14
Reeny Dynamisch Klassen kompilieren Allgemeine Java-Themen 5
G JDO Dynamisch ? Allgemeine Java-Themen 2
H Objekte m. versch. Interf. dynamisch erzeugen Allgemeine Java-Themen 11
E Klasse dynamisch über main-Methode aufrufen Allgemeine Java-Themen 9
D Strings dynamisch füllen Allgemeine Java-Themen 5
A Dynamisch Attribute hinzufügen Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben