首页 > 其他分享 >服务中心选址

服务中心选址

时间:2023-09-07 14:02:56浏览次数:50  
标签:right min -- positions double 选址 服务中心 left

题目描述

一个快递公司希望在一条街道建立新的服务中心。公司统计了该街道中所有区域在地图上的位置,并希望能够以此为依据为新的服务中心选址: 使服务中心到所有区域的距离的总和最小。

给你一个数组positions,其中positions = [left, right] 表示第i个区域在街道上的位置 其中left代表区域的左侧的起点,right代表区域的右侧终点,假设服务中心的位置为location

  • 如果第i个区域的右侧终点right满足 right< location,则第i个区域到服务中心的距离为 location - right
  • 如果第i个区域的左侧起点left 满足 left >location,则第i个区域到服务中心的距离为left-location
  • 如果第i个区域的两侧left, right满足left <= location <= right,则第i个区域到服务中心的距离为0

选择最佳的服务中心位置为location,请返回最佳的服务中心位置到所有区域的距离总和的最小值

输入描述

先输入区域数组 positions 的长度n 服务中心选址_极值

  • 接下来服务中心选址_用例_02行,每行输入成对的 服务中心选址_用例_03服务中心选址_数组_04值,以空格隔开
  • 服务中心选址_数组_05
  • 服务中心选址_用例_06

输出描述

输出为 服务中心选址_用例_07的值

用例

用例一
--输入
3
1 2
3 4
10 20
--输出
8
--说明
无

用例二
--输入
2
1 4
4 5
--输出
0
--说明
无

用例三
--输入
4
5 6
1 8
7 15
2 4
--输出
3
--说明
无

用例四
--输入
6
1 3
4 9
2 15
6 27
15 17
5 8
--输出
12

用例五
--输入
16
41 67
0 34
24 69
58 78
62 64
5 45
27 81
61 91
42 95
27 36
4 91
2 53
82 92
16 21
18 95
26 47
--输出
127

题目解析

  • 根据题目可以得到,所有的区域都在一条坐标线上。
  • 那么可以对 区域数组 positions 进行排序,记录数组长度为 n
  • 很显然 location 的位置选择应该在 {positions[0][0], positions[n-1][1]} 之间
  • 这一点不论证,画画图很轻松看出来。
  • 然后这里直观地可以用二分法来解决,因为最佳位置肯定是在 {positions[0][0], positions[n-1][1]} 之间
  • 但是这个时候产生问题了,没有办法选取一个 “参考值” 来执行二分法
  • 回到题目中的问题,假设有一点作为最佳服务中心位置满足 :“到所有区域的距离总和的值最小”
  • 那么该点,向左或者向右移动的话,距离总和是增大的。如下图
  • 如何求这个极值呢?
  • 这里需要运用到“三分法” 的知识

三分法

三分法学习参考

结合题目理解

  • 由之前分析,可以得到 positions 数组,最左边和最右边的位置坐标,分别记为 min,max由此可以得到中心点mid
  • 如下图

服务中心选址_用例_08

  • 根据图示,服务中心的最佳选址位置在 点 mid
  • 那么现在问题变成了,如何求得 mid 点所在的位置.

  • 如下图,考虑一种最简单的情况。
  • 点 1,3 对应计算出来的距离总和为 b ,点 2 计算出来的距离总和为 a
  • 很显然 服务中心选址_数组_09
  • 最佳选址位置应该选在点 2
  • 那么想要找到 最佳选址位置,在计算过程中需要确定 3 个点
  • 一个是中心点 计算出的距离总和记为 mid_distance
  • 一个是中心点左边的点 计算出的距离总和记为 left_distance
  • 一个是中心点右边的点 计算出的距离总和记为 right_distance
  • 三个点计算出来的距离,有以下几种情况
  • 根据选点示例,每一次选择三个点,然后分别计算距离总和。
  • 如果出现 case1 图示情况,证明选点需要向右移,因为很显然,“极值”在右边,三个点一起移动
  • 如果出现 case2 图示情况,证明选点需要向左移,因为很显然,“极值”在左边,三个点一起移动
  • 直到找到 -- “最佳选址”

show code

import java.util.Scanner;

/**
 * desc :  <a href="https://blog.csdn.net/qfc_128220/article/details/128808359">服务中心选址</a>
 * <p>
 * create time : 2023/9/5 17:20
 */
public class ServiceCenterSiteSelection {

