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. 洛谷 P1199 三国游戏 题解

    每日一题 day18 打卡 Analysis 贪心 假如小A先选最大的[5,4],虽然电脑必须选一个破坏, 我们可以理解为5和4都属于小A的,假如后面未被破坏的最大值无论是和5相关还是和4相关,必然还 ...

  2. 笔记-读官方Git教程(1)~认识Git

    小书匠版本管理 教程内容基本来自git官方教程,认真都了系列的文章,然后对一些重点的记录下来,做了简单的归纳并写上自己的思考. 目录: 1.Git介绍 2.Git版本控制原理 3.Git特点 4.Gi ...

  3. 29、Java虚拟机垃圾回收调优

    一.背景 如果在持久化RDD的时候,持久化了大量的数据,那么Java虚拟机的垃圾回收就可能成为一个性能瓶颈.因为Java虚拟机会定期进行垃圾回收,此时就会追踪所有的java对象, 并且在垃圾回收时,找 ...

  4. 洛谷P3124被困在haybales

    题目 按理来说是可以二分的,但是发现其实直接暴力然后注意细节就可以了. 先找到牛所在的起点,然后分别向右找和向左找. 第一次查找从\(r\)点冲到\(l\)点时,突破不了\(l\),从\(l\)点冲到 ...

  5. git revert 让提交不再害怕

    git revert 让提交不再害怕 使用了好多命令, 但对于 git revert 一直不敢怎么使用, 为什么呢? 因为 git merge 的存在. 每次 对于 git merge 的分支, 执行 ...

  6. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  7. 无法将“Scaffold-DbContext”项识别为 cmdlet、函数、脚本文件或可运行程序的名称...

    原文链接:https://my.oschina.net/taadis/blog/889560 为什么80%的码农都做不了架构师?>>>     PM> Scaffold-DbC ...

  8. 第10组 Alpha冲刺(1/6)

    链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 史恩泽(组长) 过去两天完成了哪些任务 描述 了解了反馈机制的实现原理 确定好算法的框架 对接口的规范化进行学习 展示Gi ...

  9. Unity3d 错误提示 GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced

    程序出現這個問題的話,程序編譯時正確,運行時報錯,而且沒有報出是哪個代碼文件出處. 這個問題一般首先去檢查Level內有用到OnGUI,Debug結果發現某代碼文件在調試代碼時複製多了一行GUILay ...

  10. MiniUI treeGrid 动态加载数据与静态加载数据的区别

    说明:treegrid静态数据加载时数据结构是一棵树包含children节点集合,而采用动态加载数据时数据是List结构的具体项. 静态加载数据 test1.html <!DOCTYPE htm ...