小蜜蜂采蜜暴力解法

这几天室友过了荣耀的机试,听他说有个小蜜蜂采蜜的问题,想着记录一下。

我们采用的是暴力解法,即求出所有的采蜜顺序,并求解距离。求采蜜顺序其实是一个求解全排列的过程,这里要谢谢这位本家人的全排列代码地址。最后附上全部代码。` private List<List> res = new ArrayList<>();

//声明一个布尔数组,用来判断某个索引位置的数字是否被使用过了
private boolean[] used;

public void permute(int[] actual) {
    /**小蜜蜂采蜜
     *action为坐标数组
     */
    //先根据坐标数组得到一个新数组(用来求全排列),里面的元素是从1到action.length/2

    int[] nums = new int[actual.length / 2];
    for (int i = 1; i <= actual.length / 2; i++) {
        nums[i - 1] = i;

    }

    used = new boolean[nums.length];
    List<Integer> preList = new ArrayList<>();
    generatePermutation(nums, 0, preList);

    //存储最小距离
    double min_distance = Double.MAX_VALUE;
    //存储最小距离对应的采蜜顺序
    List<Integer> min_queue= null;


    //根据全排列的结果来取对应的坐标 并计算距离

    for (int i = 0; i < res.size(); i++) {
        int firstindex = res.get(i).get(0);
        int x_x = actual[2 * (firstindex - 1)] * actual[2 * (firstindex - 1)];
        int y_y = actual[2 * (firstindex - 1) + 1] * actual[2 * (firstindex - 1) + 1];
        double distance = Math.sqrt(x_x + y_y);
        for (int j = 1; j < res.get(i).size(); j++) {
            int index = res.get(i).get(j);
            int pre_index = res.get(i).get(j - 1);
            int x_cha = (actual[2 * (index - 1)] - actual[2 * (pre_index - 1)]) * (actual[2 * (index - 1)] - actual[2 * (pre_index - 1)]);
            int y_cha = (actual[2 * (index - 1) + 1] - actual[2 * (pre_index - 1) + 1]) * (actual[2 * (index - 1) + 1] - actual[2 * (pre_index - 1) + 1]);
            distance += Math.sqrt(x_cha + y_cha);


        }
        System.out.println(res.get(i));
        System.out.println(distance);
        if(distance<min_distance){
            min_distance=distance;
            min_queue=res.get(i);
        }

    }

    System.out.println("最小的顺序是"+min_queue);
    System.out.println("最小距离是"+min_distance);

}


private void generatePermutation(int[] nums, int index, List<Integer> preList) {
    /**
     * 回溯
     *求全排列
     * @param nums    给定数组
     * @param index   当前考察的索引位置
     * @param preList 先前排列好的子序列
     */
    //index 等于给定数组的长度时,说明一种排列已经形成,直接将其加入成员变量 res 里
    if (index == nums.length) {
        //这里需要注意java的值传递
        //此处必须使用重新创建对象的形式,否则 res 列表中存放的都是同一个引用
        res.add(new ArrayList<>(preList));
        return;
    }

    for (int i = 0; i < nums.length; i++) {
        if (!used[i]) {
            preList.add(nums[i]);
            used[i] = true;
            generatePermutation(nums, index + 1, preList);
            //一定要记得回溯状态
            preList.remove(preList.size() - 1);
            used[i] = false;
        }
    }
    return;
}`
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值