Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package hw7;
- import hw4.Edge;
- import hw4.Graph;
- import hw4.Node;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.HashSet;
- import java.util.PriorityQueue;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.HashMap;
- /**
- * @author Khalil Fleming
- *
- * Abstraction Function: The model of the MVC, this class will create
- * the graph, and store it in its respective data structures allowing it
- * to be processed for information from the view/controller. This
- * contains the main graph object of a string and double holding the
- * name and the distance between two building. It also has 4 hashmaps to
- * hold the data from the csvs, and an arraylist of arraylists to hold
- * the edge data
- *
- * Representation Invariant: All of the member variables can not be null
- *
- */
- public class CampusPathModel extends Graph<String, Double> {
- private Graph<String, Double> graph;
- private HashMap<String, String> nameToId;
- private HashMap<String, String> idToName;
- private HashMap<String, Integer> idToX;
- private HashMap<String, Integer> idToY;
- private ArrayList<ArrayList<String>> idToId;
- /**
- * The constructor for the campusPathModel class, will initialize an empty
- * campusPathModel object
- *
- * @modifies creates an empty campusPathModel object
- */
- public CampusPathModel() {
- this.graph = new Graph<>();
- this.nameToId = new HashMap<>();
- this.idToName = new HashMap<>();
- this.idToX = new HashMap<>();
- this.idToY = new HashMap<>();
- this.idToId = new ArrayList<>();
- }
- /**
- * getDirection will determine which cardinal direction the path is taking at
- * every step
- *
- * @param b1
- * - the current building you are looking at
- * @param b2
- * - the previous building you were coming from
- * @return - A string telling you which direction you should step
- */
- public String getDirection(Node<String> b1, Node<String> b2) {
- String dir = "";
- String b1Id = nameToId.get(b1.getName());
- String b2Id = nameToId.get(b2.getName());
- int b1X = idToX.get(b1Id);
- int b1Y = idToY.get(b1Id);
- int b2X = idToX.get(b2Id);
- int b2Y = idToY.get(b2Id);
- int xOffset = b2X - b1X;
- int yOffset = b2Y - b1Y;
- double angle = Math.atan((b2Y - b1Y) / (double) (b2X - b1X)) * 57.3;
- if (xOffset > 0 && yOffset > 0) {
- if (angle < 67.5 && angle > 22.5) {
- dir = "NorthWest";
- } else if (angle < 22.5) {
- dir = "West";
- } else {
- dir = "North";
- }
- } else if (xOffset < 0 && yOffset < 0) {
- if (angle < 67.5 && angle > 22.5) {
- dir = "SouthEast";
- } else if (angle < 22.5) {
- dir = "East";
- } else {
- dir = "South";
- }
- } else if (xOffset < 0 && yOffset > 0) {
- if (angle < -22.5 && angle > -67.5) {
- dir = "NorthEast";
- } else if (angle < -67.5) {
- dir = "North";
- } else {
- dir = "East";
- }
- } else if (xOffset > 0 && yOffset < 0) {
- if (angle < -22.5 && angle > -67.5) {
- dir = "SouthWest";
- } else if (angle < -67.5) {
- dir = "South";
- } else {
- dir = "West";
- }
- } else if (xOffset != 0 && yOffset == 0) {
- if (xOffset < 0) {
- dir = "East";
- } else {
- dir = "West";
- }
- }
- return dir;
- }
- /**
- * createNewGraph will take in two csv files and construct the corresponding
- * graph
- *
- * @param file1
- * - the name of the first csv file for nodes
- * @param file2
- * - the name of the second csv file for edges
- * @throws IOException
- * - if the file is in the incorrect format
- * @effect builds a graph using the csv files
- * @modify graph - the member variable graph
- */
- public void createNewGraph(String file1, String file2) throws IOException {
- CampusPathModelParse.readNode(file1, this.nameToId, this.idToName, this.idToX, this.idToY);
- CampusPathModelParse.readEdge(file2, this.idToId);
- for (String m : this.nameToId.keySet()) {
- graph.addNode(m);
- this.addNode(m);
- }
- for (ArrayList<String> id : idToId) {
- String id1 = id.get(0);
- String id2 = id.get(1);
- Integer id1XCord = this.idToX.get(id1);
- Integer id1YCord = this.idToY.get(id1);
- Integer id2XCord = this.idToX.get(id2);
- Integer id2YCord = this.idToY.get(id2);
- double dist = Math.sqrt(
- (id1XCord - id2XCord) * (id1XCord - id2XCord) + (id1YCord - id2YCord) * (id1YCord - id2YCord));
- graph.addEdge(this.idToName.get(id1), this.idToName.get(id2), dist);
- graph.addEdge(this.idToName.get(id2), this.idToName.get(id1), dist);
- this.addEdge(this.idToName.get(id1), this.idToName.get(id2), dist);
- this.addEdge(this.idToName.get(id2), this.idToName.get(id1), dist);
- }
- }
- /**
- * Will list all the building names in the graph
- *
- * @return a String of all the building names separated by newlines
- */
- public String listBuildings() {
- StringBuilder allBuildings = new StringBuilder();
- ArrayList<String> buildings = new ArrayList<>();
- for (String name : nameToId.keySet()) {
- if (!name.contains("Intersection")) {
- buildings.add(name + "," + this.nameToId.get(name) + "\n");
- }
- }
- Collections.sort(buildings);
- for (String b : buildings) {
- allBuildings.append(b);
- }
- return allBuildings.toString();
- }
- /**
- * Will store all the building names in the graph in an array list
- *
- * @return a ArrayList of of all the building names
- */
- public ArrayList<String> getAllBuildings() {
- ArrayList<String> allBuildings = new ArrayList<>();
- for (String name : nameToId.keySet()) {
- if (!name.contains("Intersection")) {
- allBuildings.add(name);
- }
- }
- Collections.sort(allBuildings);
- return allBuildings;
- }
- /**
- * Find path will take in two building names and find the shortest path between
- * them
- *
- * @param n1
- * - name of the first building
- * @param n2
- * - name of the second building
- * @return a string which contains the shortest path between two buildings
- */
- public String findPath(String n1, String n2) {
- String building1 = n1;
- String building2 = n2;
- String regex = "[-+]?\\d*\\.?\\d+";
- if (building1.matches(regex) && !building2.matches(regex)) {
- building1 = this.idToName.get(building1);
- } else if (!building1.matches(regex) && building2.matches(regex)) {
- building2 = this.idToName.get(building2);
- } else if (building1.matches(regex) && building2.matches(regex)) {
- building1 = this.idToName.get(building1);
- building2 = this.idToName.get(building2);
- }
- String unknownBuild = " Unknown building: [";
- String intersection = "Intersection ";
- if (building1.contains(intersection) && !building2.contains(intersection)) {
- return unknownBuild + building1.replace(intersection, "") + "]\n";
- }
- if (!building1.contains(intersection) && building2.contains(intersection)) {
- return unknownBuild + building2.replace(intersection, "") + "]\n";
- }
- if (building1.equals(building2) && building1.contains(intersection) && building2.contains(intersection)) {
- return unknownBuild + building1.replace(intersection, "") + "]\n";
- }
- if (building1.contains(intersection) && building2.contains(intersection)) {
- return unknownBuild + building1.replace(intersection, "") + "]\n" + "Unknown building: ["
- + building2.replace(intersection, "") + "]\n";
- }
- if (!graph.hasNode(building1) && graph.hasNode(building2)) {
- return unknownBuild + building1 + "]\n";
- }
- if (graph.hasNode(building1) && !graph.hasNode(building2)) {
- return unknownBuild + building2 + "]\n";
- }
- if (!graph.hasNode(building1) && !graph.hasNode(building2)) {
- return unknownBuild + building1 + "]\n" + "Unknown building: [" + building2 + "]\n";
- }
- Node<String> startNode = new Node<>(building1);
- Node<String> destNode = new Node<>(building2);
- PriorityQueue<Path> active = new PriorityQueue<>(Comparator.comparingDouble(Path::getCost));
- HashSet<String> finished = new HashSet<>();
- Path startingPath = new Path();
- startingPath.addToPath(startNode, 0);
- active.add(startingPath);
- while (!active.isEmpty()) {
- Path minPath = active.poll();
- Node<String> minDest = minPath.allPaths.get(minPath.allPaths.size() - 1);
- if (minDest.equals(destNode)) {
- return printShortestPath(minPath);
- }
- if (finished.contains(minDest.getName())) {
- continue;
- }
- HashSet<Edge<String, Double>> tempSet = this.adjList.get(minDest.getName());
- for (Edge<String, Double> edge : tempSet) {
- if (edge == null) {
- continue;
- }
- if (!finished.contains(edge.getEndPoint().getName())) {
- double tempDist = edge.getLabel();
- Path tempPath = new Path(minPath);
- tempPath.addToPath(edge.getEndPoint(), tempDist);
- active.add(tempPath);
- }
- }
- finished.add(minDest.getName());
- }
- return " There is no path from " + building1 + " to " + building2 + ".\n";
- }
- /**
- * printShortestPath will return the correct formatting for the shortest path
- *
- * @param minPath
- * - the Path object which contains the shortest path waiting to be
- * printed
- * @return - the Correct string representation of the shortest path
- */
- public String printShortestPath(Path minPath) {
- String startBuild = minPath.allPaths.get(0).getName();
- String endBuild = minPath.allPaths.get(minPath.allPaths.size() - 1).getName();
- String pathString = "";
- Node<String> tempBuild = new Node<>("");
- pathString += (" Path from " + startBuild + " to " + endBuild + ":\n");
- for (Node<String> n : minPath.allPaths) {
- if (n.equals(minPath.allPaths.get(0))) {
- tempBuild = new Node<>(n.getName());
- continue;
- }
- Node<String> temp = new Node<>(n.getName());
- String dir = getDirection(temp, tempBuild);
- pathString += "\tWalk " + dir + " to (" + temp.getName() + ")\n";
- tempBuild = new Node<>(temp.getName());
- }
- pathString += "Total distance: " + String.format("%.3f", minPath.getCost()) + " pixel units.\n";
- return pathString;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement