[Google] 人和自行車匹配


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 建築物的最短距離 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM