Day6

1.dijkstra

/*
 * Dijkstra最短路径。
 * 即,统计图中"顶点vs"到其它各个顶点的最短路径。
 *
 * 参数说明:
 *       vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。
 *     prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
 *     dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。
 */
public void dijkstra(int vs, int[] prev, int[] dist) {
    // flag[i]=true表示"顶点vs"到"顶点i"的最短路径已成功获取
    boolean[] flag = new boolean[mVexs.length];

    // 初始化
    for (int i = 0; i < mVexs.length; i++) {
        flag[i] = false;          // 顶点i的最短路径还没获取到。
        prev[i] = 0;              // 顶点i的前驱顶点为0。
        dist[i] = mMatrix[vs][i];  // 顶点i的最短路径为"顶点vs"到"顶点i"的权。
    }

    // 对"顶点vs"自身进行初始化
    flag[vs] = true;
    dist[vs] = 0;

    // 遍历mVexs.length-1次;每次找出一个顶点的最短路径。
    int k=0;
    for (int i = 1; i < mVexs.length; i++) {
        // 寻找当前最小的路径;
        // 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
        int min = INF;
        for (int j = 0; j < mVexs.length; j++) {
            if (flag[j]==false && dist[j]<min) {
                min = dist[j];
                k = j;
            }
        }
        // 标记"顶点k"为已经获取到最短路径
        flag[k] = true;

        // 修正当前最短路径和前驱顶点
        // 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
        for (int j = 0; j < mVexs.length; j++) {
            int tmp = (mMatrix[k][j]==INF ? INF : (min + mMatrix[k][j]));
            if (flag[j]==false && (tmp<dist[j]) ) {
                dist[j] = tmp;
                prev[j] = k;
            }
        }
    }

    // 打印dijkstra最短路径的结果
    System.out.printf("dijkstra(%c): \n", mVexs[vs]);
    for (int i=0; i < mVexs.length; i++)
        System.out.printf("  shortest(%c, %c)=%d\n", mVexs[vs], mVexs[i], dist[i]);
}

2.A*

import java.util.ArrayList;

