All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.tommyettinger.gand.algorithms.AStarSearch Maven / Gradle / Ivy

The newest version!
package com.github.tommyettinger.gand.algorithms;

import com.github.tommyettinger.gand.Connection;
import com.github.tommyettinger.gand.Node;
import com.github.tommyettinger.gand.Path;
import com.github.tommyettinger.gand.utils.Heuristic;
import com.github.tommyettinger.gand.utils.SearchProcessor;

import java.util.ArrayList;

@SuppressWarnings("unchecked")
public class AStarSearch extends Algorithm {

    private Heuristic heuristic;
    private SearchProcessor processor;
    private SearchStep step = new SearchStep<>();
    private final BinaryHeap heap;
    private Node start, target, u, end;
    private Path path;

    protected AStarSearch(int id, final Node start, final Node target, final Heuristic heuristic, final SearchProcessor processor) {
        super(id);
        this.start = start;
        this.target = target;
        this.heuristic = heuristic;
        this.processor = processor;
        heap = new BinaryHeap();
        start.resetAlgorithmAttribs(id);
        start.setDistance(0);
        heap.add(start);
    }

    @Override
    public boolean update() {
        if (isFinished()) return true;

        u = heap.pop();

        if (!u.isProcessed()) {
            if (processor != null && u.getIndex() > 0) {
                step.prepare(u);
                processor.accept(step);
                if (step.terminate) {
                    heap.clear();
                    return true;
                }
                if (step.ignore) {
                    return isFinished();
                }
            }
            u.setProcessed(true);

            if (u == target) {
                heap.clear();
                end = u;
                return true;
            }

            ArrayList> outEdges = u.getOutEdges();
            for (Connection e : outEdges) {
                Node v = e.getNodeB();
                v.resetAlgorithmAttribs(id);
                if (!v.isProcessed()) {
                    float newDistance = u.getDistance() + e.getWeight();
                    if (newDistance < v.getDistance()) {
                        v.setDistance(newDistance);
                        v.setPrev(u);
                        v.setConnection(e);
                        if (heuristic != null && !v.isSeen()) {
                            v.setEstimate(heuristic.getEstimate(v.getObject(), target.getObject()));
                        }
                        if (!v.isSeen()) {
                            heap.add(v, v.getDistance() + v.getEstimate());
                        } else {
                            heap.setValue(v, v.getDistance() + v.getEstimate());
                        }
                        v.setIndex(u.getIndex() + 1);
                        v.setSeen(true);
                    }
                }
            }
        }
        return isFinished();
    }

    @Override
    public boolean isFinished() {
        return heap.size == 0;
    }

    public Path getPath() {
        if (!isFinished()) return null;
        if (path == null) {
            path = end != null ? new AlgorithmPath<>(end) : Path.EMPTY_PATH;
        }
        return path;
    }

    Node getEnd() {
        return end;
    }

    /**
     *
     * @param start
     * @param target
     * @param heuristic
     * @return the target Node if reachable, otherwise null
     */
    private Node aStarSearch(final Node start, final Node target, final Heuristic heuristic, final SearchProcessor processor) {

        start.resetAlgorithmAttribs(id);
        start.setDistance(0);

        heap.add(start);

        final SearchStep step = processor != null ? new SearchStep<>() : null;

        while(heap.size != 0) {
            Node u = heap.pop();
            if (u == target) {
                heap.clear();
                return u;
            }
            if (!u.isProcessed()) {
                if (processor != null && u.getIndex() > 0) {
                    step.prepare(u);
                    processor.accept(step);
                    if (step.terminate) {
                        heap.clear();
                        return null;
                    }
                    if (step.ignore) continue;
                }
                u.setProcessed(true);
                ArrayList> outEdges = u.getOutEdges();
                for (Connection e : outEdges) {
                    Node v = e.getNodeB();
                    v.resetAlgorithmAttribs(id);
                    if (!v.isProcessed()) {
                        float newDistance = u.getDistance() + e.getWeight();
                        if (newDistance < v.getDistance()) {
                            v.setDistance(newDistance);
                            v.setPrev(u);
                            v.setConnection(e);
                            if (heuristic != null && !v.isSeen()) {
                                v.setEstimate(heuristic.getEstimate(v.getObject(), target.getObject()));
                            }
                            if (!v.isSeen()) {
                                heap.add(v, v.getDistance() + v.getEstimate());
                            } else {
                                heap.setValue(v, v.getDistance() + v.getEstimate());
                            }
                            v.setIndex(u.getIndex() + 1);
                            v.setSeen(true);
                        }
                    }
                }
            }
        }
        heap.clear();
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy