哈希算法-Time33

现在几乎所有流行的HashMap都采用了DJB Hash Function,俗称“Time33”算法

Times33实现起来非诚简单,不断的与33相乘:nHash = nHash*33 + *key++

主要实现:

unsigned int time33(char *str){
    unsigned int hash = 5381;
    while(*str){
        hash += (hash << 5 ) + (*str++);
    }
    return (hash & 0x7FFFFFFF);
}

 

转载于:https://www.cnblogs.com/LIUWEI123/p/7966127.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Anytime repair A* (ARA*) 算法是一种在有限时间内求解最优路径的启发式搜索算法。相比于传统的 A* 算法,ARA* 算法允许在有限时间内返回一个次优解,然后继续搜索以找到更优解。本文将介绍如何用 Java 实现 ARA* 算法。 首先,定义一个节点类来表示搜索树中的每个节点: ```java public class Node { public int x; public int y; public double g; public double h; public double f; public Node parent; public Node(int x, int y) { this.x = x; this.y = y; } } ``` 其中,x 和 y 表示节点在地图上的坐标,g 表示从起点到该节点的实际代价,h 表示从该节点到终点的估计代价,f = g + h 表示该节点的总代价,parent 表示该节点的父节点。 然后,定义一个 ARAStar 类来实现 ARA* 算法: ```java import java.util.*; public class ARAStar { private double weight; private double epsilon; public ARAStar(double weight, double epsilon) { this.weight = weight; this.epsilon = epsilon; } public List<Node> search(Node start, Node goal, Map<Node, List<Node>> graph, long timeLimit) { PriorityQueue<Node> open = new PriorityQueue<>(Comparator.comparingDouble(node -> node.f)); Map<Node, Double> gScore = new HashMap<>(); Map<Node, Double> fScore = new HashMap<>(); Map<Node, Node> cameFrom = new HashMap<>(); open.add(start); gScore.put(start, 0.0); fScore.put(start, weight * heuristic(start, goal)); long startTime = System.currentTimeMillis(); while (!open.isEmpty()) { if (System.currentTimeMillis() - startTime > timeLimit) { break; } Node current = open.poll(); if (current.equals(goal)) { return reconstructPath(cameFrom, current); } for (Node neighbor : graph.getOrDefault(current, Collections.emptyList())) { double tentativeGScore = gScore.get(current) + distance(current, neighbor); if (!gScore.containsKey(neighbor) || tentativeGScore < gScore.get(neighbor)) { cameFrom.put(neighbor, current); gScore.put(neighbor, tentativeGScore); fScore.put(neighbor, weight * tentativeGScore + (1 - weight) * heuristic(neighbor, goal)); if (!open.contains(neighbor)) { open.add(neighbor); } } } if (fScore.get(current) > epsilon * fScore.get(start)) { fScore.replaceAll((node, f) -> Math.max(f, gScore.get(node) + epsilon * heuristic(node, goal))); open.addAll(open.stream() .filter(node -> fScore.get(node) > epsilon * fScore.get(start)) .map(node -> { node.f = fScore.get(node); return node; }).collect(Collectors.toList())); } } return null; } private List<Node> reconstructPath(Map<Node, Node> cameFrom, Node current) { List<Node> path = new ArrayList<>(); path.add(current); while (cameFrom.containsKey(current)) { current = cameFrom.get(current); path.add(0, current); } return path; } private double distance(Node a, Node b) { return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); } private double heuristic(Node a, Node b) { return distance(a, b); } } ``` 其中,weight 表示启发式函数的权重,epsilon 表示次优解的最大相对误差。search 方法接收起点、终点、图和时间限制,返回搜索结果。图使用邻接表表示,每个节点是一个列表,包含与其相邻的节点。 在 search 方法中,我们使用优先队列存储开放列表,使用哈希表存储 gScore、fScore 和 cameFrom。对于每个节点,我们首先计算其 f 值,然后将其加入开放列表。当开放列表为空时,搜索结束。 在每次从开放列表中取出节点时,我们检查它是否为终点。如果是,则返回重构的路径。否则,对于每个相邻节点,我们计算 tentativeGScore,并更新 gScore、fScore 和 cameFrom。如果该节点不在开放列表中,我们将其加入开放列表。 然后,我们检查当前节点的 f 值是否超过了 epsilon 倍起点的 f 值。如果是,则重新计算所有节点的 f 值,并将开放列表中 f 值超过 epsilon 倍起点的节点重新加入开放列表。 最后,我们使用 reconstructPath 方法重构路径。该方法从终点开始,沿着 cameFrom 指针一直向前,直到到达起点。然后,它将路径反转并返回。 下面是一个使用 ARAStar 类的示例: ```java public static void main(String[] args) { Node start = new Node(1, 1); Node goal = new Node(8, 8); Map<Node, List<Node>> graph = new HashMap<>(); // 添加节点及其相邻节点 // ... ARAStar araStar = new ARAStar(1.0, 0.1); List<Node> path = araStar.search(start, goal, graph, 1000); if (path != null) { for (Node node : path) { System.out.println("(" + node.x + ", " + node.y + ")"); } } } ``` 在该示例中,我们创建了起点、终点和图,并使用 ARAStar 类进行搜索。ARAStar 构造函数接收 weight 和 epsilon 参数,search 方法接收时间限制参数。如果算法能够在指定时间内找到路径,则返回路径,否则返回 null。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值