Morgen,
ich arbeite zur Zeit an einem verzwickten Algorithmus.
Dieser soll Objekte mit einander kombinieren. Dabei ist zu beachten, dass die Objekte in einer bestimmten Reihenfolge gegeben sind, geordnet nach einem Objektkriterium.
Sprachlich formuliert sieht meine Lösung erstmal folgendermaßen aus:
Hier das zu betrachtende Objekt. Das angesprochende Objektkriterium ist "j_prio". TJob hat zwar noch weitere Werte, aber die beiden reichen.
Hier die Hauptklasse:
PermutationGenerator Klasse -> Permutation Generator
Die "print(tjob_list)" Methode habe ich weggelassen, weil sie nichts mit dem Algorithmus zu tun hat.
Dann noch ein kleines Beispiel wie das ganze Arbeiten soll.
Ja, also ihr seht es bereits am Quellcode. Punkt 6. auf der Liste ist noch nicht implementiert. Ich hatte es zu erst versucht die einzelnen ArrayListen auf eine gleiche Elementanzahl zu bringen, in dem ich deren eigenen Inhalt so lange selbst eingefügt habe bis die Elementanzahl der Anzahl der TJob Objekte entsprach (was auch recht einfach ging). Problem wurde dann darauf folgend, wenn ich nun die Listen in eine neue Liste durch eine for-Schleife zusammen packen wollte, dann sah das Ergebnis folgendermaßen aus:
Der Grund ist mir durchaus bewusst, so nach mehr stündigem Überlegen, allerdings fällt mir sonst nichts weiter ein. Könntet ihr mir eine Möglichkeit aufzeigen?
ich arbeite zur Zeit an einem verzwickten Algorithmus.
Dieser soll Objekte mit einander kombinieren. Dabei ist zu beachten, dass die Objekte in einer bestimmten Reihenfolge gegeben sind, geordnet nach einem Objektkriterium.
Sprachlich formuliert sieht meine Lösung erstmal folgendermaßen aus:
- Absteigende Sortierung (QuickSort) der Objekte in einem Array nach einem Objektkriterium
- Prüfung, ob es Objekte mit dem gleichen Objektkriterium gib in der Sortierung
- Wenn false, dann gebe das Array direkt zurück und beende den Algorithmus
- Wenn true, dann weiter bei 3.
- Finde alle Objekte mit gleichem Objektkriterium und speichere sie jeweils in einer neuen ArrayList
- Berechne die Anzahl an möglichen Kombinationen
- Generiere Permutationen einer jeden neuen ArrayList (aus 3.)
- Kombinierte die Ergebnisse aus 5. mit einander
- Gebe das Ergebnis zurück und beende den Algorithmus
Hier das zu betrachtende Objekt. Das angesprochende Objektkriterium ist "j_prio". TJob hat zwar noch weitere Werte, aber die beiden reichen.
Java:
public class TJob {
private int j_id;
private int j_prio;
public TJob(int id, int prio) {
setID(id);
setPrio(prio);
}
public int getID() {
return j_id;
}
public int getPrio() {
return j_prio;
}
public void setID(int id) {
j_id = id;
}
public void setPrio(int prio) {
j_prio = prio;
}
}
Java:
public class MchCombi {
public enum Mode {
ASC, DSC
}
private static List<TJob[]> tjob_list = new ArrayList<TJob[]>();
private static void quickSort(TJob[] arr, int inf, int sup, Mode mode) {
if (inf < sup) {
int pivot = arr[(inf + sup) / 2].getPrio();
TJob aux;
int i = inf, j = sup;
while (i <= j) {
if (mode == Mode.DSC) {
while (arr[i].getPrio() > pivot)
i++;
while (arr[j].getPrio() < pivot)
j--;
} else if (mode == Mode.ASC) {
while (arr[i].getPrio() < pivot)
i++;
while (arr[j].getPrio() > pivot)
j--;
}
if (i <= j) {
aux = arr[i];
arr[i] = arr[j];
arr[j] = aux;
i++;
j--;
}
}
if (j > inf)
quickSort(arr, inf, j, mode);
if (i < sup)
quickSort(arr, i, sup, mode);
}
}
private static boolean equalCheck(TJob[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if (arr[i].getPrio() == arr[j].getPrio() && arr[i].getID() != arr[j].getID()) {
return true;
}
}
}
return false;
}
private static void findPossibilities(TJob[] arr) {
// 3. Finde alle Objekte mit gleichem Objektkriterium und speichere
// sie jeweils in einer neuen ArrayList
List<List<TJob>> equalPrio_list = new ArrayList<List<TJob>>(20);
for (int i = 0; i < arr.length; i++) {
List<TJob> equalPrio = new ArrayList<TJob>(arr.length);
for (int j = 0; j < arr.length; j++) {
if (arr[i].getPrio() == arr[j].getPrio()) {
// Check, ob TJob bereits erfasst wurde
if (!MchCombi.subListsContains(equalPrio_list, arr[j]))
equalPrio.add(arr[j]);
}
}
if (equalPrio.size() > 0)
equalPrio_list.add(equalPrio);
}
// 4. Berechne die Anzahl an möglichen Kombinationen
long count = 1L;
List<Long> fac_list = new ArrayList<Long>(10);
for (int i = 0; i < equalPrio_list.size(); i++) {
fac_list.add(MchCombi.factorial(equalPrio_list.get(i).size()));
}
for (int i = 0; i < fac_list.size(); i++)
count = count * fac_list.get(i);
// 5. Generiere Permutationen einer jeden neuen ArrayList
List<List<List<TJob>>> prio_list = new ArrayList<List<List<TJob>>>();
for (int i = 0; i < equalPrio_list.size(); i++) {
int[] indices;
List<TJob> elements = equalPrio_list.get(i);
List<List<TJob>> li = new ArrayList<List<TJob>>();
PermutationGenerator x = new PermutationGenerator(elements.size());
while (x.hasMore()) {
indices = x.getNext();
List<TJob> tj_list = new ArrayList<TJob>(10);
for (int j = 0; j < indices.length; j++)
tj_list.add(elements.get(indices[j]));
li.add(tj_list);
}
prio_list.add(li);
}
// 6. Kombinierte die Ergebnisse aus 5. mit einander
}
private static boolean subListsContains(List<List<TJob>> mainList, TJob tjob) {
for (int i = 0; i < mainList.size(); i++) {
for (int j = 0; j < mainList.get(i).size(); j++) {
if (mainList.get(i).get(j).getID() == tjob.getID())
return true;
}
}
return false;
}
private static long factorial(int n) {
long factorial = 1;
for (int i = 1; i <= n; i++)
factorial = factorial * i;
return factorial;
}
public static void main(String[] args) {
// Testwerte
TJob[] arr = { new TJob(0, 7),
new TJob(1, 6),
new TJob(2, 6),
new TJob(3, 5),
new TJob(4, 3),
new TJob(5, 3) };
MchCombi.quickSort(arr, 0, arr.length-1, Mode.DSC);
if (MchCombi.equalCheck(arr))
MchCombi.findPossibilities(arr);
else
MchCombi.tjob_list.add(arr);
//MchCombi.print(tjob_list);
}
}
Die "print(tjob_list)" Methode habe ich weggelassen, weil sie nichts mit dem Algorithmus zu tun hat.
Dann noch ein kleines Beispiel wie das ganze Arbeiten soll.
Code:
geg. sind 6 TJob Objekte, die jeweils folgende j_prio Werte haben
und in einem Array zusammengefasst sind:
TJob1(7), TJob2(6), TJob3(6), TJob4(5), TJob5(3) und TJob6(3)
Absteigende Sortierung durch QuickSort liefert als Ergebnis:
TJob1(7), TJob3(6), TJob2(6), TJob4(5), TJob6(3), TJob5(3)
Wie man gleich sehen kann, gibt es TJobs, die die gleiche j_prio
aufweisen. Diese jeweils in eine eigene ArrayListe packen:
ArrayList1 ( TJob1(7) )
ArrayList2 ( TJob3(6), TJob2(6) )
ArrayList3 ( TJob4(5) )
ArrayList4 ( TJob6(3), TJob5(3) )
Nun Permutationen aus den Elementen in den neuen ArrayListen
bilden, die mehr als 1 Element besitzen:
ArrayList1 ( ArrayListe1( TJob1(7) ) )
ArrayList2 ( ArrayListe1( TJob3(6), TJob2(6) ),
ArrayListe2( TJob2(6), TJob3(6) ) )
ArrayList3 ( ArrayListe1( TJob4(5) ) )
ArrayList4 ( ArrayListe1( TJob6(3), TJob5(3) ),
ArrayListe1( TJob5(3), TJob6(3) ) )
Nun diese ArrayListen kombinieren unter Einhaltung der Reihenfolge.
Es sollten dann 4 Kombinationen rauskommen:
Kombination 1: ArrayList( TJob1(7), TJob3(6), TJob2(6), TJob4(5), TJob6(3), TJob5(3) )
Kombination 2: ArrayList( TJob1(7), TJob2(6), TJob3(6), TJob4(5), TJob6(3), TJob5(3) )
Kombination 3: ArrayList( TJob1(7), TJob3(6), TJob2(6), TJob4(5), TJob5(3), TJob6(3) )
Kombination 4: ArrayList( TJob1(7), TJob2(6), TJob3(6), TJob4(5), TJob5(3), TJob6(3) )
Ja, also ihr seht es bereits am Quellcode. Punkt 6. auf der Liste ist noch nicht implementiert. Ich hatte es zu erst versucht die einzelnen ArrayListen auf eine gleiche Elementanzahl zu bringen, in dem ich deren eigenen Inhalt so lange selbst eingefügt habe bis die Elementanzahl der Anzahl der TJob Objekte entsprach (was auch recht einfach ging). Problem wurde dann darauf folgend, wenn ich nun die Listen in eine neue Liste durch eine for-Schleife zusammen packen wollte, dann sah das Ergebnis folgendermaßen aus:
Code:
Kombination 1: TJob1(7) TJob3(6) TJob2(6) TJob2(6) TJob3(6) TJob3(6) TJob2(6) TJob2(6) TJob3(6) TJob4(5) TJob4(5) TJob4(5) TJob4(5) TJob6(3) TJob5(3) TJob5(3) TJob6(3) TJob6(3) TJob5(3) TJob5(3) TJob6(3)
Kombination 2: TJob1(7) TJob3(6) TJob2(6) TJob2(6) TJob3(6) TJob3(6) TJob2(6) TJob2(6) TJob3(6) TJob4(5) TJob4(5) TJob4(5) TJob4(5) TJob6(3) TJob5(3) TJob5(3) TJob6(3) TJob6(3) TJob5(3) TJob5(3) TJob6(3)
Kombination 3: TJob1(7) TJob3(6) TJob2(6) TJob2(6) TJob3(6) TJob3(6) TJob2(6) TJob2(6) TJob3(6) TJob4(5) TJob4(5) TJob4(5) TJob4(5) TJob6(3) TJob5(3) TJob5(3) TJob6(3) TJob6(3) TJob5(3) TJob5(3) TJob6(3)
Kombination 4: TJob1(7) TJob3(6) TJob2(6) TJob2(6) TJob3(6) TJob3(6) TJob2(6) TJob2(6) TJob3(6) TJob4(5) TJob4(5) TJob4(5) TJob4(5) TJob6(3) TJob5(3) TJob5(3) TJob6(3) TJob6(3) TJob5(3) TJob5(3) TJob6(3)