From bed270e7d278386079abf0f7a73f7df5495644f1 Mon Sep 17 00:00:00 2001 From: i23007 Date: Thu, 4 Jul 2024 21:18:57 +0200 Subject: [PATCH] Stable Version with finished visualisation --- .idea/workspace.xml | 53 +++++++++++++----- OurApplication/OurApplication.java | 2 +- OurApplication/OurDrawArea.java | 23 +------- OurApplication/OurLogElement.java | 14 +++++ graph/DirectedGraph.java | 32 +++++++++-- graph/Display.java | 32 ----------- .../ProjektGraph/.idea/workspace.xml | 46 +++++++++++++-- .../OurApplication/OurApplication.class | Bin 3874 -> 3978 bytes .../OurApplication/OurDrawArea.class | Bin 2106 -> 1401 bytes .../OurApplication/OurLogElement.class | Bin 1213 -> 1577 bytes .../ProjektGraph/graph/DirectedGraph.class | Bin 9814 -> 11128 bytes .../ProjektGraph/graph/Display.class | Bin 2656 -> 0 bytes 12 files changed, 124 insertions(+), 78 deletions(-) delete mode 100644 graph/Display.java delete mode 100644 out/production/ProjektGraph/graph/Display.class diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 378374b..a66bbd2 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,13 +6,17 @@ + + + - - - + + + + + - - + - { + "keyToString": { + "Application.Display.executor": "Run", + "Application.OurApplication.executor": "Run", + "RunOnceActivity.ShowReadmeOnStart": "true", + "git-widget-placeholder": "main", + "kotlin-language-version-configured": "true", + "last_opened_file_path": "C:/Git/ProjektGraphMain" } -}]]> +} @@ -84,7 +88,15 @@ @@ -103,4 +115,15 @@ + + + + + file://$PROJECT_DIR$/OurApplication/OurDrawArea.java + 53 + + + + \ No newline at end of file diff --git a/OurApplication/OurApplication.java b/OurApplication/OurApplication.java index 5e502e6..432452a 100644 --- a/OurApplication/OurApplication.java +++ b/OurApplication/OurApplication.java @@ -79,7 +79,7 @@ public class OurApplication { System.out.println(myGraph.toString()); - drawArea.setCurrentGraph(myGraph); + drawArea.setCurrentGraph(myGraph.getScreenGraph()); algorithm.setCurrentGraph(myGraph); } diff --git a/OurApplication/OurDrawArea.java b/OurApplication/OurDrawArea.java index 1262424..1b3dc42 100644 --- a/OurApplication/OurDrawArea.java +++ b/OurApplication/OurDrawArea.java @@ -21,7 +21,7 @@ public class OurDrawArea extends DrawArea{ private static final long serialVersionUID = 1L; - private graph.Graph currentGraph; + private visualizationElements.Graph currentGraph; /** @@ -41,7 +41,7 @@ public class OurDrawArea extends DrawArea{ } - public void setCurrentGraph(Graph graph) { + public void setCurrentGraph(visualizationElements.Graph graph) { this.currentGraph = graph; } @@ -51,25 +51,8 @@ public class OurDrawArea extends DrawArea{ public void draw(Graphics g) { - this.currentGraph.getScreenGraph().draw(g); - OurLogElement logElement = (OurLogElement) logList.get(); - - if (logElement.getVertex() != null) { - if (logElement.getVertex().getColor() == Color.BLACK) { - logElement.getVertex().setColor(Color.YELLOW); - } else if (logElement.getVertex().getColor() == Color.YELLOW) { - logElement.getVertex().setColor(Color.BLUE); - } - } else { - if (logElement.getEdge().getColor() == Color.BLACK) { - logElement.getEdge().setColor(Color.YELLOW); - } else if (logElement.getEdge().getColor() == Color.YELLOW) { - logElement.getEdge().setColor(Color.BLUE); - } - } - - logElement.getVertex().draw(g); + logElement.getGraph().draw(g); } diff --git a/OurApplication/OurLogElement.java b/OurApplication/OurLogElement.java index 5a05dfc..a9590d2 100644 --- a/OurApplication/OurLogElement.java +++ b/OurApplication/OurLogElement.java @@ -22,6 +22,7 @@ public class OurLogElement extends LogElement{ protected long value; protected Vertex vertex; protected Edge edge; + protected visualizationElements.Graph ourGraph; /** * Standard constructor. @@ -47,12 +48,20 @@ public class OurLogElement extends LogElement{ } + public OurLogElement(int step, String description, long value, Edge e){ this.step = step; this.description = description; this.value = value; this.edge = e; } + + public OurLogElement(int step, String description, long value, visualizationElements.Graph ourGraph ){ + this.step = step; + this.description = description; + this.value = value; + this.ourGraph = ourGraph; + } /** * Returns the log element's sum up value. @@ -71,4 +80,9 @@ public class OurLogElement extends LogElement{ public Vertex getVertex() { return this.vertex; } + + + public visualizationElements.Graph getGraph() { + return this.ourGraph; + } } diff --git a/graph/DirectedGraph.java b/graph/DirectedGraph.java index 41a084a..b8d6ae0 100644 --- a/graph/DirectedGraph.java +++ b/graph/DirectedGraph.java @@ -8,6 +8,7 @@ import visualizationElements.EdgeStyle; import visualizationElements.Vertex; import java.awt.*; +import java.io.*; import java.util.HashMap; import java.util.Objects; import java.util.PriorityQueue; @@ -43,6 +44,23 @@ public class DirectedGraph exten return this.screenGraph; } + public visualizationElements.Graph getScreenGraphCopy() { + visualizationElements.Graph graphCopy = new visualizationElements.Graph(new Vector(), new Vector(), true, EdgeStyle.Direct); + Vector copiedVertexes = new Vector<>(); + Vector copiedEdges = new Vector<>(); + for (visualizationElements.Vertex vertexCopy : this.screenGraph.getVertexes()) { + visualizationElements.Vertex newCopiedVertex = new visualizationElements.Vertex(vertexCopy.getXpos(), vertexCopy.getYpos(), vertexCopy.getMarking(), vertexCopy.getColor()); + copiedVertexes.add(newCopiedVertex); + graphCopy.setVertexes(copiedVertexes); + } + for (visualizationElements.Edge edgeCopy : this.screenGraph.getEdges()) { + visualizationElements.Edge newCopiedEdge = new visualizationElements.Edge(edgeCopy.getSource(), edgeCopy.getDestination(), edgeCopy.getMarking(), edgeCopy.getColor()); + copiedEdges.add(newCopiedEdge); + graphCopy.setEdges(copiedEdges); + } + return graphCopy; + } + public LogElementList getLogList() { return this.logList; @@ -212,7 +230,6 @@ public class DirectedGraph exten int dist = 0; // Zähler für LogList int step = 0; - visualizationElements.Graph display; while (!queue.isEmpty()) { // Den nächsten Knoten, der am wenigsten kostet, besuchen @@ -224,7 +241,8 @@ public class DirectedGraph exten // Logging System.out.println("Visit " + nextVertex.getElement().getName()); - this.logList.add(new OurLogElement(step, "Step: " + step, 0, nextVertex.getElement().getScreenVertex())); + nextVertex.getElement().getScreenVertex().setColor(Color.BLUE); + this.logList.add(new OurLogElement(step, "Step: " + step, 0, this.getScreenGraphCopy())); // Gehe von diesem Knoten aus alle erreichbaren Knoten durch @@ -250,7 +268,8 @@ public class DirectedGraph exten // Logging System.out.println("Add " + i.getName() + " with " + dist + " weight to queue."); - this.logList.add(new OurLogElement(step, "Step: " + step, 0, nextVertex.getElement().getScreenVertex())); + nextVertex.getElement().getScreenVertex().setColor(Color.YELLOW); + this.logList.add(new OurLogElement(step, "Step: " + step, 0, this.getScreenGraphCopy())); // Nehme nächsten Knoten in die Queue auf queue.add(new WrapperElement<>(i, dist)); @@ -288,7 +307,6 @@ public class DirectedGraph exten int airDist = 0; // Zähler für LogList int step = 0; - visualizationElements.Graph display; while (!queue.isEmpty()) { // Den nächsten Knoten, der am wenigsten kostet, besuchen @@ -300,7 +318,8 @@ public class DirectedGraph exten // Logging System.out.println("Visit " + nextVertex.getElement().getName()); - this.logList.add(new OurLogElement(step, "Step: " + step, 0, nextVertex.getElement().getScreenVertex())); + nextVertex.getElement().getScreenVertex().setColor(Color.BLUE); + this.logList.add(new OurLogElement(step, "Step: " + step, 0, this.getScreenGraphCopy())); // Gehe von diesem Knoten aus alle erreichbaren Knoten durch @@ -330,7 +349,8 @@ public class DirectedGraph exten // Logging System.out.println("Add " + i.getName() + " with " + dist + " weight to queue."); - this.logList.add(new OurLogElement(step, "Step: " + step, 0, nextVertex.getElement().getScreenVertex())); + nextVertex.getElement().getScreenVertex().setColor(Color.YELLOW); + this.logList.add(new OurLogElement(step, "Step: " + step, 0, this.getScreenGraphCopy())); // Nehme nächsten Knoten in die Queue auf queue.add(new WrapperElement<>(i, dist)); diff --git a/graph/Display.java b/graph/Display.java deleted file mode 100644 index 93a3861..0000000 --- a/graph/Display.java +++ /dev/null @@ -1,32 +0,0 @@ -package graph; - -import java.util.Random; - -public class Display { - - public static void main(String[] args) { - DirectedGraph myGraph = new DirectedGraph<>(); - - for (int i = 0; i < 10; i++) { - myGraph.addVertex(new MarkedVertex<>(String.valueOf(i), null)); - } - Random random = new Random(); - - for (MarkedVertex i: myGraph.getAllVertexes()) { - myGraph.addEdge(new MarkedEdge<>("a", i, myGraph.getAllVertexes().get(random.nextInt(myGraph.getAllVertexes().size())), null, random.nextInt(1, 10))); - } - - for (MarkedVertex i: myGraph.getAllVertexes()) { - myGraph.addEdge(new MarkedEdge<>("a", i, myGraph.getAllVertexes().get(random.nextInt(myGraph.getAllVertexes().size())), null, random.nextInt(1, 10))); - } - - System.out.println(myGraph.toString()); - - MarkedVertex start = myGraph.getAllVertexes().get(random.nextInt(myGraph.getAllVertexes().size())); - MarkedVertex end = myGraph.getAllVertexes().get(random.nextInt(myGraph.getAllVertexes().size())); - System.out.println(start.getName() + " to " + end.getName()); - - System.out.println(myGraph.getShortestPathDijkstra(start, end)); - - } -} diff --git a/out/production/ProjektGraph/.idea/workspace.xml b/out/production/ProjektGraph/.idea/workspace.xml index 7dfa0db..15310ea 100644 --- a/out/production/ProjektGraph/.idea/workspace.xml +++ b/out/production/ProjektGraph/.idea/workspace.xml @@ -4,11 +4,10 @@ + + + + \ No newline at end of file diff --git a/out/production/ProjektGraph/OurApplication/OurApplication.class b/out/production/ProjektGraph/OurApplication/OurApplication.class index a6f780d18e0e1d59138703393833a57c330f8356..1e89cfabc1dc66b326cc528861fc329ca1242f02 100644 GIT binary patch delta 540 zcmaKoJ4};N7>1v(wEp$)U%)x5U9nb+R>AuXyx%XQ8zwF;x}b0SGrN4}eCNF1^SW+$aMoxa^UEXqi@smjSM?*$^RQ&+c^Ic@}iP(#`{ z*ibF+Wo%uYbBRd8t#hdf3sbAi#t%+q8L{o`ZJ~}yev%9~X%OQV1KQn^fe_qgUQiw{L%T4}nHL!uGUPoyMHQJV8UoP|tAFh~M8cFx>3# z9_%w@mbUf&XBDx!wyev>$DGAdq|R%5Of=Bqlw>cGAUhNdNhB*S2gaP7nvi;SY*vVe zB34v8nj+OIYkE@%v;MEwa#Y$hFb$DM$2IA`B%i&-LRcyfp+IhW|ENocsi!mMGcN56 zE)h0J<%=q1n{wAaTST?xH7?ui$UW0kvdf-G@=P)N9FRz{$>WeCc~_V$jyVyNYrLFt zrXRHO%{doXy7tK>S9qCh7wk1Rf}SGCEq4OG*P(Km!~q@z5I_5T)BBcsxKQ!jz{Kjh0 diff --git a/out/production/ProjektGraph/OurApplication/OurDrawArea.class b/out/production/ProjektGraph/OurApplication/OurDrawArea.class index 55b077761ad6fcea53bb08982dde1cad567a028a..a1874825510fdcd7dbc3d74e4ddc980d8682a65c 100644 GIT binary patch delta 555 zcmZ9J$xZ@66h&{*HZ4ty6Cw^sJ2Esl;D95>r3T%YxKJ0mAn3*zf@{8k)L*#LL?I#3 zxHc|a`U`%78{@5ppfR1UdhhkE^KQLv^n97->v!WBzz(*n=B+1^m$n%3Z}{LxuZ2GJ z%Yujn1`skZXd#Rtfl&1zB=1C2jL3H}9vDW%!Wg0goy9`A`kC;LW5U3sg(*zSh{(w^ zEh9g)w=Un|W%25~d{Zh2>{s()`P8wi+3{A(#F2nrES+Cp$Wwh!)^w*bgBS$jwC6#B zZvfqlJ6O}<ny+ekCAnj*|%j+p}Zs8E0tXnX)8>7?o~ z6hecGsJM(cTP0kE-PE-hJfY^}at+L5f$9toH#@0s%Gweu9xO9jL6)oPm}5n`^Cq1~ znEySe>222SR|z#`?S@{gasukU9Bm7BOpUT1Og^BehTsc^_fs{DIyKn8=zyzP;a|+7WYIhqY@!ecVoa{cFi02v=WhyVZp literal 2106 zcmb7FTXz~&6#h;_m_Q~iCKZ$Pl6Z?iE~u#?7K{R+ZPH27N<*#nHX$ROh5&13XseGt zn*Y&0o27IuA6!29;BRud{Lak45F6?e7Bgqx_x|=in?L{l^)~={)S@_pAq627!w3t+ zADMPrubZ~+n9W9d-O?ZDEkhRw=gfxbtO*Pyk`-w*A}t~UiwUjXtkuj$Ev+?crMhuw zG#t&eovijyf261DIwfVtqCz%ViC`3}f-x0maZX@*r)}k1t-4wD;*ktOs@1k-(b;uN zZ#@tg(`xdNcFAlMuV7rkgo^WcRbaGFCUCZ9IOVEk7!BWcCXv+q%D#6a`FYwsZ?9oe z!IX+=ToAbM5?z7NK2af539mr?vEz9$tF~X^B^8%3BcKo&35CGqAdsSX9d9UjQ^i|& zn@&&1lCZNRf%B{*Ky_#Dp;2|R3f>X8_#%=)JEE9FQbh{$0uef@7?xu^5ttnai>E=9 z7qO%ut>Rt0#~`QU(segN*TrVNX$g#X6P4(=yle!^xT4?#6)VWFM{XTGvA}Ra%NK77 z!~$3Y!w*$ll~&<Mt(>@Je4=vHX&owPyCn%mQN=n+ zY!EXp?bi%}%LAd1asqK(0&#;QdpZVEODg4LYLl$OHY`)G6B?TrX?J5?Kx}e|i_M1Z z=nbc$*W1Q0@1Xn$wxw*=8oJZAm`kRA(sMrHfxM+#2l6KQOc}MyTFbJ)VsoDk&S_@D z*lr*08P*+ruTIXm)~qrcojH;AnIY$aX|t=^i?h?ch4iV)ahFSATR(I?1q0|`YmV(n z_usX;Ayx;>eeRT)!MtW=En9;Y%YWMTU6J16At-WAPHdD|q9179T@InUM+B~(5dDuH zNGGBuFcD0#yMyF%5Qy@6`>Tf|_i_w4EM-Tp9&G6?zhBXEvu#z4Yo_dItZ!E?$(C@D zjB+o7ziHfr214jk+vITDlD_5Aw-Mr*>z>a~$yw%G@I9P*4)K$#Qsz@Gd0>Xhv$(^P z>M3Ct6;jecgc{PpeGKsnD5?2{=TM}JAp|ZGjFfa;%zA3R3mV8Z>AF>L7oXAHJ=%JK zr0jFbyqxdz^aZ~31K#3WCKpc4|AOeh<1I3^B{yE&)9S?w<0}`3Ad2MN?nU{UC;kEO z$+Cp|*T^VGsh<(;AU5AYoX3kD%>ItKt%VK}e;^}Y9V{H<{ildY;uxzPWS?QXCs}=p zyeIkCm0TfF=-^tRsS8!sWt{hmXH zOK}}*EGo~^3OGO!PssTJH}E4i``U2SgXIX{Kxff$w6TXOLEESAQH1_NM#0?FRGdPC ItTXub9|NWY&j0`b diff --git a/out/production/ProjektGraph/OurApplication/OurLogElement.class b/out/production/ProjektGraph/OurApplication/OurLogElement.class index 5c5356a7b5315bb24ea927eae283676ec39ef0e7..8312e760fbe2bfeb7cd971920d9bd9b4a67a7dc0 100644 GIT binary patch delta 639 zcmZvZ%Syvg7=-7fiKZdgMM0Zt?ZsB@%~VaRQm-I%BZ!;s1w}Wa6x|8>3UXe+tqaA1 zD?uN?jZfjmcTk*@rbXIr&W)MxpG@Au54QF3`}z)G2i3L}5wS2#Oxs8zC19RkwHmF% zi&KHb-Oq&KpJhyZ3Qs;`KJ65XSR8Ad>M$7vZ6VGdS5FEU0!QWR98?=G9h4K zglk&fYm;t;MH)22k@KqXW-kGLvvHR4u?TP1F7C@znw09WYY68*S3 zaqGlw5VuL(7IE9da5t(Om9EIIVKa>4GMH+>D7;|wk%vxBRUFXxSCP@HsLTqwX3;Y{ v&wb{-L9<1*%i`2exz)#yR3n{92ZLg&7O|wXRJq){F%$ihnnTUYeje`+WcNao delta 436 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 I%dH6gHy;UpWB>pF literal 9814 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 J=lBwR{{RU$xlI57