Dynamische Sorten-Prüfung?

Status
Nicht offen für weitere Antworten.

RTC

Mitglied
Hallo Leute.

Das wird jetzt etwas schwer zu erklären sein, aber ich hoffe ihr versteht was ich will. Ich möchte ein Programm schreiben, in dem es möglich sein soll dynamisch (durch den Benutzer) einen Graphen aufzubauen, bei dem jeder Knoten einem Algorithmus entspricht und jede Kante einer Daten-Transformation zwischen Ausgabedaten von Algorithmus1 und Eingabedaten von Algorithmus2. Ein Beispiel-Graph könnte so aussehen:
Code:
---> ImgProc ---> NeuralNet --->
In dem Fall würde ein Bild eingegeben, von der Bildverarbeitung vorverarbeitet und dann an ein Neuronale Netz übergeben werden. Als Zwischenschritt müsste das Bild, welches aus der Bildverarbeitung rauskommt in einen Vektor umgewandelt werden, der als Eingabe des Neuronalen Netzes dient.

Mein Problem ist, dass ich solch einen Prozess verallgemeinern will/muss. D.h. natürlich zum einen, dass ich beliebige solcher Graphen erzeugen will und vor allem die Graph-Klasse zum Ausführen solcher (sequentieller) Graphen kompilierbar sein muss.

Das heißt zunächst einmal dass jedes Graph-Objekt (ob Algorithmus oder Daten-Transformation) eine allgemeine Schnittstelle implementiert, z.B. (Pseudocode):
Code:
interface IGraphComponent{
  public void Input(Object o);
  public Object Output();
}

So wäre es allgemein möglich, eine Liste von IGraphComponent-Objekten abzuarbeiten und den Output eines Objekts als Input des nächsten zu benutzen. Das Problem dabei wird offensichtlich: es werden nur Object's hin- und hergeschuppst, das sagt aber noch gar nichts darüber aus, ob es sich z.B. bei dem an das Neuronale Netz übergebene Argument (Object) nun um einen Vektor oder ein Bild oder sonstwas handelt.

Meine Frage ist nun, wie ich das bereinigen kann? Ich könnte sicher im Neuronalen Netz in der Input()-Methode eine Abfrage starten, z.B. so in der Art "if(!(o is Vector)) throw Exception", aber die Exception würde erst dann geworfen werden, wenn der Graph traversiert wird. Ich möchte aber, dass eine Prüfung schon beim Zusammenbauen des Graphen stattfindet, sodass unmögliche Fälle gleich ausgeschlossen werden. Wie könnte ich das realisieren?

Ich dachte schon an eine Art "AcceptedInputs()"-Methode, die ein String-Array der Sorten zurückgibt, die als Input erlaubt sind. Analog dazu eine "ProvidedOutputs()"-Methode. Allerdings halte ich diesen "Umweg" über String's für nicht sehr elegant und auch für fehleranfällig, wenn z.B. mal eine Klasse umbenannt wird etc. ...

Danke für eure Hilfe.
Viele Grüße,
Matthias
 
S

SlaterB

Gast
falls die Klassen bekannt sind,
kann du die Strings auch dynamisch erstellen:
static String[] classnames = {KlasseXY.class.getSimpleName(), ..};

wenn dann eine Klasse umbenannt wird, dann kommt auch der geänderte Name in dein Array

----------------

manchmal sieht man den Wald vor lauter Interfaces nicht,
so schön das Design am Ende auch wird,
am Anfang würde ich mit 1-2 Algorithmen und 1-2 Transformationen anfangen,
so dass als Übergabetyp eben nicht gleich Object stehen muss, sondern vielleicht erstmal mal Vector
(oder besser ArrayList, wenn nicht synchronisiert werden muss)
oder ein eigener Datentyp steht

--------

überhaupt könntest du dir überlegen, zum Transport jeglicher Art von Daten einen eigenen Datentyp zur Kapselung verwenden,
der dann sinnvolle allgemeine Operation wie getType(), getAcceptedTransformations(), getAcceptedOperations(),
historyOfFormerTransformations() usw. enthält

---------

allgemeine Interface können nicht viel mehr als Object zurückgeben,

wenn du aber die neuen Generics benutzt, kannst du zumindest bei konkreten Unterklassen etwas Typisierung einbauen

