前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2022-04-19:A*算法, 过程和Dijskra高度相处, 有到终点的预估函数, 只要预估值<=客观上最优距离,就是对的。 预估函数是一种吸引力: 1)合

2022-04-19:A*算法, 过程和Dijskra高度相处, 有到终点的预估函数, 只要预估值<=客观上最优距离,就是对的。 预估函数是一种吸引力: 1)合

原创
作者头像
福大大架构师每日一题
发布2022-04-19 19:47:42
2400
发布2022-04-19 19:47:42
举报

2022-04-19:A*算法,

过程和Dijskra高度相处,

有到终点的预估函数,

只要预估值<=客观上最优距离,就是对的。

预估函数是一种吸引力:

1)合适的吸引力可以提升算法的速度;

2)吸引力“过强”会出现错误。

答案2022-04-19:

具体见代码。

代码用rust编写。代码如下:

代码语言:go
复制
use rand::Rng;
fn main() {
    let mut map: Vec<Vec<isize>> = vec![];
    for i in 0..10 {
        map.push(vec![]);
        for j in 0..10 {
            map[i].push(0);
        }
    }
    for i in 0..map.len() {
        for j in 0..map[0].len() {
            map[i][j] = rand::thread_rng().gen_range(1, 10);
        }
    }
    let startX: isize = 0;
    let startY: isize = 0;
    let targetX: isize = 4;
    let targetY: isize = 7;
    let ret: isize = min_distance2(&mut map, startX, startY, targetX, targetY);
    for i in 0..10 {
        println!("{:?}", map[i]);
    }
    println!("{}", ret);
}

const MAX_VALUE: isize = 9223372036854775807;

fn min_distance2(
    map: &mut Vec<Vec<isize>>,
    startX: isize,
    startY: isize,
    targetX: isize,
    targetY: isize,
) -> isize {
    if map[startX as usize][startY as usize] == 0 || map[targetX as usize][targetY as usize] == 0 {
        return MAX_VALUE;
    }
    let n = map.len() as isize;
    let m = map[0].len() as isize;
    let mut heap: Vec<Vec<isize>> = Vec::new();
    let mut closed: Vec<Vec<bool>> = Vec::new();
    for i in 0..n {
        closed.push(Vec::new());
        for j in 0..m {
            closed[i as usize].push(false);
        }
    }
    let mut t = vec![
        map[startX as usize][startY as usize],
        distance(startX, startY, targetX, targetY),
        startX,
        startY,
    ];
    heap.push(t);
    let mut ans = MAX_VALUE;
    while heap.len() > 0 {
        //用切片模拟堆,所以需要排序
        heap.sort_by(|x, y| (x[0] + x[1]).cmp(&(y[0] + y[1])));

        // 报错
        // let mut cur: &Vec<isize> = &(heap[0]);
        // heap.remove(0);

        let mut fromDistance: isize = heap[0][0];
        let mut row: isize = heap[0][2];
        let mut col: isize = heap[0][3];
        heap.remove(0); //必须放在这里
        if (closed[row as usize][col as usize]) {
            continue;
        }
        closed[row as usize][col as usize] = true;
        if (row == targetX && col == targetY) {
            ans = fromDistance;
            break;
        }
        add2(
            fromDistance,
            row - 1,
            col,
            targetX,
            targetY,
            n,
            m,
            map,
            &mut closed,
            &mut heap,
        );
        add2(
            fromDistance,
            row + 1,
            col,
            targetX,
            targetY,
            n,
            m,
            map,
            &mut closed,
            &mut heap,
        );
        add2(
            fromDistance,
            row,
            col - 1,
            targetX,
            targetY,
            n,
            m,
            map,
            &mut closed,
            &mut heap,
        );
        add2(
            fromDistance,
            row,
            col + 1,
            targetX,
            targetY,
            n,
            m,
            map,
            &mut closed,
            &mut heap,
        );
    }
    return ans;
}

fn add2(
    pre: isize,
    row: isize,
    col: isize,
    targetX: isize,
    targetY: isize,
    n: isize,
    m: isize,
    map: &mut Vec<Vec<isize>>,
    closed: &mut Vec<Vec<bool>>,
    heap: &mut Vec<Vec<isize>>,
) {
    if (row >= 0
        && row < n
        && col >= 0
        && col < m
        && map[row as usize][col as usize] != 0
        && !closed[row as usize][col as usize])
    {
        let mut t = vec![
            pre + map[row as usize][col as usize],
            distance(row, col, targetX, targetY),
            row,
            col,
        ];
        heap.push(t);
    }
}

// 曼哈顿距离
fn distance(curX: isize, curY: isize, targetX: isize, targetY: isize) -> isize {
    return abs(targetX - curX) + abs(targetY - curY);
}

fn abs(a: isize) -> isize {
    if a < 0 {
        -a
    } else {
        a
    }
}

执行结果如下:

在这里插入图片描述
在这里插入图片描述

左神java代码

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com