2D平面上,有m个人(P),n辆自行车(B),还有空白(O)满足以下条件
1.m < n. 
2.不存在两个人,到同一辆自行车距离相等, 距离用abs(x1-x2) + abs(y1-y2)定义
3.每个人尽量找离自己最近的自行车,一旦某辆自行车被占,其他人只能找别的自行车。


OPOBOOP
OOOOOOO
OOOOOOO
OOOOOOO
BOOBOOB

红色的人找到第一行的自行车,距离最近。
蓝色的人离第一行自行车最近,但自行车已经被红色人占有,所以他只能找离他第二近的,右下角的自行车。
问:把人和自行车配对,输出vector<pair<int, int>>每个人对应的自行车. {i, j} 是人i对应自行车j

解法:从自行车开始bfs,碰到最近的人就assign。

有很多自行车和很多人,如果完美匹配自行车和人,就是匹配最近的自行车和最近的人,至少有
一个解,自己设计数据结构。
这道题很开放,需要跟面试官积极交流,厘清条件。
- 比如是人多还是自行车多?如果是人多、自行车少,那么从自行车出发做计算会比较高
效。
- 如果出现相等距离怎么办?例如自行车a到两个人x、y的距离相同,match谁呢?
Solution 1: BFS
我用图来存,然后我从自行车做bfs,碰到最近的人就assign。 Solution 2: Greedy, HashMap + MinHeap
我最后写的是一个比较简单的解法,假设函数给定一堆人和车以及他们的坐标,然后求出所有人 车距离,把这些数值放在一个minh8eap里面,每次拿最小的距离,同时记录下来这个人和这个车 已经match过了,这样依次匹配。 这种解法的缺点是没考虑tie的情况
之后follow up是如果有的时候很多人到同一辆车距离相同,怎么assign,要求全局最优,

我理解的全剧最优就是让每个人走的路加起来和最小,这样找到一个解使得匹配之后所有人和车 的距离之和是最短的。 可以用Greedy,每次都match到最短的pair,但这种未必能确保达到最优解。
或者可以用人为起点做了个bfs,然后得出<Node, distance>的preference list。然后做dfs,找出 最短的distance之和。烙印说可以,不过没写代码。
我问他还有什么更好的解法吗,他说有个汉密尔顿什么什么的算法

是不是搞ACM常用的二分图最大权匹配(用KM算法或网络流)。。。

提了这个解法,就是找到一个解使得匹配之后所有人和车的距离之和是最短的,但面试官说没那么复杂,用greedy的方法先match到最短的,然后依次类推

狗家近期的大杀器人车匹配出现率很高,同时挂人率也很高,而且一直没见到非常清楚的分析,自己想了想感觉挺有意思,开个帖子希望大家讨论一下。

原题:一组坐标表示人,另一组表示车,车比人多,给每个人匹配最近的车。其中人和车的距离没有tie。

原题还比较简单,最笨的bfs也可以做,坐标数值很大的时候,时间复杂度可能会很高,稍微好一点的是用pq存所有的人车距离,每次poll最小的距离,如果这个人已经匹配到车了继续poll,直到所有人都匹配到车为止。

本题的杀招主要在follow up,我知道的描述清晰准确的有以下版本,有见过其他版本的欢迎补充!!
follow up版本1: 一组坐标表示人,另一组表示车,车比人多,其中人和车的距离有tie(距离两个人最近的车可能是同一辆),给每个人匹配一辆车,要求所有匹配的人车曼哈顿距离加起来最小(全局最优)。
这一问原题的两种方法基本全部gg,因为要求全局最优并且有tie,于是每个人不一定是匹配到距离自己最近的车子。pq方法完全失效,bfs方法无法保证全局最优(距离一个人最近的车可能有多辆,然而单凭bfs无法确定给此人匹配哪辆可以全剧最优)。暴力搜索全部匹配方式,找最小总距离的匹配方式可以确保正确性,但是车和人很多的时候,时间复杂度会很高。目前个人认为这一题面试官的期待做法,应该就是二分图最小带权匹配,KM算法,但是鉴于面试的时候可能很难写出,所以在此希望大家讨论一下有没有其他稍微简单点的办法,因为和正常的二分图匹配不一样,这个已经告诉你那些节点属于哪一边了。

follow up版本2: 一组坐标表示人,另一组表示车,车比人多,其中人和车的距离有tie(距离两个人最近的车可能是同一辆),给每个人匹配一辆车,要求匹配后最大的人车距离最小。
这一问和前面的关系似乎不是很大,不过万能的暴力dfs还是能做,全部匹配方法写出来,找最长距离最小的那个,就是答案,不过和前面一样,没有非常有效的剪枝方法,复杂度很高,所以面试官也不会满意(我同学面试答了这种方法挂掉了)。感觉可以用dp来做,但是没有想出很好的状态表示和转移方程,希望大家讨论!!!!.

其实看待这个人车匹配问题的视角大方向上有两种:静态的(static/batched/offline)以及动态的(dynamic/online)。静态就是说所有信息在时间t=0都给定了并且不变,然后你尽快把最优解算出来就行;而动态情况下人与车的位置在任意时刻t都是可能会发生变动的——这两种视角会导致系统设计上很大的差异。而人车问题从实际角度来看,显然是一个动态系统。

如果只是从静态(适合面试算法题)的角度来看,这一类问题叫做“Assignment Problem“,可以看作一个二分图匹配问题(更本质上是一个0-1整数规划问题),运筹学(Operations Research)领域涉及的比较多。

找了一个关于Assignment Problem的基本介绍:
http://www.math.harvard.edu/archive/20_spring_05/handouts/assignment_overheads.pdf
既然是一个整数规划问题,那么就有Objective Function,楼主提到了两种:
(1) 最小化总(sum)距离
(2) 最小化最大(max)距离

其中(1)是线性的objective,而(2)是非线性的。

对于(1)来说,经典算法是匈牙利算法和最大流(虽然听起来是“高深”的算法,但它们其实是半个多世纪以前提出来的)
对于(2)来说,寻找最优解估计是NP-hard的,所以要么写暴力的玩具解,要么不追求最优解使用近似算法(以及模拟退火/演化算法等一类常用于优化领域的特殊方法)。

此外,之前由于共享交通是一个热点所以也有一些相关的研究,比如说:
On-demand high-capacity ride-sharing via dynamic trip-vehicle assignment
http://people.csail.mit.edu/jalonsom/docs/17-alonsomora-ridesharing-pnas-supplemental.pdf

搜ride-sharing assignment problem、vehicle assignment problem之类的可以有更多的一些文章,不过这类文章研究的模型一般涉及起点到终点的路线所以要复杂不少。

TopCoder上有个tutorial写得还不错,就是看下来需要一点耐心.. 分为三个part

1. 关于最小费用流(minimum cost flow)的基本介绍:
https://www.topcoder.com/communi ... t-one-key-concepts/

2. 具体实现的几种方法:
https://www.topcoder.com/communi ... art-two-algorithms/
3. 应用实例,第一个就是Assignment Problem:
https://www.topcoder.com/communi ... three-applications/

把Figure 1左边的所有节点看作车、右边的节点看作人、边的cost取值为曼哈顿距离就可以,关于人车数量不同的处理方法Part 1的内容里有

followup:

1. 全局最优,距离和最小?可以用加权二分图匹配算?

类似题目:

[LeetCode] 286. Walls and Gates 墙和门

[LeetCode] 317. Shortest Distance from All Buildings 建筑物的最短距离

[Google] 人和自行车匹配的更多相关文章

  1. poj 2584 T-Shirt Gumbo (二分匹配)

    T-Shirt Gumbo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2571   Accepted: 1202 Des ...

  2. 百度谷歌雅虎三大搜索引擎比较和如何配置谷歌访问助手访问Google搜索服务

    引言: 由于近期网上盛传”百度搜索引擎已死“的消息,引发个人对于搜索引擎的思考.百度作为最大的中文搜索引擎,确实有着很大声誉,再加上本地化的优势,正成为国人们的首选,但是作为一名技术开发人员,使用搜索 ...

  3. 如何使用google解决问题

    如何使用google解决问题 redguardtoo著 文章选自2004年<程序员>杂志第8期P56 前面收集了篇如何问问题的文章就是<学会提问>http://blog.pro ...

  4. 你真的会用搜索吗?—— google 搜索技巧

    鄙人用了那么多年 google ,却只会简单的空格. 虽然空格已经很强大了.google 对此做了非常多的优化,原则是让你只用最基础的输入搭配空格就能达到跟下面介绍的方法几乎一样的效果,但是还有知道一 ...

  5. 来更新一篇blog吧

    最近做了一下hackerrank的20/20的比赛.平时都只能过2题,这周顺利地通过了四道题目竟然.当妄图冲击衬衫的时候,发现剩下三个题一点招数都没有,之后就跑去看了一下node.js了... 这次比 ...

  6. 精通Web Analytics 2.0 (13) 第十一章:变身分析忍者的指导原则

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第十一章:变身分析忍者的指导原则 这个激动人心的一章,分析了几乎所有工作的各个方面. 目标很简单:使用成熟的方法来帮助避免淹死的 ...

  7. mxnet深度学习实战学习笔记-9-目标检测

    1.介绍 目标检测是指任意给定一张图像,判断图像中是否存在指定类别的目标,如果存在,则返回目标的位置和类别置信度 如下图检测人和自行车这两个目标,检测结果包括目标的位置.目标的类别和置信度 因为目标检 ...

  8. Java正则速成秘籍(三)之见招拆招篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  9. 从0到1,教你实现基于Ruby的watir-webdriver自动化测试

    一.为什么选择Ruby []完全开源. []多平台:Ruby可以运行在Linux, UNIX, Windows, MS-DOS, BeOS, OS/.. []多线程:线程就是指在一个程序中处理若干控制 ...

随机推荐

  1. easyui-datagrid统计

    <script> //打印指定的table function dayin() { var tableToPrint = document.getElementById("dg&q ...

  2. Thinkphp远程代码执行 payload汇总

    Thinkphp 5.0.22http://192.168.1.1/thinkphp/public/?s=.|think\config/get&name=database.usernameht ...

  3. GitHub上的一些使用技巧

    1.搜索 转:掌握 3 个搜索技巧,在 GitHub 上快速找到实用软件资源 例如 查找位于深圳的C#开发者 2.查看文件历史提交记录 定位至需要查看的文件 修改地址栏github.com 为 git ...

  4. C# 跨域 请求带cookie

    原文:https://blog.csdn.net/z69183787/article/details/78954325 背景: 别个的项目,要开发App接口,要求用前端AJAX的方式访问接口数据. 后 ...

  5. 开始编写Makefile

    1.Makefile 的编写规则一 目标列表:关联性列表 命令列表 目标列表:可以是多个以空格隔开多个目标文件 关联列表页称为先决条件:同样是用个或多个空格分开的目标文件 命令列表:用<tab& ...

  6. luogu 3466 对顶堆

    显然答案是将一段区间全部转化成了其中位数这样的话,需要维护一个数据结构支持查询当前所有数中位数对顶堆 用两个堆将 < 中位数的数放入大根堆将 > 中位数的数放入小根堆这样就会存在删除操作 ...

  7. ArcGIS分支版本化( Branch Versioning )技术介绍

    概述 分支版本化技术是有别于传统的SDE版本化技术,它用于支持WebGIS模式下的多用户长事务编辑. 优势功能 使用分支版本化技术将获得以下功能 1. 支持长事务的编辑. 2. 支持Undo和Redo ...

  8. github上项目的目录结构说明

    build 构建脚本 dist 编译出来的发布版 docs 文档 examples 示例文件 src 源码 test 测试脚本 .babelrc Babel 交叉编译的配置 .eslintrc ESL ...

  9. 深度Linux /etc/profile 环境变量生效问题

    /etc/profile 环境变量生效问题 设置了环境变量后 ,使用source /etc/profile生效后,每次关闭终端后,都需要重新输入source /etc/profile命令使环境变量生效 ...

  10. Complete the Projects

    F1. Complete the Projects (easy version) F2. Complete the Projects (hard version) 参考:Complete the Pr ...