Advertisement
Guest User

Untitled

a guest
Dec 11th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.04 KB | None | 0 0
  1. package hw7;
  2.  
  3. import hw4.Edge;
  4. import hw4.Graph;
  5. import hw4.Node;
  6. import java.io.IOException;
  7. import java.util.ArrayList;
  8. import java.util.HashSet;
  9. import java.util.PriorityQueue;
  10. import java.util.Collections;
  11. import java.util.Comparator;
  12. import java.util.HashMap;
  13.  
  14.  
  15.  
  16. /**
  17.  * @author Khalil Fleming
  18.  *
  19.  *         Abstraction Function: The model of the MVC, this class will create
  20.  *         the graph, and store it in its respective data structures allowing it
  21.  *         to be processed for information from the view/controller. This
  22.  *         contains the main graph object of a string and double holding the
  23.  *         name and the distance between two building. It also has 4 hashmaps to
  24.  *         hold the data from the csvs, and an arraylist of arraylists to hold
  25.  *         the edge data
  26.  *
  27.  *         Representation Invariant: All of the member variables can not be null
  28.  *
  29.  */
  30.  
  31. public class CampusPathModel extends Graph<String, Double> {
  32.  
  33.     private Graph<String, Double> graph;
  34.     private HashMap<String, String> nameToId;
  35.     private HashMap<String, String> idToName;
  36.     private HashMap<String, Integer> idToX;
  37.     private HashMap<String, Integer> idToY;
  38.     private ArrayList<ArrayList<String>> idToId;
  39.  
  40.     /**
  41.      * The constructor for the campusPathModel class, will initialize an empty
  42.      * campusPathModel object
  43.      *
  44.      * @modifies creates an empty campusPathModel object
  45.      */
  46.     public CampusPathModel() {
  47.         this.graph = new Graph<>();
  48.         this.nameToId = new HashMap<>();
  49.         this.idToName = new HashMap<>();
  50.         this.idToX = new HashMap<>();
  51.         this.idToY = new HashMap<>();
  52.         this.idToId = new ArrayList<>();
  53.     }
  54.  
  55.     /**
  56.      * getDirection will determine which cardinal direction the path is taking at
  57.      * every step
  58.      *
  59.      * @param b1
  60.      *            - the current building you are looking at
  61.      * @param b2
  62.      *            - the previous building you were coming from
  63.      * @return - A string telling you which direction you should step
  64.      */
  65.     public String getDirection(Node<String> b1, Node<String> b2) {
  66.    
  67.         String dir = "";
  68.         String b1Id = nameToId.get(b1.getName());
  69.         String b2Id = nameToId.get(b2.getName());
  70.    
  71.         int b1X = idToX.get(b1Id);
  72.         int b1Y = idToY.get(b1Id);
  73.         int b2X = idToX.get(b2Id);
  74.         int b2Y = idToY.get(b2Id);
  75.         int xOffset = b2X - b1X;
  76.         int yOffset = b2Y - b1Y;
  77.    
  78.         double angle = Math.atan((b2Y - b1Y) / (double) (b2X - b1X)) * 57.3;
  79.         if (xOffset > 0 && yOffset > 0) {
  80.             if (angle < 67.5 && angle > 22.5) {
  81.                 dir = "NorthWest";
  82.             } else if (angle < 22.5) {
  83.                 dir = "West";
  84.             } else {
  85.                 dir = "North";
  86.             }
  87.         } else if (xOffset < 0 && yOffset < 0) {
  88.             if (angle < 67.5 && angle > 22.5) {
  89.                 dir = "SouthEast";
  90.             } else if (angle < 22.5) {
  91.                 dir = "East";
  92.             } else {
  93.                 dir = "South";
  94.             }
  95.         } else if (xOffset < 0 && yOffset > 0) {
  96.             if (angle < -22.5 && angle > -67.5) {
  97.                 dir = "NorthEast";
  98.             } else if (angle < -67.5) {
  99.                 dir = "North";
  100.             } else {
  101.                 dir = "East";
  102.             }
  103.         } else if (xOffset > 0 && yOffset < 0) {
  104.             if (angle < -22.5 && angle > -67.5) {
  105.                 dir = "SouthWest";
  106.             } else if (angle < -67.5) {
  107.                 dir = "South";
  108.             } else {
  109.                 dir = "West";
  110.             }
  111.         } else if (xOffset != 0 && yOffset == 0) {
  112.             if (xOffset < 0) {
  113.                 dir = "East";
  114.             } else {
  115.                 dir = "West";
  116.             }
  117.         }
  118.    
  119.         return dir;
  120.     }
  121.  
  122.     /**
  123.      * createNewGraph will take in two csv files and construct the corresponding
  124.      * graph
  125.      *
  126.      * @param file1
  127.      *            - the name of the first csv file for nodes
  128.      * @param file2
  129.      *            - the name of the second csv file for edges
  130.      * @throws IOException
  131.      *             - if the file is in the incorrect format
  132.      * @effect builds a graph using the csv files
  133.      * @modify graph - the member variable graph
  134.      */
  135.     public void createNewGraph(String file1, String file2) throws IOException {
  136.         CampusPathModelParse.readNode(file1, this.nameToId, this.idToName, this.idToX, this.idToY);
  137.         CampusPathModelParse.readEdge(file2, this.idToId);
  138.  
  139.         for (String m : this.nameToId.keySet()) {
  140.             graph.addNode(m);
  141.  
  142.             this.addNode(m);
  143.         }
  144.  
  145.         for (ArrayList<String> id : idToId) {
  146.             String id1 = id.get(0);
  147.             String id2 = id.get(1);
  148.  
  149.             Integer id1XCord = this.idToX.get(id1);
  150.             Integer id1YCord = this.idToY.get(id1);
  151.             Integer id2XCord = this.idToX.get(id2);
  152.             Integer id2YCord = this.idToY.get(id2);
  153.  
  154.             double dist = Math.sqrt(
  155.                     (id1XCord - id2XCord) * (id1XCord - id2XCord) + (id1YCord - id2YCord) * (id1YCord - id2YCord));
  156.  
  157.             graph.addEdge(this.idToName.get(id1), this.idToName.get(id2), dist);
  158.             graph.addEdge(this.idToName.get(id2), this.idToName.get(id1), dist);
  159.  
  160.             this.addEdge(this.idToName.get(id1), this.idToName.get(id2), dist);
  161.             this.addEdge(this.idToName.get(id2), this.idToName.get(id1), dist);
  162.         }
  163.  
  164.     }
  165.  
  166.     /**
  167.      * Will list all the building names in the graph
  168.      *
  169.      * @return a String of all the building names separated by newlines
  170.      */
  171.     public String listBuildings() {
  172.         StringBuilder allBuildings = new StringBuilder();
  173.         ArrayList<String> buildings = new ArrayList<>();
  174.         for (String name : nameToId.keySet()) {
  175.             if (!name.contains("Intersection")) {
  176.                 buildings.add(name + "," + this.nameToId.get(name) + "\n");
  177.             }
  178.         }
  179.         Collections.sort(buildings);
  180.         for (String b : buildings) {
  181.             allBuildings.append(b);
  182.         }
  183.         return allBuildings.toString();
  184.     }
  185.    
  186.     /**
  187.      * Will store all the building names in the graph in an array list
  188.      *
  189.      * @return a ArrayList of of all the building names
  190.      */
  191.     public ArrayList<String> getAllBuildings() {
  192.         ArrayList<String> allBuildings = new ArrayList<>();
  193.         for (String name : nameToId.keySet()) {
  194.             if (!name.contains("Intersection")) {
  195.                 allBuildings.add(name);
  196.             }
  197.         }
  198.         Collections.sort(allBuildings);
  199.         return allBuildings;
  200.     }
  201.  
  202.  
  203.     /**
  204.      * Find path will take in two building names and find the shortest path between
  205.      * them
  206.      *
  207.      * @param n1
  208.      *            - name of the first building
  209.      * @param n2
  210.      *            - name of the second building
  211.      * @return a string which contains the shortest path between two buildings
  212.      */
  213.     public String findPath(String n1, String n2) {
  214.    
  215.         String building1 = n1;
  216.         String building2 = n2;
  217.         String regex = "[-+]?\\d*\\.?\\d+";
  218.    
  219.         if (building1.matches(regex) && !building2.matches(regex)) {
  220.             building1 = this.idToName.get(building1);
  221.         } else if (!building1.matches(regex) && building2.matches(regex)) {
  222.             building2 = this.idToName.get(building2);
  223.         } else if (building1.matches(regex) && building2.matches(regex)) {
  224.             building1 = this.idToName.get(building1);
  225.             building2 = this.idToName.get(building2);
  226.         }
  227.    
  228.         String unknownBuild = " Unknown building: [";
  229.         String intersection = "Intersection ";
  230.    
  231.         if (building1.contains(intersection) && !building2.contains(intersection)) {
  232.             return unknownBuild + building1.replace(intersection, "") + "]\n";
  233.         }
  234.         if (!building1.contains(intersection) && building2.contains(intersection)) {
  235.             return unknownBuild + building2.replace(intersection, "") + "]\n";
  236.         }
  237.         if (building1.equals(building2) && building1.contains(intersection) && building2.contains(intersection)) {
  238.             return unknownBuild + building1.replace(intersection, "") + "]\n";
  239.         }
  240.         if (building1.contains(intersection) && building2.contains(intersection)) {
  241.             return unknownBuild + building1.replace(intersection, "") + "]\n" + "Unknown building: ["
  242.                     + building2.replace(intersection, "") + "]\n";
  243.         }
  244.    
  245.         if (!graph.hasNode(building1) && graph.hasNode(building2)) {
  246.             return unknownBuild + building1 + "]\n";
  247.         }
  248.         if (graph.hasNode(building1) && !graph.hasNode(building2)) {
  249.             return unknownBuild + building2 + "]\n";
  250.         }
  251.         if (!graph.hasNode(building1) && !graph.hasNode(building2)) {
  252.             return unknownBuild + building1 + "]\n" + "Unknown building: [" + building2 + "]\n";
  253.         }
  254.    
  255.         Node<String> startNode = new Node<>(building1);
  256.         Node<String> destNode = new Node<>(building2);
  257.         PriorityQueue<Path> active = new PriorityQueue<>(Comparator.comparingDouble(Path::getCost));
  258.         HashSet<String> finished = new HashSet<>();
  259.    
  260.         Path startingPath = new Path();
  261.         startingPath.addToPath(startNode, 0);
  262.         active.add(startingPath);
  263.    
  264.         while (!active.isEmpty()) {
  265.             Path minPath = active.poll();
  266.             Node<String> minDest = minPath.allPaths.get(minPath.allPaths.size() - 1);
  267.    
  268.             if (minDest.equals(destNode)) {
  269.                 return printShortestPath(minPath);
  270.             }
  271.    
  272.             if (finished.contains(minDest.getName())) {
  273.                 continue;
  274.             }
  275.    
  276.             HashSet<Edge<String, Double>> tempSet = this.adjList.get(minDest.getName());
  277.    
  278.             for (Edge<String, Double> edge : tempSet) {
  279.                 if (edge == null) {
  280.                     continue;
  281.                 }
  282.    
  283.                 if (!finished.contains(edge.getEndPoint().getName())) {
  284.                     double tempDist = edge.getLabel();
  285.    
  286.                     Path tempPath = new Path(minPath);
  287.                     tempPath.addToPath(edge.getEndPoint(), tempDist);
  288.                     active.add(tempPath);
  289.                 }
  290.             }
  291.             finished.add(minDest.getName());
  292.         }
  293.         return " There is no path from " + building1 + " to " + building2 + ".\n";
  294.     }
  295.  
  296.     /**
  297.      * printShortestPath will return the correct formatting for the shortest path
  298.      *
  299.      * @param minPath
  300.      *            - the Path object which contains the shortest path waiting to be
  301.      *            printed
  302.      * @return - the Correct string representation of the shortest path
  303.      */
  304.     public String printShortestPath(Path minPath) {
  305.         String startBuild = minPath.allPaths.get(0).getName();
  306.         String endBuild = minPath.allPaths.get(minPath.allPaths.size() - 1).getName();
  307.         String pathString = "";
  308.         Node<String> tempBuild = new Node<>("");
  309.         pathString += (" Path from " + startBuild + " to " + endBuild + ":\n");
  310.  
  311.         for (Node<String> n : minPath.allPaths) {
  312.             if (n.equals(minPath.allPaths.get(0))) {
  313.                 tempBuild = new Node<>(n.getName());
  314.                 continue;
  315.             }
  316.  
  317.             Node<String> temp = new Node<>(n.getName());
  318.             String dir = getDirection(temp, tempBuild);
  319.  
  320.             pathString += "\tWalk " + dir + " to (" + temp.getName() + ")\n";
  321.  
  322.             tempBuild = new Node<>(temp.getName());
  323.         }
  324.         pathString += "Total distance: " + String.format("%.3f", minPath.getCost()) + " pixel units.\n";
  325.         return pathString;
  326.     }
  327.  
  328. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement