取物资问题

该博客介绍了如何在二维地图上为军营设置补给站,以使军营到补给站的最大距离最小化。通过分析得出补给站应在军营横坐标范围内的中间位置,采用三分查找算法进行优化。具体实现中,博客提供了一个Java代码示例,展示了如何运用三分查找法来确定最佳补给站位置。算法的精度可以通过调整循环次数来控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

取物资

在一个二维地图上有很多军营,每个军营的坐标为(x,y)(x,y),现在你要在xx轴上设置一个补给站,补给站不一定要在整点上,现在想让军营到补给站的距离的最大值最小。
请问最小的最大距离是多少?

兵营的数量小于等于10^4
坐标(x,y)保证0 <= |x|, |y| <= 10000

分析

由题知补给站到军营的距离符合二次函数变化规律。在给定的军营坐标集合中,补给站到军营的最大距离最小的点一定在给定的军营的最小横坐标到最大横坐标
之间,并且越往中间最大距离的值越小。符合三分查查找算法的特征

算法

算法过程如下

  • 取l为给定军营集合的横坐标的最小值,r为给定军营集合的最大值,利用三分法查找补给点

  • 每次取中点和3/4点,优化l,r

  • 由于补给点可能为小数,因此我们需要通过控制三分查找的次数,以控制精度。通常循环次数越多精度越高

具体实现

package com.aim.algorithm;

public class SupplyStation {

    public static void main(String args[]){
        int[][] barracks = new int[3][2];
        barracks[0][0] = 0;
        barracks[0][1] = 0;
        barracks[1][0] = 0;
        barracks[1][1] = 2;
        barracks[2][0] = 2;
        barracks[2][1] = 0;
        System.out.println(fetchSuppliesII(barracks));
    }

    /**
     * @param barracks: the position of barracks
     * @return: the minimum of the maximum of the distance
     */
    public static double fetchSuppliesII(int[][] barracks) {
        // write your code here
        double l = Integer.MAX_VALUE;
        double r = Integer.MIN_VALUE;
        for (int i = 0; i < barracks.length; i++) {
            for (int j = 0; j < barracks[i].length; j++) {
                if (barracks[i][j] < l) {
                    l = barracks[i][j];
                }
                if (barracks[i][j] > r) {
                    r = barracks[i][j];
                }
            }
        }
        int loop = 100;
        double mid = 0;
        for (int i = 0; i < loop; i++) {
            mid = l + (r - l) / 2;
            double midmid = mid + (r - mid) / 2;
            if(maxDistance(mid, barracks) > maxDistance(midmid, barracks)){
                l = mid;
            } else {
                r = midmid;
            }
        }
        return maxDistance(mid, barracks);
    }

    private static double maxDistance(double x, int[][] barracks) {
        double maxDistance = Double.MIN_VALUE;
        for (int i = 0; i < barracks.length; i++) {
            double distance = Math.sqrt((barracks[i][0] - x) * (barracks[i][0] - x) + (barracks[i][1]*barracks[i][1]));
            if(maxDistance < distance){
                maxDistance = distance;
            }
        }
        return maxDistance;
    }

}

知识点整理

三分查找算法

三分查找法是用于查找二次函数,极值问题的算法。类似于二分查找,某值的过程。但二分查找是在一次函数中确定某个值,要求数组是单调的。三分查找面对的是呈二次函数规则分配的数组的极值算法,对于二次函数分布的数据二分查找无能为力。

在这里插入图片描述

三分查找算法过程如下

  • 确定查找左边界l,右边界r

  • 取l至r中间点mid,取l至r 3/4 点midmid

  • 比较mid、midmid对应值,若mid > midmid,则l = mid; 若mid <= midmid,则取r = midmid

  • 循环取中间点,3/4点逻辑并比较值,移动l、r值,使得无限趋近于极值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值