    public static void main(String[] args) {
        double l = 1e-5;
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int n = in.nextInt();
            int[][] positions = new int[n][2];

            for (int i = 0; i < n; i++) {
                positions[i][0] = in.nextInt();
                positions[i][1] = in.nextInt();
            }

            serviceCenterSiteSelection(positions);
        }
    }

    private static void serviceCenterSiteSelection(int[][] positions) {
        // 首先去拿到 最左边 和 最右边的坐标
        double min_left = Integer.MAX_VALUE,max_right = 0;
        for (int[] position : positions) {
            min_left = Math.min(position[0], min_left);
            max_right = Math.max(position[1], max_right);
        }

        // 1e-5:表示 10 的 -5 次方,即 0.00001.
        double eps = 1e-5;

        while(max_right - min_left >= eps) {
            // 进行三等分
            double k = (max_right - min_left) / 3;
            double m_l = min_left + k;
            double m_r = max_right - k;

            // 计算 mid 偏左边的位置.
            double l_distance = dealDistance(positions, m_l);
            // 计算 mid 偏右边的位置.
            double r_distance = dealDistance(positions, m_r);

            if(l_distance < r_distance) {
                max_right = m_r;
            } else {
                min_left = m_l;
            }
        }

        // 此时  点 min_left :为最佳估计点,最接近 最佳选址位置.
        
        System.out.println((int) dealDistance(positions, min_left));
    }

    private static double dealDistance(int[][] positions, double mid) {
        double ans = 0;
        for (int[] position : positions) {
            double l = position[0], r = position[1];
            if(l > mid) {
                //  在左边
                ans += l - mid;
            } else if(r < mid) {
                ans += mid - r;
            }
        }
        return ans;
    }

}

标签:right,min,--,positions,double,选址,服务中心,left
From: https://blog.51cto.com/u_16079703/7396587

相关文章

  • 铺先生:店铺选址要警惕的点,内行人才知道
    要想店铺经营好,店铺选址要谨慎。想开店就得先找到合适的场地,一般有经验的内行人都会通过一些细节判断来让自己提高找到好地址的概率。但是其中一些点,需要谨慎对待,否则可能适得其反。下面就让小编给大家讲讲店铺选址要警惕的点。1. 预算合理使用我们不管是做什么事情,在行动之前一......
  • 铺先生:广州开店选址细节,帮助大家找到合适的地址
    在广州这座美丽的一线大都市中,有着很多的朝九晚五的打工人,他们厌倦了打工的生活,想着找到一个合适的地址开一家属于自己的店铺。可是,自己对于开店选址这件事并不是很了解,不知道广州开店选址细节都有社什么。那么小编就针对这个问题,说一下看法,帮助大家排忧解难。1. 看街口类型我们......
  • 用友助力交易控股集团打造财务共享服务中心
    交易控股集团成功打造了财务共享服务中心,通过数字化技术和智能化手段提高了财务工作效率和准确性。该中心成立后,财务工作审批效率提高50%,发票查验时间由月均10个工作日锐减为2个工作日,单家企业平均降本增效39%以上。抓住试点契机,交易控股集团在省属一级企业中率先实现财务共享,成立......
  • 供应链产能受限型选址模型——Python实现
    选址问题是运筹学中非常经典的问题。选址问题是指在确定选址对象,选址目标区,成本函数以及存在何种约束条件的前提下,以总物流成本最低或总服务最优或社会效益最大化为总目标,以确定物流系统中物流节点的数量、位置,从而合理规划物流网络结构。设施选址问题(FacilityLocationProblem)自......
  • MATLAB代码:基于多目标遗传算法的分布式电源选址定容
    MATLAB代码:基于多目标遗传算法的分布式电源选址定容研究关键词:选址定容分布式电源多目标遗传算法参考文档:《OptimalSitingandSizingofDistributedGenerationinRadialDistributionSystemusingGeneticAlgorithm》完全复现仿真平台:MATLAB平台主要内容:代码主要做的是......
  • MATLAB程序采用非支配排序遗传算法(NSGA2)求解分布式电源选址定容问题,可作为一个有用的
    MATLAB程序采用非支配排序遗传算法(NSGA2)求解分布式电源选址定容问题,可作为一个有用的参考,程序注释明确,算法原理可以自己搜。YID:4120651507678049......
  • DG储能选址定容模型matlab 程序采用改进粒子群算法,考虑时序
    DG储能选址定容模型matlab程序采用改进粒子群算法,考虑时序性得到分布式和储能的选址定容模型,程序运行可靠这段程序是一个改进的粒子群算法,主要用于解决电力系统中的优化问题。下面我将对程序进行详细分析。首先,程序开始时加载了一些数据文件,包括gfjl、fljl、fhjl1、cjgs和fhbl。这......
  • CCF_201912-2 回收站选址(C++_暴力_枚举)
    思路本来想用dfs来着,有垃圾的地方就标一后来看到数的大小为,数量却只有就果断暴力了…Code#include<bits/stdc++.h>//暴力枚举usingnamespacestd;typedeflonglongll;llx[1010],y[1010],num[1010],score[1010],ans[10];intmain(){ intn; cin>>n; for(inti=......
  • 方芳:基于区块链技术的养殖场建设项目选址研究
    武汉市江夏区交通局武汉市江夏区公路局  武汉市江夏区公路建筑工程公司武汉市江夏城投集团有限公司武汉江夏路桥工程总公司 武汉工程大学 土木工程与建筑学院    方芳    15927602711近年来,区块链技术的发展引起了全球各行各业的广泛关注。在农业领......
  • 财务共享服务中心建设流程是什么样的?
    财务共享是当今众多企业在数智化转型道路上的首选模式,财务共享服务中心由于具备“标准化、流程化、资源共享、信息化”的特点,一改传统财务分散的运作模式,将资源集中共享,大大提升了财务管理效率,也为企业管理打下良好的数据基础。财务共享服务中心的流程再造过程遵循“PDCA”管理循环......