Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.amindorost.searchalgorithms; import java.util.ArrayList; import java.util.List; import org.json.simple.JSONArray; import org.json.simple.JSONObject; public abstract class MainSearch { protected Topology topology; protected Node src; protected Node dst; protected List<Node> nodesQueue; protected List<Node> processedNodes; protected JSONObject resultJSON; protected JSONArray iterationJSONArray; protected JSONArray pathJSON; protected int heuristicsType; protected List<Link> pathFound; protected int iterationCount; public MainSearch() { this.topology = null; this.src = null; this.dst = null; this.nodesQueue = null; this.resultJSON = new JSONObject(); this.iterationJSONArray = new JSONArray(); this.pathJSON = new JSONArray(); } public MainSearch(Topology topology, Node src, Node dst, int heuristicsType) { this.topology = null; this.topology = topology; this.src = src; this.dst = dst; this.heuristicsType = heuristicsType; this.nodesQueue = new ArrayList<Node>(); if (heuristicsType == 0) this.src.setNodeValue(1); else this.src.setNodeValue(heuristics(this.src)); this.nodesQueue.add(this.src); this.processedNodes = new ArrayList<Node>(); this.resultJSON = new JSONObject(); this.heuristicsType = heuristicsType; this.pathFound = new ArrayList<>(); this.iterationJSONArray = new JSONArray(); this.pathJSON = new JSONArray(); } public abstract List<Node> updateNodesCost(List<Node> nodes); protected double calculateF(Node node) { return node.getNodeValue() + heuristics(node); } protected double heuristics(Node node) { switch (this.heuristicsType) { case 0: return 0; case 1: //SLD return Math.sqrt(Math.pow(node.getLocation().width - this.dst.getLocation().width, 2) + Math.pow(node.getLocation().height - this.dst.getLocation().height, 2)); default: return 0; } } private boolean checkGoal(Node node) { if (node.getNodeName().equalsIgnoreCase(this.dst.getNodeName())) return true; for (Node nodes : this.nodesQueue) { if (nodes.getNodeName().equalsIgnoreCase(this.dst.getNodeName())) return true; } return false; } //This method steps ahead to update queue list ! //returns null if best node is not the destination otherwise returns the best node to be spreaded ! protected Node updateNodesQueue() { JSONObject currentIteration = new JSONObject(); JSONArray queueJSONArray = new JSONArray(); JSONObject queueJSON; for (Node node : this.nodesQueue) { queueJSON = new JSONObject(); queueJSON.put("node", node.getNodeName()); queueJSON.put("value", Math.round(node.getNodeValue())); queueJSONArray.add(queueJSON); } currentIteration.put("queue", queueJSONArray); Node toBeSpreadedNode = pickBestNode(); if (checkGoal(toBeSpreadedNode)) { return this.dst; } JSONObject spreadingNodeJSON = new JSONObject(); spreadingNodeJSON.put("name", toBeSpreadedNode.toString()); spreadingNodeJSON.put("value", toBeSpreadedNode.getNodeValue()); currentIteration.put("spreadingNode", spreadingNodeJSON); this.iterationJSONArray.add(currentIteration); List<Node> children = this.getChildren(toBeSpreadedNode); children = updateNodesCost(children); if (children.size() != 0) { //Remove The Parent Node and replace the children this.nodesQueue.remove(toBeSpreadedNode); this.nodesQueue.addAll(children); this.processedNodes.addAll(children); } else { this.nodesQueue.remove(toBeSpreadedNode); // A leaf that is not the destination } return null; } //This method determines which node should be spreaded in the queue list ! protected Node pickBestNode() { double minValue = Integer.MAX_VALUE; Node bestNode = null; for (Node node : this.nodesQueue) { if (node.getProcessCount() > 0) continue; double nodeFitness = calculateF(node); if (nodeFitness < minValue) { minValue = nodeFitness; bestNode = node; } } bestNode.processed(); return bestNode; } //node should be in the current queue list private List<Node> getChildren(Node node) { List<Node> children = new ArrayList<Node>(); String offspringName; if (node.getLinks().size() == 0) { return children; } for (Link link : node.getLinks()) { offspringName = link.getTailNode().toString(); List<Node> tmp = new FilterList().filterList(this.topology.nodes, filter, offspringName); Node offspring = tmp.get(0); if (offspring.getProcessCount() > 0 || this.processedNodes.contains(offspring) || this.nodesQueue.contains(offspring)) continue; offspring.setParentNode(node); offspring.setParentLink(link.reverse()); children.add(offspring); } return children; } public JSONObject getResults() { JSONObject linkJSON; for (int i = this.pathFound.size() - 1; i >= 0; i--) { linkJSON = new JSONObject(); linkJSON.put("link", this.pathFound.get(i).toString()); linkJSON.put("cost", this.pathFound.get(i).getCost()); this.pathJSON.add(linkJSON); } this.resultJSON.put("path", this.pathJSON); this.resultJSON.put("iterations", this.iterationJSONArray); return this.resultJSON; } public List<Link> getRoute() { List<Link> path = new ArrayList<Link>(); Node destination; do { destination = updateNodesQueue(); } while (destination == null); Link connectorLink; while ((connectorLink = destination.getParentLink()) != null) { path.add(connectorLink.reverse()); String newDestinationName = connectorLink.reverse().getHeadNode().getNodeName(); List<Node> tmp = new FilterList().filterList(this.topology.nodes, filter, newDestinationName); destination = tmp.get(0); } this.pathFound = path; return path; } Filter<Node, String> filter = new Filter<Node, String>() { public boolean isMatched(Node object, String text) { return object.getNodeName().equalsIgnoreCase(text); } }; }