基于经纬度和工作日的拜访轨迹问题
一 问题描述
设有 n 家客户,n <= 24,每个客户有如下属性(客户名称、客户类型、经度、纬度、每月拜访次数)。
每个客户 m 天拜访 1 次。
每个客户每天最多拜访 8 次。
给出一个月的工作日列表。
求一个月拜访轨迹。
二 输入和输出
1 输入说明
第 1 行代表客户数 n 和拜访频率 m。
接下来的 n 行描述每个客户,每个客户信息包括(客户名称、客户类型、经度、纬度、每月拜访次数),客户类型有:M-商业拜访,H-医院拜访、P-药房拜访
接下来的一行是工作日列表
2 输出说明
药代这个月每天拜访轨迹。
三 输入和输出样例
1 输入样例
24 3
H1 H 117.196067 39.103303 8
H2 H 117.206175 39.111509 8
H3 H 117.187551 39.109744 8
H4 H 117.179981 39.113295 8
H5 H 117.183536 39.125713 8
H6 H 117.209626 39.12228 8
H7 H 117.233087 39.082267 8
H8 H 117.195568 39.111846 8
H9 H 117.207421 39.121483 8
H10 H 117.191717 39.104914 8
H11 H 117.200753 39.109458 8
H12 H 117.182597 39.102957 8
H13 H 117.188228 39.128191 8
H14 H 117.193003 39.121008 8
H15 H 117.190858 39.135014 8
H16 H 117.179979 39.11038 8
M1 B 117.18461 39.117381 4
M2 B 117.206176 39.127932 4
M3 B 117.185073 39.124452 4
M4 B 117.183584 39.121472 4
M5 B 117.172522 39.126702 4
M6 B 117.185248 39.104909 4
M7 B 117.192618 39.129049 4
M8 B 117.181509 39.123574 4
1 2 3 4 5 7 8 9 10 11 12 14 15 16 17 18 19 21 22 23 24 25 26 28 29 30
2 输出样例
1 号拜访客户:H9 > H6 > M2 > H15 > M8 > M5 > H3 > H12 >
2 号拜访客户:H4 > H16 > M6 > H10 > H1 > M3 > H13 > H7 >
3 号拜访客户:M7 > H5 > M4 > M1 > H14 > H8 > H11 > H2 >
4 号拜访客户:M2 > H6 > H9 > H15 > M8 > M5 > H3 > H12 >
5 号拜访客户:H1 > H10 > M6 > H16 > H4 > M3 > H13 > H7 >
7 号拜访客户:H14 > M4 > M1 > H5 > M7 > H8 > H11 > H2 >
8 号拜访客户:H15 > M8 > M5 > H3 > H12 > H9 > H6 > M2 >
9 号拜访客户:H7 > H1 > H10 > M6 > H16 > H4 > M3 > H13 >
10 号拜访客户:H5 > M4 > M1 > H14 > M7 > H8 > H11 > H2 >
11 号拜访客户:H12 > H3 > M8 > M5 > H15 > M2 > H6 > H9 >
12 号拜访客户:H7 > H1 > H10 > M6 > H16 > H4 > M3 > H13 >
14 号拜访客户:H8 > H11 > H2 > H14 > M4 > M1 > H5 > M7 >
15 号拜访客户:H6 > H9 > H15 > H3 > H12 >
16 号拜访客户:H7 > H1 > H10 > H16 > H4 > H13 >
17 号拜访客户:H8 > H11 > H2 > H14 > H5 >
18 号拜访客户:H3 > H12 > H9 > H6 > H15 >
19 号拜访客户:H16 > H4 > H10 > H1 > H13 > H7 >
21 号拜访客户:H8 > H11 > H2 > H14 > H5 >
22 号拜访客户:H9 > H6 > H15 > H3 > H12 >
23 号拜访客户:H13 > H4 > H16 > H10 > H1 > H7 >
24 号拜访客户:H5 > H14 > H8 > H11 > H2 >
25 号拜访客户:H3 > H12 > H9 > H6 > H15 >
26 号拜访客户:H4 > H16 > H10 > H1 > H13 > H7 >
28 号拜访客户:H8 > H11 > H2 > H14 > H5 >
四 代码
package com.platform.modules.alg.alglib.sdgt0002;import java.util.*;public class Sdgt0002 {public String output = "";/*** 默认地球半径*/private static double EARTH_RADIUS = 6371000; // 赤道半径(单位m)private final int inf = 0x3f3f3f3f;// 客户数private int n;// 拜访频率,几天拜访一次private int frequency;// 拜访天数,每月拜访多少天private int days;// 客户批次 map,第1个泛型代表第几批客户,第2个泛型代表批次客户列表private Map<Integer, List<Customer>> batchCustomerMap = new HashMap<>();// 拜访轨迹 map,第1个泛型代表每月第几天,第2个泛型代表该天拜访的客户列表private Map<Integer, List<Customer>> visitMap = new HashMap<>();// 轨迹计算public String cal(String input) {String[] line = input.split("\n");String[] params = line[0].split(" ");n = Integer.parseInt(params[0]); // 客户数frequency = Integer.parseInt(params[1]); // 几天拜访一次//days = Integer.parseInt(params[2]); // 每月拜访多少天// 对输入数据进行处理for (int i = 1; i <= n; i++) {String[] customerStr = line[i].split(" ");Customer customer = new Customer();customer.setName(customerStr[0]); // 客户名称customer.setType(customerStr[1]); // 客户类别customer.setLocationLon(Double.parseDouble(customerStr[2])); // 经度customer.setLocationLat(Double.parseDouble(customerStr[3])); // 纬度customer.setTotalCount(Integer.parseInt(customerStr[4])); // 每月最多拜访次数// 批次客户列表加第1个客户,如果 frequency = 3,则批次下标范围 [0,1,2]if (batchCustomerMap.get(i % frequency) == null) {List<Customer> batchCustomerList = new ArrayList();batchCustomerList.add(customer);batchCustomerMap.put(i % frequency, batchCustomerList);} else { // 批次客户列表加其他客户batchCustomerMap.get((i % frequency)).add(customer);}}// 模拟每月的几号String[] days = line[n + 1].split(" ");List batchDays[] = new ArrayList[frequency];for (int i = 0; i < batchDays.length; i++) {batchDays[i] = new ArrayList();}for (int i = 0; i < days.length; i++) {int batchNum = i % frequency;batchDays[batchNum].add(days[i]);}// 每日拜访处理for (int i = 0; i < days.length; i++) {int batch = 0;for (List batchDay : batchDays) {if (batchDay.contains(days[i])) {batch = i % frequency;break;}}// 获取某批次客户列表List<Customer> customers = batchCustomerMap.get(batch);// 打乱批次客户列表顺序Collections.shuffle(customers);List<Customer> selectCustomers = new ArrayList<>();// 选择前8个客户for (int j = 0; j < customers.size(); j++) {if (customers.get(j).getTotalCount() > 0) {selectCustomers.add(customers.get(j));if (selectCustomers.size() >= 8) {break;}}}// 每日拜访的第1个客户if (selectCustomers.size() == 0) continue;Customer startCustomer = selectCustomers.get(0);// 标识该客户已访问startCustomer.setVisited(true);// 修正剩余可拜访次数int plusCount = startCustomer.getTotalCount() - 1;startCustomer.setTotalCount(plusCount);// 创建第 i 号的拜访客户列表List<Customer> oneDayCustomerList = new ArrayList();visitMap.put(i, oneDayCustomerList);// 向 i 号拜访客户列表加第1个客户oneDayCustomerList.add(startCustomer);Customer firstCustomer; // 两次相邻拜访的前一个客户Customer secondCustomer; // 两次相邻拜访的后一个客户Customer nextSelectCustomer = new Customer(); // 下一个选中的客户double tempMinDistance; // 临时最短距离firstCustomer = startCustomer;for (int m = 1; m < selectCustomers.size(); m++) { // 从第2个客户开始处理double minDistance = inf; // 初始化最短距离for (int n = 1; n < selectCustomers.size(); n++) { // 从第2个客户开始处理secondCustomer = selectCustomers.get(n);// 两次相邻拜访的后一个客户如果已经拜访或剩余可拜访次数为0,不处理if (secondCustomer.isVisited() || secondCustomer.getTotalCount() == 0) {continue;}// 计算相邻两个客户的距离tempMinDistance = GetDistance(firstCustomer.getLocationLon(), firstCustomer.getLocationLat(), secondCustomer.getLocationLon(), secondCustomer.getLocationLat());if (tempMinDistance < minDistance) {// 更新最短距离minDistance = tempMinDistance;// 最短距离对应的客户nextSelectCustomer = secondCustomer;}}// 下一个被选中的客户设置为已拜访nextSelectCustomer.setVisited(true);int plusTimes = nextSelectCustomer.getTotalCount() - 1;// 下一个被选中的客户剩余拜访次数nextSelectCustomer.setTotalCount(plusTimes);// 向 i 号拜访客户列表加选中的客户visitMap.get(i).add(nextSelectCustomer);firstCustomer = nextSelectCustomer;}// visited 只对当天拜访起作用,所以要清空 visited 标识for (Customer selectCustomer : customers) {selectCustomer.setVisited(false);}}// 输出处理for (int i = 0; i < days.length; i++) {List<Customer> customers = visitMap.get(i);if (customers == null) {continue;}output += days[i] + " 号拜访客户:";for (Customer customer : customers) {output += customer.getName() + " > ";}output += "\n";}return output;}/*** 功能描述:通过经纬度计算两点之间的距离** @param lon1 第 1 个点的经度* @param lat1 第 1 个点的纬度* @param lon2 第 2 个点经度* @param lat2 第 2 个点纬度* @return 两点间的距离* @author chengqiuming* @date 2022/10/25* @description:*/public double GetDistance(double lon1, double lat1, double lon2, double lat2) {double radLat1 = rad(lat1);double radLat2 = rad(lat2);double a = radLat1 - radLat2;double b = rad(lon1) - rad(lon2);double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));s = s * EARTH_RADIUS;s = Math.round(s * 10000) / 10000;return s;}/*** 转化为弧度(rad)*/private static double rad(double d) {return d * Math.PI / 180.0;}
}class Customer {// 客户名称private String name;// 客户类型 H-医院客户 M-商业公司客户 P-药房拜访private String type;// 经度private Double locationLon;// 纬度private Double locationLat;// 每月最多可拜访次数private int totalCount;// 是否已拜访private boolean visited = false;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getType() {return type;}public void setType(String type) {this.type = type;}public Double getLocationLon() {return locationLon;}public void setLocationLon(Double locationLon) {this.locationLon = locationLon;}public Double getLocationLat() {return locationLat;}public void setLocationLat(Double locationLat) {this.locationLat = locationLat;}public int getTotalCount() {return totalCount;}public void setTotalCount(int totalCount) {this.totalCount = totalCount;}public boolean isVisited() {return visited;}public void setVisited(boolean visited) {this.visited = visited;}
}
五 测试
1 输入
24 3
H1 H 117.196067 39.103303 8
H2 H 117.206175 39.111509 8
H3 H 117.187551 39.109744 8
H4 H 117.179981 39.113295 8
H5 H 117.183536 39.125713 8
H6 H 117.209626 39.12228 8
H7 H 117.233087 39.082267 8
H8 H 117.195568 39.111846 8
H9 H 117.207421 39.121483 8
H10 H 117.191717 39.104914 8
H11 H 117.200753 39.109458 8
H12 H 117.182597 39.102957 8
H13 H 117.188228 39.128191 8
H14 H 117.193003 39.121008 8
H15 H 117.190858 39.135014 8
H16 H 117.179979 39.11038 8
M1 B 117.18461 39.117381 4
M2 B 117.206176 39.127932 4
M3 B 117.185073 39.124452 4
M4 B 117.183584 39.121472 4
M5 B 117.172522 39.126702 4
M6 B 117.185248 39.104909 4
M7 B 117.192618 39.129049 4
M8 B 117.181509 39.123574 4
1 2 3 4 5 7 8 9 10 11 12 14 15 16 17 18 19 21 22 23 24 25 26 28 29 30
2 输出
1 号拜访客户:H15 > M8 > M5 > H3 > H12 > H9 > H6 > M2 >
2 号拜访客户:H1 > H10 > M6 > H16 > H4 > M3 > H13 > H7 >
3 号拜访客户:H14 > M4 > M1 > H5 > M7 > H8 > H11 > H2 >
4 号拜访客户:M2 > H6 > H9 > H15 > M8 > M5 > H3 > H12 >
5 号拜访客户:H13 > M3 > H4 > H16 > M6 > H10 > H1 > H7 >
7 号拜访客户:H14 > M4 > M1 > H5 > M7 > H8 > H11 > H2 >
8 号拜访客户:H6 > H9 > M2 > H15 > M8 > M5 > H3 > H12 >
9 号拜访客户:M3 > H13 > H4 > H16 > M6 > H10 > H1 > H7 >
10 号拜访客户:M1 > M4 > H5 > M7 > H14 > H8 > H11 > H2 >
11 号拜访客户:M8 > M5 > H15 > M2 > H6 > H9 > H3 > H12 >
12 号拜访客户:M3 > H13 > H4 > H16 > M6 > H10 > H1 > H7 >
14 号拜访客户:H8 > H11 > H2 > H14 > M4 > M1 > H5 > M7 >
15 号拜访客户:H15 > H9 > H6 > H3 > H12 >
16 号拜访客户:H7 > H1 > H10 > H16 > H4 > H13 >
17 号拜访客户:H5 > H14 > H8 > H11 > H2 >
18 号拜访客户:H12 > H3 > H9 > H6 > H15 >
19 号拜访客户:H1 > H10 > H16 > H4 > H13 > H7 >
21 号拜访客户:H11 > H2 > H8 > H14 > H5 >
22 号拜访客户:H9 > H6 > H15 > H3 > H12 >
23 号拜访客户:H4 > H16 > H10 > H1 > H13 > H7 >
24 号拜访客户:H2 > H11 > H8 > H14 > H5 >
25 号拜访客户:H12 > H3 > H9 > H6 > H15 >
26 号拜访客户:H1 > H10 > H16 > H4 > H13 > H7 >
28 号拜访客户:H11 > H2 > H8 > H14 > H5 >
基于经纬度和工作日的拜访轨迹问题相关推荐
- 基于经纬度的拜访轨迹问题
一 问题描述 设有 n 家客户,n<=31,每个客户有如下属性(客户名称.客户类型.经度.纬度.每月拜访次数). 每个客户 times 天拜访 1 次. 每个客户每天最多拜访 8 次. 每月天数 ...
- 一种基于贝塞尔曲线的终端定位轨迹拟合方法
一种基于贝塞尔曲线的终端定位轨迹拟合方法 专利名称一种基于贝塞尔曲线的终端定位轨迹拟合方法 技术领域本发明属于卫星导航领域,具体涉及一种基于贝塞尔曲线的终端定位轨迹拟合方法. 背景技术目前有很多设备( ...
- 【手机信令轨迹挖掘01】基于手机信令的用户出行轨迹挖掘之问题定义
手机信令数据 手机信令数据是指移动终端用户在发生通话.短信.上网及变换寻呼区时在运营商网络中产生的大量手机信令数据. 手机信令数据直接来源于运营商(中国移动.中国联通.中国电信)的移动通信系统,通常对 ...
- matlab机器人轨迹规划仿真程序,基于MATLAB的六自由度机器人轨迹规划与仿真.pdf...
基于MATLAB的六自由度机器人轨迹规划与仿真 学兔兔 l 訇 似 基于MATLAB的六自由度机器人轨迹规划与仿真 Trajectory planning and simulation of six- ...
- 基于hyperledger联盟链的汽车轨迹追溯系统 (三)
基于hyperledger联盟链的汽车轨迹追溯系统 一.后端接口搭建 引入模块 插入轨迹完整流程 区块链验证 封装区块信息查询 查询 二.配置路由 三.简单的测试调用 四.个性化的业务功能 一.后端接 ...
- mysql数据范围什么意思_数据都在mysql里的话,基于经纬度的范围查询有什么高效的方案吗...
[今日话题] 数据都在mysql里的话,基于经纬度的范围查询有什么高效的方案吗 – yingang 1. 经纬度搜索(1)-Geohash算法原理 http://hankesi2000.iteye.c ...
- 《整体决策的统一框架和基于时空的高速路自动驾驶轨迹规划》论文分析
文献分析 这篇<整体决策的统一框架和基于时空的高速路自动驾驶轨迹规划>论文,针对过往前任研究的一些不足,建立了决策规划的三个模块,这三个模块针对短期(10hz,一秒运行十次),中期(1hz ...
- 【K-Means】基于经纬度的城市聚类
文章目录 1. 项目准备 1.1. 问题导入 1.2. 数据集简介 2. K-Means算法 2.1. 算法特点 2.2. 算法流程 2.3. 算法缺陷 2.4. 算法改进 3. 实验步骤 3.1. ...
- 轨迹跟踪主要方法_DELMIA教程:基于指令形式的机器人TCP轨迹局部跟踪方法
上一期为大家介绍了基于工具条中的"TCP Trace"命令按钮的全局TCP轨迹跟踪,之所以称之为全局轨迹跟踪,是因为只要命令被打开,机器人运行的全部轨迹都将实现跟踪.既然有全局TC ...
最新文章
- 爱的世界很拥挤,写在读《爱,就这么简单》之后
- 【Git、GitHub、GitLab】十 将git仓库备份到本地
- java数学函数Math类
- 事件---------2
- pyGurobi使用手册
- 18年12月英语六级第二套听力单词
- jscpd--前端代码重复率检测
- “分类” 与 “回归”的概念及区别详解
- mac 恢复未能与服务_MacBook Pro无法与恢复服务器取得联系?
- 小程序关注微信公众号的方法
- 如何减少PDF文件的大小,为pdf瘦身?
- Ubuntu下使用OpenCV显示中文
- Sieve of Eratosthenes(埃拉托色尼筛选法)——C++实现
- 搜索引擎蜘蛛抓取不到网站内容页面的原因总结
- LaTeX入门|(2)定制专属模板
- 中国宽带无线移动互联网论坛-无线传感器网络
- nvidia jetson nano 操作指南
- LocalDate获取本日所在周的周一和周日
- 交换机千兆和百兆对网速影响_千兆网线和百兆网线是否可以通用?
- 移动端H5(JavaScript)识别二维码功能