Beispiel (kenn mich mit der Syntax nicht ganz so aus, evtl falsch, aber sollte ähnlich möglich sein? Experten fragen)
Code:
interface IGraphComponent<Eingabe extends MyContainer, Ausgabe extends MyContainer>{
  public void Input(Eingabe o);
  public Ausgabe Output();
}

public class TransformationXY implements IGraphComponent<
  MyContainerVector, MyContainerObjectArray>{
  
  public void Input(MyContainerVector o) {
    ..
  }
  public MyContainerObjectArray Output() {
    ..
  }
}

ich hoffe, dass es dann noch weiterhin möglich ist,
alle IGraphComponent gemeinsam anzusprechen, was ja der eigentliche Sinn ist,

eine Alternative ohne Generics bildet das Konstrukt



Code:
interface IGraphComponent {
  public void Input(MyContainero);
  public MyContainerOutput();
}

public class TransformationXY implments IGraphComponent{

  public void Input(MyContainer o) {
    ..
  }
  public MyContainer Output() {
    ..
  }

 // zusätzlich
  public void Input(MyContainerVector o) {
    Input(o);
  }
  public MyContainerObjectArray Output() {
    return (MyContainerObjectArray ) Output;
  }
}

was wohl ein wenig dem Nachbau der Generics entspricht,
in einer bestimmten Programmsituation,
wo du also weißt, dass der Typ MyContainerVector vorliegt und genau TransformationXY der nächste Schritt ist,
könntest du also eine typsichere Objektübergabe machen

etwas allgemeiner und wiederverwendbarer wirds ohne Generics mit Zwischeninterfacen,
Code:
public interface MyContainerObjectArrayOutputter {
 public MyContainerObjectArray Output();
}

public class TransformationXY implments IGraphComponent,
  MyContainerVectorInputter, MyContainerObjectArrayOutputter {
  ..
}

war das deine Frage? ;)
 

RTC

Mitglied
Hallo Slater.

Danke erstmal für deine Antwort - das bringt erstes Licht ins Dunkel :)

SlaterB hat gesagt.:
falls die Klassen bekannt sind,
kann du die Strings auch dynamisch erstellen:
static String[] classnames = {KlasseXY.class.getSimpleName(), ..};

Sieht ganz nach dem aus was ich gesucht habe. Auf jeden Fall eine Überlegung wert.

SlaterB hat gesagt.:
manchmal sieht man den Wald vor lauter Interfaces nicht,
so schön das Design am Ende auch wird,
am Anfang würde ich mit 1-2 Algorithmen und 1-2 Transformationen anfangen,
so dass als Übergabetyp eben nicht gleich Object stehen muss, sondern vielleicht erstmal mal Vector
(oder besser ArrayList, wenn nicht synchronisiert werden muss) oder ein eigener Datentyp steht

Mag sein dass es am Ende unübersichtlich wird, aber ich bin zuversichtlich. Ich denke nicht dass es Vorteile mit sich bringt jetzt erstmal das Ganze auf speziell zu trimmen und dann zu verallgemeinern. Darum werde ich auch gleich auf allgemein setzen.

SlaterB hat gesagt.:
überhaupt könntest du dir überlegen, zum Transport jeglicher Art von Daten einen eigenen Datentyp zur Kapselung verwenden,
der dann sinnvolle allgemeine Operation wie getType(), getAcceptedTransformations(), getAcceptedOperations(),
historyOfFormerTransformations() usw. enthält

Gute Idee, danke.

SlaterB hat gesagt.:
ich hoffe, dass es dann noch weiterhin möglich ist,
alle IGraphComponent gemeinsam anzusprechen, was ja der eigentliche Sinn ist

Wohl wahr. Wenn das ginge, dann wäre das die Lösung meiner Probleme. Natürlich müsste ich unterscheiden können, welchen Datentypen die Template-Klassen "Eingabe" und "Ausgabe" zur Laufzeit tatsächlich haben. Lässt sich das über "if(Eingabe is Datentyp)" realisieren?

Was ich will ist ja z.B. dass der Benutzer 2 Algorithmen-Komponenten wie ImgProc und NeuralNet zum Netz hinzufügt und bei der Verbindung zwischen beiden genau zwischen den Klassen wählen kann, die eine geeignete Datentransformation bereitstellen.


Nochmal danke für die Hilfe - ich hoffe, dass das so realisierbar ist. Ansonsten melde ich mich bald wieder ^^.
Gruß,
Matthias
 
