Compare commits
16 Commits
2da192b76d
...
9f5e04d11d
Author | SHA1 | Date | |
---|---|---|---|
|
9f5e04d11d | ||
|
8e17de3392 | ||
|
d4ba6c78d4 | ||
|
97ccd4d66b | ||
|
22ffd96380 | ||
|
4753ba5aa9 | ||
|
76c66440d6 | ||
|
29328c2288 | ||
|
136c78cd9d | ||
|
3ac16301fb | ||
|
8f28761776 | ||
|
8d87ca5aab | ||
|
7a81bd5dc8 | ||
|
7242c5985f | ||
|
d6a0ddcd8d | ||
|
e0932b4721 |
@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="CS3642-Artificial_Intelligence [javafx:run]" type="MavenRunConfiguration" factoryName="Maven" nameIsGenerated="true">
|
<configuration default="false" name="CS3642-Artificial_Intelligence [javafx:run]" type="MavenRunConfiguration" factoryName="Maven" activateToolWindowBeforeRun="false" nameIsGenerated="true">
|
||||||
<MavenSettings>
|
<MavenSettings>
|
||||||
<option name="myGeneralSettings" />
|
<option name="myGeneralSettings" />
|
||||||
<option name="myRunnerSettings" />
|
<option name="myRunnerSettings" />
|
||||||
<option name="myRunnerParameters">
|
<option name="myRunnerParameters">
|
||||||
<MavenRunnerParameters>
|
<MavenRunnerParameters>
|
||||||
|
<option name="cmdOptions" />
|
||||||
<option name="profiles">
|
<option name="profiles">
|
||||||
<set />
|
<set />
|
||||||
</option>
|
</option>
|
||||||
@ -17,6 +18,9 @@
|
|||||||
<option name="profilesMap">
|
<option name="profilesMap">
|
||||||
<map />
|
<map />
|
||||||
</option>
|
</option>
|
||||||
|
<option name="projectsCmdOptionValues">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
<option name="resolveToWorkspace" value="false" />
|
<option name="resolveToWorkspace" value="false" />
|
||||||
<option name="workingDirPath" value="$PROJECT_DIR$" />
|
<option name="workingDirPath" value="$PROJECT_DIR$" />
|
||||||
</MavenRunnerParameters>
|
</MavenRunnerParameters>
|
||||||
|
126919
null/AStar.txt
Normal file
4
pom.xml
@ -17,12 +17,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjfx</groupId>
|
<groupId>org.openjfx</groupId>
|
||||||
<artifactId>javafx-controls</artifactId>
|
<artifactId>javafx-controls</artifactId>
|
||||||
<version>18.0.2</version>
|
<version>21-ea+24</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjfx</groupId>
|
<groupId>org.openjfx</groupId>
|
||||||
<artifactId>javafx-fxml</artifactId>
|
<artifactId>javafx-fxml</artifactId>
|
||||||
<version>18.0.2</version>
|
<version>21-ea+24</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
|
@ -1,152 +0,0 @@
|
|||||||
package Assignments.A1;
|
|
||||||
|
|
||||||
// Potentially will be changed to an UI Implementation with JavaFX if time permits.
|
|
||||||
|
|
||||||
import Assignments.A1.models.Board;
|
|
||||||
import Assignments.A1.models.BoardGenerator;
|
|
||||||
import Assignments.A1.models.BoardNode;
|
|
||||||
import Assignments.A1.solving_algorithms.DFS;
|
|
||||||
import Assignments.A1.solving_algorithms.comparators.AStar;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Board will be used to save locations in a 2D array.
|
|
||||||
* <p>
|
|
||||||
* The design of the board locations will be numbered like so:
|
|
||||||
* 0 1 2
|
|
||||||
* 3 4 5
|
|
||||||
* 6 7 8
|
|
||||||
* <p>
|
|
||||||
* 1 2 3
|
|
||||||
* 8 0 4
|
|
||||||
* 7 6 5
|
|
||||||
* <p>
|
|
||||||
* The values will be specified with an int. Must be between (inclusive) 1-8.
|
|
||||||
* The empty spot will be represented with null.
|
|
||||||
*/
|
|
||||||
public class Driver {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
ArrayList<Long> timer = new ArrayList<>();
|
|
||||||
int successes = 0;
|
|
||||||
int runs = 1;
|
|
||||||
BoardNode node = null;
|
|
||||||
for (int run = 0; run < runs; run++) {
|
|
||||||
Board board = BoardGenerator.generateBoard();
|
|
||||||
DFS solver = new DFS();
|
|
||||||
// BFS solver = new BFS();
|
|
||||||
// UCS solver = new UCS();
|
|
||||||
// AStar solver = new AStar();
|
|
||||||
Date start = new Date();
|
|
||||||
BoardNode result = solver.traverse(board);
|
|
||||||
Date end = new Date();
|
|
||||||
if (result.board != null) {
|
|
||||||
long runtime = end.getTime() - start.getTime();
|
|
||||||
|
|
||||||
timer.add(runtime);
|
|
||||||
successes++;
|
|
||||||
node = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
long total = 0;
|
|
||||||
for (int i = 0; i < timer.size(); i++) {
|
|
||||||
total += timer.get(i);
|
|
||||||
System.out.println("Run " + (i + 1) + ": " + timer.get(i));
|
|
||||||
}
|
|
||||||
long average = total / (long) timer.size();
|
|
||||||
System.out.println("Average Runtime: " + average);
|
|
||||||
System.out.println("Number of successful solves: " + successes + "/" + runs);
|
|
||||||
|
|
||||||
StringBuffer result = printTotalHierarchy(node);
|
|
||||||
writeToFile("AStar", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// public static void main(String[] args) {
|
|
||||||
// int[] values = {1, 2, 3, 8, 0, 5, 4, 7, 6};
|
|
||||||
// BoardNode node = new BoardNode(new Board(values), null);
|
|
||||||
// System.out.println(node.heuristic);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
private static StringBuffer printTotalHierarchy(BoardNode root, int depth, boolean hasMoreChildren) {
|
|
||||||
StringBuffer output = new StringBuffer();
|
|
||||||
for (int i = 0; i < depth - 1; i++) {
|
|
||||||
output.append("│ ");
|
|
||||||
}
|
|
||||||
if (hasMoreChildren) {
|
|
||||||
output.append("├── ").append(root.board.toString()).append(System.lineSeparator());
|
|
||||||
} else {
|
|
||||||
output.append("└── ").append(root.board.toString()).append(System.lineSeparator());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < root.children.size(); i++) {
|
|
||||||
if (i == root.children.size() - 1) {
|
|
||||||
output.append(printTotalHierarchy(root.children.get(i), depth+1, false));
|
|
||||||
} else {
|
|
||||||
output.append(printTotalHierarchy(root.children.get(i), depth+1, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StringBuffer printTotalHierarchy(BoardNode solved) {
|
|
||||||
BoardNode root = null;
|
|
||||||
while (solved.parent != null) {
|
|
||||||
solved = solved.parent;
|
|
||||||
}
|
|
||||||
root = solved;
|
|
||||||
|
|
||||||
StringBuffer output = new StringBuffer();
|
|
||||||
output.append(root.board.toString()).append(System.lineSeparator());
|
|
||||||
if (root.children.size() == 1) {
|
|
||||||
output.append(printTotalHierarchy(root.children.get(0), 1, false));
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < root.children.size(); i++) {
|
|
||||||
if (i == root.children.size() - 1) {
|
|
||||||
output.append(printTotalHierarchy(root.children.get(i), 1, false));
|
|
||||||
} else {
|
|
||||||
output.append(printTotalHierarchy(root.children.get(i), 1, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void writeToFile(String name, StringBuffer values) {
|
|
||||||
URL resourcePath = Driver.class.getResource("/A1/results/" + name + ".txt");
|
|
||||||
URI resourceURI = URI.create(resourcePath.toString());
|
|
||||||
File resource = new File(resourceURI.getPath());
|
|
||||||
|
|
||||||
try (FileWriter out = new FileWriter(resource)) {
|
|
||||||
out.write(values.toString());
|
|
||||||
System.out.println("Data written to file: " + name + ".txt");
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Error writing to file: " + e.getMessage());
|
|
||||||
}
|
|
||||||
openDirectoryFile(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void openDirectoryFile(File open) {
|
|
||||||
if (!Desktop.isDesktopSupported() || !Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
|
|
||||||
System.out.println("Desktop is not supported");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Desktop desktop = Desktop.getDesktop();
|
|
||||||
try {
|
|
||||||
desktop.open(open);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,9 +1,18 @@
|
|||||||
package Assignments.A1;
|
package Assignments.A1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launches the MainScene
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public class GUILauncher {
|
public class GUILauncher {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is used to prevent the issue of "missing javafx toolkit"
|
||||||
|
* @param args - the program args.
|
||||||
|
*/
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
GUIDriver.main(args);
|
MainScene.main(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,13 @@ import javafx.scene.Parent;
|
|||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
public class GUIDriver extends Application {
|
/**
|
||||||
|
* The main Scene that is ran by GUILauncher to fix VM argument requirements.
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
|
public class MainScene extends Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage stage) throws Exception {
|
public void start(Stage stage) throws Exception {
|
@ -3,14 +3,29 @@ package Assignments.A1.models;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to represent a board on a spanning tree.
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public class BoardNode implements Comparable<BoardNode> {
|
public class BoardNode implements Comparable<BoardNode> {
|
||||||
|
|
||||||
|
/* Fields used to hold each node's data. */
|
||||||
public BoardNode parent;
|
public BoardNode parent;
|
||||||
public int heuristic, cost, expected;
|
|
||||||
public Board board;
|
public Board board;
|
||||||
public List<BoardNode> children;
|
public List<BoardNode> children;
|
||||||
public int depth = -1;
|
public int heuristic, cost, expected, depth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to create a board with a parent and child nodes.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @param board the board representing the node.
|
||||||
|
* @param parent the parent node, can be null.
|
||||||
|
*/
|
||||||
public BoardNode(Board board, BoardNode parent) {
|
public BoardNode(Board board, BoardNode parent) {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
@ -20,10 +35,40 @@ public class BoardNode implements Comparable<BoardNode> {
|
|||||||
this.children = new ArrayList<>();
|
this.children = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDepth(int depth) {
|
/**
|
||||||
this.depth = depth;
|
* adds a child to the node.
|
||||||
|
*
|
||||||
|
* @precondition child != null
|
||||||
|
* @postcondition the child is added..
|
||||||
|
*/
|
||||||
|
public void addChild(BoardNode node) {
|
||||||
|
children.add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Overrides */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the Object compareTo method. Is a placehold for specifying priority in queues.
|
||||||
|
* Default: BFS
|
||||||
|
*
|
||||||
|
* @param o the object to be compared.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compareTo(BoardNode o) { // BFS
|
||||||
|
return Integer.compare(this.heuristic, o.heuristic);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the board in a single string (no line breaks)
|
||||||
|
* @return the formatting string
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.board.toString().replaceAll("\n", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Private Classes: End of JavaDocs */
|
||||||
|
|
||||||
private int getActualCost() {
|
private int getActualCost() {
|
||||||
if (this.parent != null) {
|
if (this.parent != null) {
|
||||||
return this.parent.cost + 10;
|
return this.parent.cost + 10;
|
||||||
@ -32,10 +77,6 @@ public class BoardNode implements Comparable<BoardNode> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addChild(BoardNode node) {
|
|
||||||
children.add(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getHeuristic() {
|
private int getHeuristic() {
|
||||||
int cost = 0;
|
int cost = 0;
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
@ -83,14 +124,4 @@ public class BoardNode implements Comparable<BoardNode> {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(BoardNode o) { // BFS
|
|
||||||
return Integer.compare(this.heuristic, o.heuristic);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.board.toString().replaceAll("\n", " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import Assignments.A1.models.Board;
|
|||||||
*/
|
*/
|
||||||
public class Move {
|
public class Move {
|
||||||
|
|
||||||
private Board board;
|
private final Board board;
|
||||||
private final Pair<Integer> points;
|
private final Pair<Integer> points;
|
||||||
private boolean used;
|
private boolean used;
|
||||||
|
|
||||||
|
@ -3,9 +3,32 @@ package Assignments.A1.models.helper;
|
|||||||
import Assignments.A1.models.Board;
|
import Assignments.A1.models.Board;
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
|
|
||||||
import java.util.Comparator;
|
/**
|
||||||
|
* Interface used for implementing a solver when there are multiple different variations and classes.
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public interface Solver {
|
public interface Solver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of nodes from the previous iterations.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @return the number of nodes from the interation.
|
||||||
|
*/
|
||||||
|
int getNumOfNodes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves for, finds and creates a spanning representing the solving pattern.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @param root the first node/initial start.
|
||||||
|
* @return the solved leaf node.
|
||||||
|
*/
|
||||||
BoardNode traverse(Board root);
|
BoardNode traverse(Board root);
|
||||||
}
|
}
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
Run from #e13806a1: (Time in Milliseconds)
|
|
||||||
Run 1: 279
|
|
||||||
Run 2: 280
|
|
||||||
Run 3: 159
|
|
||||||
Run 4: 178
|
|
||||||
Run 5: 165
|
|
||||||
Run 6: 249
|
|
||||||
Run 7: 229
|
|
||||||
Run 8: 138
|
|
||||||
Run 9: 147
|
|
||||||
Run 10: 135
|
|
||||||
Run 11: 151
|
|
||||||
Run 12: 130
|
|
||||||
Run 13: 140
|
|
||||||
Run 14: 132
|
|
||||||
Run 15: 142
|
|
||||||
Run 16: 131
|
|
||||||
Run 17: 146
|
|
||||||
Run 18: 139
|
|
||||||
Run 19: 145
|
|
||||||
Run 20: 143
|
|
||||||
Run 21: 150
|
|
||||||
Run 22: 154
|
|
||||||
Run 23: 146
|
|
||||||
Run 24: 148
|
|
||||||
Run 25: 144
|
|
||||||
Run 26: 142
|
|
||||||
Run 27: 148
|
|
||||||
Run 28: 152
|
|
||||||
Run 29: 128
|
|
||||||
Run 30: 140
|
|
||||||
Run 31: 130
|
|
||||||
Run 32: 160
|
|
||||||
Run 33: 131
|
|
||||||
Run 34: 143
|
|
||||||
Run 35: 134
|
|
||||||
Run 36: 147
|
|
||||||
Run 37: 195
|
|
||||||
Run 38: 204
|
|
||||||
Run 39: 142
|
|
||||||
Run 40: 151
|
|
||||||
Run 41: 149
|
|
||||||
Run 42: 133
|
|
||||||
Run 43: 143
|
|
||||||
Run 44: 148
|
|
||||||
Run 45: 146
|
|
||||||
Run 46: 143
|
|
||||||
Run 47: 129
|
|
||||||
Run 48: 143
|
|
||||||
Run 49: 151
|
|
||||||
Run 50: 141
|
|
||||||
Run 51: 144
|
|
||||||
Run 52: 133
|
|
||||||
Run 53: 145
|
|
||||||
Run 54: 140
|
|
||||||
Run 55: 140
|
|
||||||
Run 56: 147
|
|
||||||
Run 57: 131
|
|
||||||
Run 58: 145
|
|
||||||
Run 59: 139
|
|
||||||
Run 60: 146
|
|
||||||
Run 61: 147
|
|
||||||
Run 62: 126
|
|
||||||
Run 63: 151
|
|
||||||
Run 64: 131
|
|
||||||
Run 65: 141
|
|
||||||
Run 66: 146
|
|
||||||
Run 67: 133
|
|
||||||
Run 68: 143
|
|
||||||
Run 69: 130
|
|
||||||
Run 70: 149
|
|
||||||
Run 71: 145
|
|
||||||
Run 72: 140
|
|
||||||
Run 73: 145
|
|
||||||
Run 74: 130
|
|
||||||
Run 75: 140
|
|
||||||
Run 76: 159
|
|
||||||
Run 77: 148
|
|
||||||
Run 78: 150
|
|
||||||
Run 79: 127
|
|
||||||
Run 80: 146
|
|
||||||
Run 81: 144
|
|
||||||
Run 82: 140
|
|
||||||
Run 83: 140
|
|
||||||
Run 84: 129
|
|
||||||
Run 85: 145
|
|
||||||
Run 86: 137
|
|
||||||
Run 87: 145
|
|
||||||
Run 88: 144
|
|
||||||
Run 89: 127
|
|
||||||
Run 90: 140
|
|
||||||
Run 91: 131
|
|
||||||
Run 92: 153
|
|
||||||
Run 93: 137
|
|
||||||
Run 94: 133
|
|
||||||
Run 95: 144
|
|
||||||
Run 96: 128
|
|
||||||
Run 97: 149
|
|
||||||
Run 98: 150
|
|
||||||
Run 99: 145
|
|
||||||
Run 100: 144
|
|
||||||
Average Runtime: 148
|
|
||||||
Number of successful solves: 100/100
|
|
@ -1,103 +0,0 @@
|
|||||||
Run from #d8bea791: (Time in Milliseconds)
|
|
||||||
Run 1: 5677
|
|
||||||
Run 2: 1012
|
|
||||||
Run 3: 17058
|
|
||||||
Run 4: 11860
|
|
||||||
Run 5: 45404
|
|
||||||
Run 6: 10
|
|
||||||
Run 7: 10250
|
|
||||||
Run 8: 29170
|
|
||||||
Run 9: 26660
|
|
||||||
Run 10: 22485
|
|
||||||
Run 11: 5372
|
|
||||||
Run 12: 28510
|
|
||||||
Run 13: 1269
|
|
||||||
Run 14: 37239
|
|
||||||
Run 15: 3
|
|
||||||
Run 16: 36978
|
|
||||||
Run 17: 38774
|
|
||||||
Run 18: 42041
|
|
||||||
Run 19: 662
|
|
||||||
Run 20: 2951
|
|
||||||
Run 21: 11334
|
|
||||||
Run 22: 1581
|
|
||||||
Run 23: 1738
|
|
||||||
Run 24: 2604
|
|
||||||
Run 25: 17161
|
|
||||||
Run 26: 5572
|
|
||||||
Run 27: 14
|
|
||||||
Run 28: 8316
|
|
||||||
Run 29: 25494
|
|
||||||
Run 30: 7669
|
|
||||||
Run 31: 43046
|
|
||||||
Run 32: 20427
|
|
||||||
Run 33: 16146
|
|
||||||
Run 34: 30095
|
|
||||||
Run 35: 11381
|
|
||||||
Run 36: 0
|
|
||||||
Run 37: 1366
|
|
||||||
Run 38: 10928
|
|
||||||
Run 39: 529
|
|
||||||
Run 40: 10643
|
|
||||||
Run 41: 19734
|
|
||||||
Run 42: 3631
|
|
||||||
Run 43: 17513
|
|
||||||
Run 44: 3892
|
|
||||||
Run 45: 21224
|
|
||||||
Run 46: 105
|
|
||||||
Run 47: 30568
|
|
||||||
Run 48: 5313
|
|
||||||
Run 49: 6464
|
|
||||||
Run 50: 21124
|
|
||||||
Run 51: 31758
|
|
||||||
Run 52: 1619
|
|
||||||
Run 53: 35134
|
|
||||||
Run 54: 20679
|
|
||||||
Run 55: 98
|
|
||||||
Run 56: 2760
|
|
||||||
Run 57: 13905
|
|
||||||
Run 58: 15965
|
|
||||||
Run 59: 39522
|
|
||||||
Run 60: 2
|
|
||||||
Run 61: 2293
|
|
||||||
Run 62: 41910
|
|
||||||
Run 63: 17853
|
|
||||||
Run 64: 2950
|
|
||||||
Run 65: 56304
|
|
||||||
Run 66: 45523
|
|
||||||
Run 67: 17346
|
|
||||||
Run 68: 10577
|
|
||||||
Run 69: 703
|
|
||||||
Run 70: 324
|
|
||||||
Run 71: 1081
|
|
||||||
Run 72: 3846
|
|
||||||
Run 73: 13315
|
|
||||||
Run 74: 28206
|
|
||||||
Run 75: 47831
|
|
||||||
Run 76: 7488
|
|
||||||
Run 77: 12499
|
|
||||||
Run 78: 17101
|
|
||||||
Run 79: 7968
|
|
||||||
Run 80: 8936
|
|
||||||
Run 81: 1494
|
|
||||||
Run 82: 0
|
|
||||||
Run 83: 19235
|
|
||||||
Run 84: 15755
|
|
||||||
Run 85: 4979
|
|
||||||
Run 86: 22015
|
|
||||||
Run 87: 11589
|
|
||||||
Run 88: 27377
|
|
||||||
Run 89: 16111
|
|
||||||
Run 90: 25775
|
|
||||||
Run 91: 7022
|
|
||||||
Run 92: 27261
|
|
||||||
Run 93: 6351
|
|
||||||
Run 94: 26618
|
|
||||||
Run 95: 4594
|
|
||||||
Run 96: 13039
|
|
||||||
Run 97: 23729
|
|
||||||
Run 98: 16315
|
|
||||||
Run 99: 35539
|
|
||||||
Run 100: 2126
|
|
||||||
Average Runtime: 15314
|
|
||||||
Number of successful solves: 100/100
|
|
@ -9,6 +9,6 @@ package Assignments.A1.resources;
|
|||||||
public class Parameters {
|
public class Parameters {
|
||||||
|
|
||||||
/* Used to prevent DFS from going down only 1 branch */
|
/* Used to prevent DFS from going down only 1 branch */
|
||||||
public static final int MAX_DEPTH = 100; // Max number of moves in 8-Puzzle's are 31 moves if solvable.
|
public static final int MAX_DEPTH = 150; // Max number of moves in 8-Puzzle's are 31 moves if solvable.
|
||||||
|
|
||||||
}
|
}
|
@ -4,20 +4,37 @@ import Assignments.A1.models.*;
|
|||||||
import Assignments.A1.models.helper.Move;
|
import Assignments.A1.models.helper.Move;
|
||||||
import Assignments.A1.models.helper.Solver;
|
import Assignments.A1.models.helper.Solver;
|
||||||
import Assignments.A1.resources.Parameters;
|
import Assignments.A1.resources.Parameters;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to evaluate a generated SpanningTree of BoardNodes with respect to DFS LIFO.
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public class DFS implements Solver {
|
public class DFS implements Solver {
|
||||||
|
|
||||||
|
/* Private Fields for Searching */
|
||||||
private final Board solved = new Board();
|
private final Board solved = new Board();
|
||||||
private final List<String> tried = new ArrayList<>();
|
private final List<String> tried = new ArrayList<>();
|
||||||
|
private int numOfNodes = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traverses through a Board using a Stack, allowing for DFS LIFO.
|
||||||
|
*
|
||||||
|
* @precondition root != null
|
||||||
|
* @postcondition the spanning tree is created.
|
||||||
|
*
|
||||||
|
* @param root the first node/initial start.
|
||||||
|
* @return the leaf node that is solved.
|
||||||
|
*/
|
||||||
public BoardNode traverse(Board root) {
|
public BoardNode traverse(Board root) {
|
||||||
|
tried.clear(); // Resets each run.
|
||||||
Stack<BoardNode> stack = new Stack<>();
|
Stack<BoardNode> stack = new Stack<>();
|
||||||
BoardNode rootNode = new BoardNode(root, null);
|
BoardNode rootNode = new BoardNode(root, null);
|
||||||
rootNode.setDepth(0);
|
rootNode.depth = 0;
|
||||||
stack.push(rootNode);
|
stack.push(rootNode);
|
||||||
|
numOfNodes = 1;
|
||||||
while (!stack.isEmpty()) {
|
while (!stack.isEmpty()) {
|
||||||
BoardNode current = stack.pop();
|
BoardNode current = stack.pop();
|
||||||
|
|
||||||
@ -25,7 +42,7 @@ public class DFS implements Solver {
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.depth > Parameters.MAX_DEPTH || tried.contains(current.toString())) {
|
if (current.depth > Parameters.MAX_DEPTH || tried.contains(current.board.toString())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tried.add(current.toString());
|
tried.add(current.toString());
|
||||||
@ -35,11 +52,24 @@ public class DFS implements Solver {
|
|||||||
Board child = next.getBoard();
|
Board child = next.getBoard();
|
||||||
child.swap(next);
|
child.swap(next);
|
||||||
BoardNode childNode = new BoardNode(child, current);
|
BoardNode childNode = new BoardNode(child, current);
|
||||||
childNode.setDepth(current.depth+1);
|
childNode.depth = current.depth+1;
|
||||||
stack.push(childNode);
|
stack.push(childNode);
|
||||||
current.addChild(childNode);
|
current.addChild(childNode);
|
||||||
|
numOfNodes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of nodes from the previous iterations.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @return the number of nodes from the interations.
|
||||||
|
*/
|
||||||
|
public int getNumOfNodes() {
|
||||||
|
return numOfNodes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,22 +10,39 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to traverse a Spanning Tree of 8 Puzzle using a provided comparitor for a Priority Queue.
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public class PriorityTraversal implements Solver {
|
public class PriorityTraversal implements Solver {
|
||||||
|
|
||||||
private final Board solved = new Board();
|
private final Board solved = new Board();
|
||||||
private final HashSet<Board> visited = new HashSet<>();
|
private final HashSet<Board> visited = new HashSet<>();
|
||||||
|
|
||||||
private final Comparator<BoardNode> comparator;
|
private final Comparator<BoardNode> comparator;
|
||||||
|
private int numOfNodes = 1;
|
||||||
|
|
||||||
public PriorityTraversal(Comparator<BoardNode> type) {
|
public PriorityTraversal(Comparator<BoardNode> type) {
|
||||||
this.comparator = type;
|
this.comparator = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traverses through the list using a priority queue which is specified by the comparitor at constructor.
|
||||||
|
*
|
||||||
|
* @precondition root != null
|
||||||
|
* @postcondition a spanning tree is created.
|
||||||
|
*
|
||||||
|
* @param root the first node/initial start.
|
||||||
|
* @return the solved leaf node.
|
||||||
|
*/
|
||||||
public BoardNode traverse(Board root) {
|
public BoardNode traverse(Board root) {
|
||||||
|
visited.clear();
|
||||||
PriorityQueue<BoardNode> boards = new PriorityQueue<>(comparator);
|
PriorityQueue<BoardNode> boards = new PriorityQueue<>(comparator);
|
||||||
boards.add(new BoardNode(root, null));
|
boards.add(new BoardNode(root, null));
|
||||||
BoardNode node = null;
|
BoardNode node = null;
|
||||||
Board current = new Board(root);
|
Board current = new Board(root);
|
||||||
|
numOfNodes = 1;
|
||||||
while (!current.equals(solved) && !boards.isEmpty()) {
|
while (!current.equals(solved) && !boards.isEmpty()) {
|
||||||
node = boards.poll();
|
node = boards.poll();
|
||||||
current = node.board;
|
current = node.board;
|
||||||
@ -40,8 +57,22 @@ public class PriorityTraversal implements Solver {
|
|||||||
BoardNode childNode = new BoardNode(child, node);
|
BoardNode childNode = new BoardNode(child, node);
|
||||||
boards.add(childNode);
|
boards.add(childNode);
|
||||||
node.addChild(childNode);
|
node.addChild(childNode);
|
||||||
|
numOfNodes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of nodes from the previous iterations.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @return the number of nodes from the interation.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getNumOfNodes() {
|
||||||
|
return this.numOfNodes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,26 @@
|
|||||||
package Assignments.A1.solving_algorithms.comparators;
|
package Assignments.A1.solving_algorithms.comparators;
|
||||||
|
|
||||||
import Assignments.A1.models.Board;
|
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is used to compare two BoardNodes for an AStar Traversal.
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public class AStar implements Comparator<BoardNode> {
|
public class AStar implements Comparator<BoardNode> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two BoardNodes and sorts them in respect to both g(n) and h(n) resulting in AStar Priority.
|
||||||
|
*
|
||||||
|
* @precondition o1 != null && o2 != null
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @param o1 the first object to be compared.
|
||||||
|
* @param o2 the second object to be compared.
|
||||||
|
* @return -1,0,1 based on the a(n).
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int compare(BoardNode o1, BoardNode o2) {
|
public int compare(BoardNode o1, BoardNode o2) {
|
||||||
return Integer.compare(o1.expected, o2.expected);
|
return Integer.compare(o1.expected, o2.expected);
|
||||||
|
@ -1,10 +1,26 @@
|
|||||||
package Assignments.A1.solving_algorithms.comparators;
|
package Assignments.A1.solving_algorithms.comparators;
|
||||||
|
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is used to compare two BoardNodes for an BFS Traversal.
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public class BFS implements Comparator<BoardNode> {
|
public class BFS implements Comparator<BoardNode> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two BoardNodes and sorts them in respect to h(n) resulting in BFS Priority.
|
||||||
|
*
|
||||||
|
* @precondition o1 != null && o2 != null
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @param o1 the first object to be compared.
|
||||||
|
* @param o2 the second object to be compared.
|
||||||
|
* @return -1,0,1 based on the h(n).
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int compare(BoardNode o1, BoardNode o2) {
|
public int compare(BoardNode o1, BoardNode o2) {
|
||||||
return Integer.compare(o1.heuristic, o2.heuristic);
|
return Integer.compare(o1.heuristic, o2.heuristic);
|
||||||
|
@ -1,10 +1,26 @@
|
|||||||
package Assignments.A1.solving_algorithms.comparators;
|
package Assignments.A1.solving_algorithms.comparators;
|
||||||
|
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is used to compare two BoardNodes for an UCS Traversal.
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public class UCS implements Comparator<BoardNode> {
|
public class UCS implements Comparator<BoardNode> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two BoardNodes and sorts them in respect to g(n) resulting in UCS Priority.
|
||||||
|
*
|
||||||
|
* @precondition o1 != null && o2 != null
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @param o1 the first object to be compared.
|
||||||
|
* @param o2 the second object to be compared.
|
||||||
|
* @return -1,0,1 based on the g(n).
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int compare(BoardNode o1, BoardNode o2) {
|
public int compare(BoardNode o1, BoardNode o2) {
|
||||||
return Integer.compare(o1.cost, o2.cost);
|
return Integer.compare(o1.cost, o2.cost);
|
||||||
|
@ -6,6 +6,12 @@ import javafx.event.ActionEvent;
|
|||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code Behind file for MainView.fxml
|
||||||
|
*
|
||||||
|
* @author Jonathan Turner
|
||||||
|
* @version Spring 2024
|
||||||
|
*/
|
||||||
public class BoardViewCodeBehind {
|
public class BoardViewCodeBehind {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -29,9 +35,6 @@ public class BoardViewCodeBehind {
|
|||||||
@FXML
|
@FXML
|
||||||
private ToggleButton expanded;
|
private ToggleButton expanded;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private ToggleButton showOnlySolvedPath;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private MenuItem AStar;
|
private MenuItem AStar;
|
||||||
|
|
||||||
@ -44,6 +47,12 @@ public class BoardViewCodeBehind {
|
|||||||
@FXML
|
@FXML
|
||||||
private MenuItem UCS;
|
private MenuItem UCS;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button openPerformance;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button runPerformanceCHeck;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button solve_button;
|
private Button solve_button;
|
||||||
|
|
||||||
@ -53,6 +62,9 @@ public class BoardViewCodeBehind {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label no_solv_alg_err;
|
private Label no_solv_alg_err;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label iteration_count;
|
||||||
|
|
||||||
private MainViewModel viewModel;
|
private MainViewModel viewModel;
|
||||||
|
|
||||||
public BoardViewCodeBehind() {
|
public BoardViewCodeBehind() {
|
||||||
@ -71,10 +83,23 @@ public class BoardViewCodeBehind {
|
|||||||
this.expanded.selectedProperty().bindBidirectional(viewModel.expandedProperty());
|
this.expanded.selectedProperty().bindBidirectional(viewModel.expandedProperty());
|
||||||
this.alg_speed.textProperty().bindBidirectional(viewModel.algSpeedProperty());
|
this.alg_speed.textProperty().bindBidirectional(viewModel.algSpeedProperty());
|
||||||
this.disclaimer.visibleProperty().bindBidirectional(viewModel.disclaimerProperty());
|
this.disclaimer.visibleProperty().bindBidirectional(viewModel.disclaimerProperty());
|
||||||
|
this.runPerformanceCHeck.visibleProperty().bindBidirectional(viewModel.runPerfProperty());
|
||||||
|
this.openPerformance.visibleProperty().bindBidirectional(viewModel.openPerfProperty());
|
||||||
|
this.iteration_count.textProperty().bindBidirectional(viewModel.iterationCounterProperty());
|
||||||
|
|
||||||
this.current_board.textProperty().setValue(new Board().toString());
|
this.current_board.textProperty().setValue(new Board().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
void runPerformanceCheck(ActionEvent event) {
|
||||||
|
this.viewModel.runPerformanceCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
void openPerformance(ActionEvent event) {
|
||||||
|
this.viewModel.openPerf();
|
||||||
|
}
|
||||||
|
|
||||||
public void onGenerateBoard(ActionEvent actionEvent) {
|
public void onGenerateBoard(ActionEvent actionEvent) {
|
||||||
this.viewModel.generateBoard();
|
this.viewModel.generateBoard();
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import Assignments.A1.solving_algorithms.comparators.BFS;
|
|||||||
import Assignments.A1.solving_algorithms.DFS;
|
import Assignments.A1.solving_algorithms.DFS;
|
||||||
import Assignments.A1.solving_algorithms.comparators.UCS;
|
import Assignments.A1.solving_algorithms.comparators.UCS;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.TreeItem;
|
import javafx.scene.control.TreeItem;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -17,53 +18,62 @@ import java.util.Stack;
|
|||||||
|
|
||||||
public class MainViewModel {
|
public class MainViewModel {
|
||||||
|
|
||||||
private StringProperty currentBoardProperty, algSpeedProperty;
|
/* Private Fields used to bind */
|
||||||
private BooleanProperty expanded, DFS, UCS, BFS, AStar, solvingAlgErr, genBoardErr, disclaimer;
|
private final StringProperty currentBoardProperty, algSpeedProperty, iterationCounter;
|
||||||
private String selectedAlg;
|
private final BooleanProperty expanded, DFS, UCS, BFS, AStar, solvingAlgErr, genBoardErr, disclaimer, openPerf, runPerf;
|
||||||
|
|
||||||
private BoardNode current = new BoardNode(new Board(), null);
|
private BoardNode current = new BoardNode(new Board(), null);
|
||||||
private TreeItem<BoardNode> solvedRootNode = null;
|
private TreeItem<BoardNode> solvedRootNode = null;
|
||||||
private BoardNode solvedRootBoardNode = null;
|
|
||||||
|
|
||||||
|
/* Private Fields used for traversing/creating nodes. */
|
||||||
|
private BoardNode solvedRootBoardNode = null;
|
||||||
|
private final long[][] hasRanPerformance;
|
||||||
|
private String selectedAlg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes all the Properties and initial values for any fields.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition a VM is created.
|
||||||
|
*/
|
||||||
public MainViewModel() {
|
public MainViewModel() {
|
||||||
this.currentBoardProperty = new SimpleStringProperty();
|
this.currentBoardProperty = new SimpleStringProperty();
|
||||||
this.algSpeedProperty = new SimpleStringProperty();
|
this.algSpeedProperty = new SimpleStringProperty();
|
||||||
this.disclaimer = new SimpleBooleanProperty();
|
this.disclaimer = new SimpleBooleanProperty();
|
||||||
this.expanded = new SimpleBooleanProperty();
|
this.expanded = new SimpleBooleanProperty();
|
||||||
|
this.openPerf = new SimpleBooleanProperty();
|
||||||
|
this.runPerf = new SimpleBooleanProperty();
|
||||||
this.DFS = new SimpleBooleanProperty();
|
this.DFS = new SimpleBooleanProperty();
|
||||||
this.UCS = new SimpleBooleanProperty();
|
this.UCS = new SimpleBooleanProperty();
|
||||||
this.BFS = new SimpleBooleanProperty();
|
this.BFS = new SimpleBooleanProperty();
|
||||||
this.AStar = new SimpleBooleanProperty();
|
this.AStar = new SimpleBooleanProperty();
|
||||||
|
this.iterationCounter = new SimpleStringProperty();
|
||||||
|
|
||||||
this.solvingAlgErr = new SimpleBooleanProperty();
|
this.solvingAlgErr = new SimpleBooleanProperty();
|
||||||
this.genBoardErr = new SimpleBooleanProperty();
|
this.genBoardErr = new SimpleBooleanProperty();
|
||||||
this.solvingAlgErr.set(false);
|
this.solvingAlgErr.set(false);
|
||||||
this.genBoardErr.set(false);
|
this.genBoardErr.set(false);
|
||||||
|
|
||||||
|
this.hasRanPerformance = new long[4][102];
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSelectedAlg() {
|
/**
|
||||||
return this.selectedAlg;
|
* Generates the board and sets the board on view to new board.
|
||||||
}
|
*
|
||||||
|
* @precondition none
|
||||||
public void setSelectedAlg(String value) {
|
* @postcondition none
|
||||||
this.selectedAlg = value;
|
*/
|
||||||
this.DFS.set(value.equals("DFS"));
|
|
||||||
this.UCS.set(value.equals("UCS"));
|
|
||||||
this.BFS.set(value.equals("BFS"));
|
|
||||||
this.AStar.set(value.equals("AStar"));
|
|
||||||
|
|
||||||
this.disclaimer.setValue(value.equals("DFS"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringProperty getCurrentBoardProperty() {
|
|
||||||
return this.currentBoardProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateBoard() {
|
public void generateBoard() {
|
||||||
this.current = new BoardNode(BoardGenerator.generateBoard(), null);
|
this.current = new BoardNode(BoardGenerator.generateBoard(), null);
|
||||||
currentBoardProperty.set(this.current.board.toString());
|
currentBoardProperty.set(this.current.board.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves the current board by checking for which alg is selected, then will solve that board
|
||||||
|
* with the given alg that implements the Solver interface.
|
||||||
|
*
|
||||||
|
* @precondition menuItem != null && (board != solver || board != null)
|
||||||
|
* @postcondition the board is solved.
|
||||||
|
*/
|
||||||
public void solveBoard() {
|
public void solveBoard() {
|
||||||
if (selectedAlg == null || selectedAlg.isEmpty()) {
|
if (selectedAlg == null || selectedAlg.isEmpty()) {
|
||||||
this.solvingAlgErr.setValue(true);
|
this.solvingAlgErr.setValue(true);
|
||||||
@ -86,6 +96,7 @@ public class MainViewModel {
|
|||||||
} else if (AStar.getValue()) {
|
} else if (AStar.getValue()) {
|
||||||
solver = new PriorityTraversal(new AStar());
|
solver = new PriorityTraversal(new AStar());
|
||||||
}
|
}
|
||||||
|
|
||||||
Date start = new Date();
|
Date start = new Date();
|
||||||
BoardNode solved = solver.traverse(this.current.board);
|
BoardNode solved = solver.traverse(this.current.board);
|
||||||
Date end = new Date();
|
Date end = new Date();
|
||||||
@ -102,12 +113,134 @@ public class MainViewModel {
|
|||||||
this.current = solved;
|
this.current = solved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the values of the data using the View's Property files and Bindings.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition none
|
||||||
|
*
|
||||||
|
* @param value the menu item value.
|
||||||
|
*/
|
||||||
|
public void setSelectedAlg(String value) {
|
||||||
|
this.selectedAlg = value;
|
||||||
|
this.DFS.set(value.equals("DFS"));
|
||||||
|
this.UCS.set(value.equals("UCS"));
|
||||||
|
this.BFS.set(value.equals("BFS"));
|
||||||
|
this.AStar.set(value.equals("AStar"));
|
||||||
|
|
||||||
|
this.disclaimer.setValue(value.equals("DFS"));
|
||||||
|
this.openPerf.setValue(this.hasRanPerformance[convertValueToInt(value)][0] == 1);
|
||||||
|
this.runPerf.setValue(this.hasRanPerformance[convertValueToInt(value)][0] == 0);
|
||||||
|
if (this.hasRanPerformance[convertValueToInt(value)][0] == 0) {
|
||||||
|
this.iterationCounter.set("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs through the selected algorithm and will run it 100 times. It will collect data from these runs
|
||||||
|
* and store them. It will then allow you to view the data in a new windows and the button will appear.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition the performance is taken.
|
||||||
|
*/
|
||||||
|
public void runPerformanceCheck() {
|
||||||
|
Solver solver = null;
|
||||||
|
int alg = -1;
|
||||||
|
if (this.selectedAlg.equals("DFS") && this.hasRanPerformance[0][0] == 0) {
|
||||||
|
solver = new DFS();
|
||||||
|
alg = 0;
|
||||||
|
} else if (this.selectedAlg.equals("UCS") && this.hasRanPerformance[1][0] == 0) {
|
||||||
|
solver = new PriorityTraversal(new UCS());
|
||||||
|
alg = 1;
|
||||||
|
} else if (this.selectedAlg.equals("BFS") && this.hasRanPerformance[2][0] == 0) {
|
||||||
|
solver = new PriorityTraversal(new BFS());
|
||||||
|
alg = 2;
|
||||||
|
} else if (this.selectedAlg.equals("AStar") && this.hasRanPerformance[3][0] == 0) {
|
||||||
|
solver = new PriorityTraversal(new AStar());
|
||||||
|
alg = 3;
|
||||||
|
}
|
||||||
|
int averageNodes = 0;
|
||||||
|
if (solver != null) {
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
Board board = BoardGenerator.generateBoard();
|
||||||
|
System.out.println(board);
|
||||||
|
long start = new Date().getTime();
|
||||||
|
BoardNode node = solver.traverse(board);
|
||||||
|
long end = new Date().getTime();
|
||||||
|
System.out.println(node.board + "\n");
|
||||||
|
if (node != null) {
|
||||||
|
this.hasRanPerformance[alg][i + 2] = end - start;
|
||||||
|
this.currentBoardProperty.setValue(node.board.toString());
|
||||||
|
averageNodes += solver.getNumOfNodes();
|
||||||
|
updateDisplay();
|
||||||
|
} else {
|
||||||
|
this.hasRanPerformance[alg][i+2] = -1;
|
||||||
|
}
|
||||||
|
iterationCounter.setValue("Performing Analysis Iteration: " + (i+1) + "/100");
|
||||||
|
}
|
||||||
|
this.hasRanPerformance[alg][0] = 1;
|
||||||
|
this.hasRanPerformance[alg][1] = averageNodes;
|
||||||
|
this.runPerf.setValue(false);
|
||||||
|
this.openPerf.setValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < this.hasRanPerformance[alg].length; i++) {
|
||||||
|
System.out.println(this.hasRanPerformance[alg][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the performance files that were previously generated. Is only visible when performance is already generated.
|
||||||
|
*
|
||||||
|
* @precondition performance == generated
|
||||||
|
* @postcondition performance is displayed in Alert.
|
||||||
|
*/
|
||||||
|
public void openPerf() {
|
||||||
|
long totalTime = 0;
|
||||||
|
int success = 0;
|
||||||
|
long shortest = 1000000;
|
||||||
|
long longest = -1;
|
||||||
|
for (int i = 2; i < this.hasRanPerformance[convertValueToInt(this.selectedAlg)].length; i++) {
|
||||||
|
long current = this.hasRanPerformance[convertValueToInt(this.selectedAlg)][i];
|
||||||
|
if (current != -1) {
|
||||||
|
success++;
|
||||||
|
totalTime += current;
|
||||||
|
if (current < shortest) {
|
||||||
|
shortest = current;
|
||||||
|
}
|
||||||
|
if (longest < current) {
|
||||||
|
longest = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long average = totalTime / (long) success;
|
||||||
|
|
||||||
|
Alert perf = new Alert(Alert.AlertType.INFORMATION);
|
||||||
|
|
||||||
|
perf.setTitle(this.selectedAlg + " Performance Report");
|
||||||
|
perf.setHeaderText(success + "/" + 100 + " Succeeded.");
|
||||||
|
String results = "Shortest Run: " + shortest + "ms\n" +
|
||||||
|
"Longest Run: " + longest + "ms\n" +
|
||||||
|
"Average Time: " + average + "ms" + "\n" +
|
||||||
|
"Average Nodes: " + (this.hasRanPerformance[convertValueToInt(this.selectedAlg)][1]/success);
|
||||||
|
perf.setContentText(results);
|
||||||
|
perf.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is used to update the display with the current board.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition the dispaly is updated.
|
||||||
|
*/
|
||||||
public void updateDisplay() {
|
public void updateDisplay() {
|
||||||
TreeItem<BoardNode> newRoot = null;
|
TreeItem<BoardNode> newRoot = null;
|
||||||
newRoot = this.rebuildTree(this.solvedRootBoardNode, this.expanded.getValue());
|
newRoot = this.rebuildTree(this.solvedRootBoardNode, this.expanded.getValue());
|
||||||
this.solvedRootNode = newRoot;
|
this.solvedRootNode = newRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Getters for bindings */
|
||||||
|
|
||||||
public TreeItem<BoardNode> getSolvedRootNode() {
|
public TreeItem<BoardNode> getSolvedRootNode() {
|
||||||
return solvedRootNode;
|
return solvedRootNode;
|
||||||
}
|
}
|
||||||
@ -136,6 +269,44 @@ public class MainViewModel {
|
|||||||
return genBoardErr;
|
return genBoardErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getExpanded() {
|
||||||
|
return expanded.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty expandedProperty() {
|
||||||
|
return expanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringProperty algSpeedProperty() {
|
||||||
|
return algSpeedProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringProperty iterationCounterProperty() {
|
||||||
|
return iterationCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDisclaimer() {
|
||||||
|
return disclaimer.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty disclaimerProperty() {
|
||||||
|
return disclaimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty openPerfProperty() {
|
||||||
|
return openPerf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty runPerfProperty() {
|
||||||
|
return runPerf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringProperty getCurrentBoardProperty() {
|
||||||
|
return this.currentBoardProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End of Public Methods. Private Fields Only */
|
||||||
|
|
||||||
private TreeItem<BoardNode> rebuildTree(BoardNode root, boolean expanded) {
|
private TreeItem<BoardNode> rebuildTree(BoardNode root, boolean expanded) {
|
||||||
if (this.selectedAlg != null) {
|
if (this.selectedAlg != null) {
|
||||||
if (this.selectedAlg.equals("DFS")) {
|
if (this.selectedAlg.equals("DFS")) {
|
||||||
@ -168,28 +339,10 @@ public class MainViewModel {
|
|||||||
return new TreeItem<>();
|
return new TreeItem<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int convertValueToInt(String value) {
|
||||||
public boolean getExpanded() {
|
if (value.equals("DFS")) return 0;
|
||||||
return expanded.get();
|
if (value.equals("UCS")) return 1;
|
||||||
}
|
if (value.equals("BFS")) return 2;
|
||||||
|
return 3;
|
||||||
public BooleanProperty expandedProperty() {
|
|
||||||
return expanded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAlgSpeedProperty() {
|
|
||||||
return algSpeedProperty.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringProperty algSpeedProperty() {
|
|
||||||
return algSpeedProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDisclaimer() {
|
|
||||||
return disclaimer.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BooleanProperty disclaimerProperty() {
|
|
||||||
return disclaimer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
src/main/resources/A1/Instructions.pdf
Normal file
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 37 KiB |
@ -10,7 +10,6 @@
|
|||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="591.0" prefWidth="928.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Assignments.A1.view.BoardViewCodeBehind">
|
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="591.0" prefWidth="928.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Assignments.A1.view.BoardViewCodeBehind">
|
||||||
<children>
|
|
||||||
<TreeView fx:id="spanning_tree" layoutX="334.0" layoutY="67.0" prefHeight="416.0" prefWidth="532.0" />
|
<TreeView fx:id="spanning_tree" layoutX="334.0" layoutY="67.0" prefHeight="416.0" prefWidth="532.0" />
|
||||||
<ToggleButton fx:id="expanded" layoutX="547.0" layoutY="33.0" mnemonicParsing="false" onAction="#showSolvedPath" text="Expand Directory" />
|
<ToggleButton fx:id="expanded" layoutX="547.0" layoutY="33.0" mnemonicParsing="false" onAction="#showSolvedPath" text="Expand Directory" />
|
||||||
<Button id="generate_board" fx:id="generate_board" layoutX="97.0" layoutY="367.0" mnemonicParsing="false" onAction="#onGenerateBoard" text="Generate Random Board" />
|
<Button id="generate_board" fx:id="generate_board" layoutX="97.0" layoutY="367.0" mnemonicParsing="false" onAction="#onGenerateBoard" text="Generate Random Board" />
|
||||||
@ -41,5 +40,7 @@
|
|||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
<Label fx:id="disclaimer" layoutX="176.0" layoutY="541.0" prefHeight="42.0" prefWidth="558.0" text="**Note: If traversing with DFS, it only shows the solving directory to prevent JavaFX StackOverflow.** However, the traversal algorithm and algorithm speed does explore all nodes despite directory display." textAlignment="CENTER" wrapText="true" />
|
<Label fx:id="disclaimer" layoutX="176.0" layoutY="541.0" prefHeight="42.0" prefWidth="558.0" text="**Note: If traversing with DFS, it only shows the solving directory to prevent JavaFX StackOverflow.** However, the traversal algorithm and algorithm speed does explore all nodes despite directory display." textAlignment="CENTER" wrapText="true" />
|
||||||
</children>
|
<Button fx:id="runPerformanceCHeck" layoutX="77.0" layoutY="471.0" mnemonicParsing="false" onAction="#runPerformanceCheck" text="Performance Analysis (100 Runs)" visible="false" />
|
||||||
|
<Button fx:id="openPerformance" layoutX="54.0" layoutY="471.0" mnemonicParsing="false" onAction="#openPerformance" text="Open Performance Analysis (Default Editor)" />
|
||||||
|
<Label fx:id="iteration_count" layoutX="123.0" layoutY="506.0" prefHeight="36.0" prefWidth="106.0" wrapText="true" />
|
||||||
</Pane>
|
</Pane>
|
||||||
|