com.amindorost.searchalgorithms.MainSearch.java Source code

Java tutorial

Introduction

Here is the source code for com.amindorost.searchalgorithms.MainSearch.java

Source

/*
 * 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);
        }
    };

}