// A*算法寻路
public class AStar2 {
    public static final int[][] maps = {
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0},
    };

    public static int straight = 10;
    public static int diagonal = 14;

    // 开放列表
    public static ArrayList<Node> openList = new ArrayList<>();
    // 闭合列表
    public static ArrayList<Node> colseList = new ArrayList<>();
    // 方向
    public static int[][] direct = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

    public static void main(String[] args) {
        //定点:起点终点
        Node start = new Node(5, 1);
        Node end = new Node(5, 4);

        Node endNode = findPath(start, end);

        printMap(maps, start, end);

        ArrayList<Node> arrayList = endNode != null ? getPaths(endNode) : null;

        printPaths(arrayList);

    }

    // 从起点开始,找到到终点的一条最短路径
    private static Node findPath(Node start, Node end) {
        start.G = 0;
        openList.add(start);

        while (!openList.isEmpty()) {
            //从开放列表中拿到最小F节点
            Node cureNode = minFINOpenList(openList);
            openList.remove(cureNode);
            // 将该节点加入到闭合列表中
            colseList.add(cureNode);

            // 当前节点的全部合法邻居
            ArrayList<Node> neighbors = getNeighbor(cureNode);
            for (Node nbrNode : neighbors) {
                // 邻居已经在openList
                if (exists(openList, nbrNode) != null)
                    updateG(cureNode, nbrNode);
                    // 邻居不在openList
                else joinOpenList(cureNode, nbrNode, end);
            }
            if (exists(openList, end) != null)
                return exists(openList, end);
        }

        return null;
    }

    private static ArrayList<Node> getPaths(Node endNode) {
        ArrayList<Node> arrayList = new ArrayList<>();
        Node parent = endNode;
        while (parent != null) {
            arrayList.add(parent);
            parent = parent.parent;
        }
        return arrayList;
    }

    private static int calStep(Node node, Node cur) {
        if (inLine(node, cur))
            return straight;
        else return diagonal;
    }

    private static int calH(Node endNode, Node nbrNode) {
        return Math.abs(endNode.y - nbrNode.y) + Math.abs(endNode.x - nbrNode.x);
    }

    // 计算距离起点的距离
    private static int calG(Node cureNode, Node nbrNode) {
        int step = calStep(cureNode, nbrNode);
        return cureNode.G + step;
    }

    private static boolean inLine(Node nbr, Node cur) {
        if (nbr.x == cur.x || nbr.y == cur.y)
            return true;
        return false;
    }

    // 途径当前节点到达节点node的路径G会不会更短
    private static void updateG(Node cureNode, Node nbrNode) {
        int step = calStep(cureNode, nbrNode);
        int G = calG(cureNode, nbrNode);
        if (G < nbrNode.G) {
            nbrNode.G = G;
            nbrNode.parent = cureNode;
            nbrNode.calcF();
        }
    }

    private static void joinOpenList(Node curNode, Node nbrNode, Node endNode) {
        openList.add(nbrNode);
        nbrNode.parent = curNode;
        nbrNode.G = calG(curNode, nbrNode);
        nbrNode.H = calH(endNode, nbrNode);
        nbrNode.calcF();
    }

    // 达到当前节点的可达,且不在closeList中的邻居节点
    private static ArrayList<Node> getNeighbor(Node cureNode) {
        ArrayList<Node> arrayList = new ArrayList<>();
        //从当前节点想八个方向扩散
        for (int i = 0; i < 8; i++) {
            int newRow = cureNode.x + direct[i][0];
            int newCol = cureNode.y + direct[i][1];
            //当前邻居节点: 可达、不在closeList中
            if (isAccesse(newRow, newCol) && !exists(colseList, newRow, newCol)) {
                arrayList.add(new Node(newRow, newCol));
            }
        }
        return arrayList;
    }

    private static Node exists(ArrayList<Node> colseList, Node cur) {
        for (Node node : colseList) {
            if (node.x == cur.x && node.y == cur.y)
                return node;
        }
        return null;
    }

    private static boolean exists(ArrayList<Node> colseList, int newX, int newY) {
        for (Node node : colseList) {
            if (node.x == newX && node.y == newY)
                return true;
        }
        return false;
    }

    // 可达性分析(非障碍物)
    private static boolean isAccesse(int newX, int newY) {
        if (0 <= newX && newX < maps.length && 0 <= newY && newY < maps[0].length)
            return maps[newX][newY] == 0;
        return false;
    }

    // 从开放列表中找到最小F=G+H的节点
    private static Node minFINOpenList(ArrayList<Node> openList) {
        Node min = openList.get(0);
        for (Node node : openList) {
            if (node.F < min.F)
                min = node;
        }
        return min;
    }

    private static void printMap(int[][] maps, Node start, Node end) {

        for (int col = 0; col < maps[0].length; col++) {
            System.out.print("\t" + col + "");
        }
        System.out.print("\n-----------------------------------------\n");
        int count = 0;
        for (int row = 0; row < maps.length; row++) {
            for (int col = 0; col < maps[0].length; col++) {
                if (col == 0)
                    System.out.print(count++ + "|\t");
                if (row == start.x && col == start.y || row == end.x && col == end.y)
                    System.out.print("X\t");
                else
                    System.out.print(maps[row][col] + "\t");
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void printPaths(ArrayList<Node> arrayList) {
        if (arrayList == null) {
            System.out.println("无路可走");
            return;
        }

        // 地图形式
        for (int col = 0; col < maps[0].length; col++) {
            System.out.print("\t" + col + "");
        }
        System.out.print("\n-----------------------------------------\n");
        int count = 0;

        for (int row = 0; row < maps.length; row++) {
            for (int col = 0; col < maps[0].length; col++) {
                if (col == 0)
                    System.out.print(count++ + "|\t");
                if (exists(arrayList, row, col)) {
                    System.out.print("X\t");
                } else {
                    System.out.print(maps[row][col] + "\t");
                }

            }
            System.out.println();
        }
        System.out.println();
        // 路径形式
        for (int i = arrayList.size() - 1; i >= 0; i--) {
            if (i == 0)
                System.out.print(arrayList.get(i));
            else
                System.out.print(arrayList.get(i) + "->");
        }
        System.out.println();
    }


}

3.BFS

private static void bfs(HashMap<Character, LinkedList<Character>> graph,HashMap<Character, Integer> dist,char start)
{
    Queue<Character> q=new LinkedList<>();
    q.add(start);//将s作为起始顶点加入队列
    dist.put(start, 0);
    int i=0;
    while(!q.isEmpty())
    {
        char top=q.poll();//取出队首元素
        i++;
        System.out.println("The "+i+"th element:"+top+" Distance from s is:"+dist.get(top));
        int d=dist.get(top)+1;//得出其周边还未被访问的节点的距离
        for (Character c : graph.get(top)) {
            if(!dist.containsKey(c))//如果dist中还没有该元素说明还没有被访问
            {
                dist.put(c, d);
                q.add(c);
            }
        }
    }
}

4.dfs

private static void dfs(HashMap<Character , LinkedList<Character>> graph,HashMap<Character, Boolean> visited)
{
    visit(graph, visited, 'u');//为了和图中的顺序一样,我认为控制了DFS先访问u节点
    visit(graph,visited,'w');
}
private static void visit(HashMap<Character , LinkedList<Character>> graph,HashMap<Character, Boolean> visited,char start)
{
    if(!visited.containsKey(start))
    {
        count++;
        System.out.println("The time into element "+start+":"+count);//记录进入该节点的时间
        visited.put(start, true);
        for (char c : graph.get(start)) 
        {
        if(!visited.containsKey(c))
        {
            visit(graph,visited,c);//递归访问其邻近节点
        }
        }
        count++;
        System.out.println("The time out element "+start+":"+count);//记录离开该节点的时间
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\protocol\Parser.js:437 throw err; // Rethrow non-MySQL errors ^ Error: secretOrPrivateKey must have a value at module.exports [as sign] (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\jsonwebtoken\sign.js:107:20) at Query.<anonymous> (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\router_handler\2user.js:49:26) at Query.<anonymous> (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\Connection.js:526:10) at Query._callback (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\Connection.js:488:16) at Sequence.end (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24) at Query._handleFinalResultPacket (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\protocol\sequences\Query.js:149:8) at Query.EofPacket (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\protocol\sequences\Query.js:133:8) at Protocol._parsePacket (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\protocol\Protocol.js:291:23) at Parser._parsePacket (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\protocol\Parser.js:433:10) at Parser.write (C:\Users\admin\Desktop\前端开发\Node.js\day6\code\api_server\node_modules\mysql\lib\protocol\Parser.js:43:10) Node.js v18.12.1
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值