S

SlaterB

Gast
bei Generics sicher
Eingabe extends MyContainer,
dass Eingabe eine Unterklasse/ Unterinterface von MyContainer ist,

ansonsten wie gesagt mit Zwischeninterface arbeiten,
für die Container bedeutet das dann auch eine Vererbungshierarchie

---------

allgemeiner Hinweis:
wann immer es darum geht generisch etwas zur Laufzeit aus eine Textbeschreibung oder Benutzereingaben zusammenzubauen,
dann spielt die Typsicherheit so gut wie keine Rolle mehr,
die ist eher was für eine saubere Programmierung des Quellcodes,

wichtigstes Indiz: Java-Generics sind im kompilieren Code nicht mehr enthalten, das hat da gar nix mehr mit zu tun,

mit Interfaces (Test: instanceof) oder (schlechter als Interface) Klassennamen kann man dann noch prüfen,
um Fehler im Voraus abzufangen,

aber das ist dann höchstens noch ein etwas komfortableres/ genaues System
als einfach auf den Fehler zu warten und auszugeben, dass ein Fehler aufgetreten ist ;)

naja, ganz so schwarz sieht es ja auch nicht aus
 

RTC

Mitglied
Hallo.

@Slater: Noch eine kurze Frage zu deinem vorletzten Post...

SlaterB hat gesagt.:
Code:
interface IGraphComponent<Eingabe extends MyContainer, Ausgabe extends MyContainer>{
  public void Input(Eingabe o);
  public Ausgabe Output();
}

public class TransformationXY implements IGraphComponent<
  MyContainerVector, MyContainerObjectArray>{
  
  public void Input(MyContainerVector o) {
    ..
  }
  public MyContainerObjectArray Output() {
    ..
  }
}
Gibt es eine Möglichkeit von außen (also z.B. der Testprozedur, die den Graphen für richtig oder falsch befindet) festzustellen, welche Sorten TransformationXY tatsächlich anstelle von MyContainer benutzt? Ich weiß zwar dass man allgemeine Sortenprüfung eines Objekts mit instanceof() durchführt, aber die kann man die Sorte der jeweiligen Template-Klasse herausfinden? :bahnhof:

Das wär's dann erstmal - der Rest funktioniert soweit wunderbar, vielen Dank nochmal!
MfG, Matthias
 
S

SlaterB

Gast
das wäre dann wohl

Code:
interface IGraphComponent<Eingabe extends MyContainer, Ausgabe extends MyContainer>{
  public void Input(Eingabe o);
  public Ausgabe Output();
  public Class getOutputType();
}

public class TransformationXY implements IGraphComponent<
  MyContainerVector, MyContainerObjectArray>{
 
  public void Input(MyContainerVector o) {
    ..
  }
  public MyContainerObjectArray Output() {
    ..
  }

  public Class getOutputType() {
    return MyContainerObjectArray.class;
  }

}

Klassen kann man nicht typisieren, der Rückgabewert wäre also Class,
ob das so sinnvoll ist, kommt darauf an, was genau du wie prüfen willst
 

RTC

Mitglied
SlaterB hat gesagt.:
Klassen kann man nicht typisieren, der Rückgabewert wäre also Class,
ob das so sinnvoll ist, kommt darauf an, was genau du wie prüfen willst

Z.B. könnte ich auf Namensgleichheit mittels Class.getName() prüfen, daher wäre deine vorgeschlagene Methode "getOutputType()" so schon ganz ok.

Ich weiß das ist jetzt vielleicht kleinlich, aber ohne eine solche Methode kann man das wohl nicht herausfinden? Also dass ich z.B. von außen eine Methode "TransformationXY.class.Methode" aufrufe, welche mir ein Class-Array zurückliefert, das die Class-Objekte von (hier) MyContainerVector und MyContainerObjectArray enthält? Insgesamt stellt es kein Problem dar, bedeutet aber (geringfügig) höheren Implementierungsaufwand und vll. Redundanz.

Ich hab schonmal geschaut: "TransformationXY.getClass().getGenericInterfaces()[0]" würde mir den Namen des implementierten Interfaces mit den beiden eingesetzten Template-Klassen zurückliefern, die müssten dann nur noch extrahiert werden, aber an der Stelle bin ich nicht weitergekommen. Eine String-Verarbeitung würde natürlich kein Problem darstellen, aber: unschön...

--- Matze
 

RTC

Mitglied
Tja, so würde es gehen, aber -oh mein Gott- das ist nicht wirklich mein Ernst :noe:
Code:
TransformationXY txy = new TransformationXY();
ParameterizedType t = (ParameterizedType)txy.getClass().getGenericInterfaces()[0];
String name1 = t.getActualTypeArguments()[0].toString();
String name2 = t.getActualTypeArguments()[1].toString();
Class t1 = Class.forName(name1.substring(name1.indexOf(' ')+1));
Class t2 = Class.forName(name2.substring(name2.indexOf(' ')+1));
 

RTC

Mitglied
Na ich bin ja auch verwirrt.
"Ganz einfach" geht es dann natürlich mit:
Code:
if(((ParameterizedType)comp2.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0] != ((ParameterizedType)comp1.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[1])
{
    System.out.println("Miiieeep");
}
Nicht schön, aber selten - zumindest würde ich so den Vergleich ohne zusätzliche Methoden hinkriegen ???:L
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Ernesto95 HTTP Mit JavaScript erzeugte dynamische Webseite auslesen und nach einem Schlüsselwort durchsuchen Allgemeine Java-Themen 6
districon Rekursion und Dynamische Programmierung Allgemeine Java-Themen 2
hello_autumn Statistische/dynamische Tests Allgemeine Java-Themen 10
E Socket Dynamische Klasse von ObjectOutputStream lesen. Allgemeine Java-Themen 8
P Erste Schritte Dynamische Anzahl von verschachtelten Schleifen Allgemeine Java-Themen 5
J Dynamische Rückgabewerte Allgemeine Java-Themen 2
K Dynamische Webseiten auslesen Allgemeine Java-Themen 6
S Variablen Dynamische Arrays Allgemeine Java-Themen 2
N Dynamische Objekte / DB Allgemeine Java-Themen 5
B dynamische Java Slideshow Allgemeine Java-Themen 4
SuperSeppel13 Dynamische Bibliotheken einbinden Allgemeine Java-Themen 16
B Script Problem "Dynamische Datenstruktur" Allgemeine Java-Themen 13
A Dynamische PDF Erstellung mit iText Allgemeine Java-Themen 4
ModellbahnerTT Dynamische Programmierung, komme nicht weiter.... Allgemeine Java-Themen 15
C dynamische imports? Allgemeine Java-Themen 13
hdi dynamische return-Werte Allgemeine Java-Themen 15
M JUnit und dynamische Tests Allgemeine Java-Themen 11
X dynamische bindung - Typsystem :?: Allgemeine Java-Themen 5
C dynamische variablen Namen! Allgemeine Java-Themen 4
D dynamische Objekte erzeugen? Allgemeine Java-Themen 16
G eigener logger mittels classe (dynamische logfilename) log4j Allgemeine Java-Themen 15
F dynamische ArrayListen? Allgemeine Java-Themen 8
C kann man dynamische variablen namen vergeben? Allgemeine Java-Themen 2
H "dynamische Ladegrafik" Allgemeine Java-Themen 2
C Dynamische Varibalen Allgemeine Java-Themen 3
C dynamische Vererbung Allgemeine Java-Themen 6
O Test schreiben mit Äquivalenzklassen (Aufgabe Prüfung) Allgemeine Java-Themen 9
MiMa Person in einer Arraylist hinzugügen mit Prüfung ? Allgemeine Java-Themen 6
B Java Mail: Prüfung auf neue Emails Allgemeine Java-Themen 1
S Prüfung von annotierten Funktionsparamatern Allgemeine Java-Themen 8
F Zurnung nach Buchstaben und deren Prüfung Allgemeine Java-Themen 9
B Sudoku-Block-Prüfung Allgemeine Java-Themen 1
W Suche Framework zur Prüfung von IPv4 und IPv6 Allgemeine Java-Themen 2
vandread Kleine Generics Aufgabe aus einer Prüfung... wie ist das gemeint? Allgemeine Java-Themen 6
W Best Practice String Prüfung Allgemeine Java-Themen 3
S OOP Designrichtlinie Parameter Prüfung Allgemeine Java-Themen 7
S Hardware Prüfung Allgemeine Java-Themen 13
A Probleme mit der String-Prüfung Allgemeine Java-Themen 20
A Regulärer Ausdruck EMail-Prüfung Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben