日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于快速GeoHash,如何实现海量商品与商圈的高效匹配?

發布時間:2024/9/3 编程问答 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于快速GeoHash,如何实现海量商品与商圈的高效匹配? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

阿里妹導讀:閑魚是一款閑置物品的交易平臺APP。通過這個平臺,全國各地“無處安放”的物品能夠輕松實現流動。這種分享經濟業務形態被越來越多的人所接受,也進一步實現了低碳生活的目標。

今天,閑魚團隊就商品與商圈的匹配算法為我們展開詳細解讀。

摘要

閑魚app根據交通條件、商場分布情況、住宅區分布情況綜合考慮,將城市劃分為一個個商圈。杭州部分區域商圈劃分如下圖所示。

閑魚的商品是由用戶發布的GPS隨機分布在地圖上的點數據。當用戶處于某個商圈范圍內時,app會向用戶推薦GPS位于此商圈中的商品。要實現精準推薦服務,就需要計算出哪些商品是歸屬于你所處的商圈。

在數據庫中,商圈是由多個點圍成的面數據,這些面數據形狀、大小各異,且互不重疊。商品是以GPS標記的點數據,如何能夠快速高效地確定海量商品與商圈的歸屬關系呢?傳統而直接的方法是,利用幾何學的空間關系計算公式對海量數據實施直接的“點—面”關系計算,來確定每一個商品是否位于每一個商圈內部。

閑魚目前有10億商品數據,且每天還在快速增加。全國所有城市的商圈數量總和大約為1萬,每個商圈的大小不一,邊數從10到80不等。如果直接使用幾何學點面關系運算,需要的計算量級約為2億億次基本運算。按照這個思路,我們嘗試過使用阿里巴巴集團內部的離線計算集群來執行計算,結果集群在運行了超過2天之后也未能給出結果。

經過算法改進,我們采用了一種基于GeoHash精確匹配,結合GeoHash非精確匹配并配合小范圍幾何學關系運算精匹配的算法,大大降低了計算量,高效地實現了離線環境下海量點-面數據的包含關系計算。同樣是對10億條商品和1萬條商圈數據做匹配,可以在1天內得到結果。

點數據GeoHash原理與算法

GeoHash是一種對地理坐標進行編碼的方法,它將二維坐標映射為一個字符串。每個字符串代表一個特定的矩形,在該矩形范圍內的所有坐標都共用這個字符串。字符串越長精度越高,對應的矩形范圍越小。

對一個地理坐標編碼時,按照初始區間范圍緯度[-90,90]和經度[-180,180],計算目標經度和緯度分別落在左區間還是右區間。落在左區間則取0,右區間則取1。然后,對上一步得到的區間繼續按照此方法對半查找,得到下一位二進制編碼。當編碼長度達到業務的進度需求后,根據“偶數位放經度,奇數位放緯度”的規則,將得到的二進制編碼穿插組合,得到一個新的二進制串。最后,根據base32的對照表,將二進制串翻譯成字符串,即得到地理坐標對應的目標GeoHash字符串。

以坐標“30.280245, 120.027162”為例,計算其GeoHash字符串。首先對緯度做二進制編碼:

  • 將[-90,90]平分為2部分,“30.280245”落在右區間(0,90],則第一位取1。
  • 將(0,90]平分為2分,“30.280245”落在左區間(0,45],則第二位取0。
  • 不斷重復以上步驟,得到的目標區間會越來越小,區間的兩個端點也越來越逼近“30.280245”。
  • 下圖的流程詳細地描述了前幾次迭代的過程:

    按照上面的流程,繼續往下迭代,直到編碼位數達到我們業務對精度的需求為止。完整的15位二進制編碼迭代表格如下:

    得到的緯度二進制編碼為10101 01100 01000。

    按照同樣的流程,對經度做二進制編碼,具體迭代詳情如下:

    得到的經度二進制編碼為11010 10101 01101。

    按照“偶數位放經度,奇數位放緯度”的規則,將經緯度的二進制編碼穿插,得到完成的二進制編碼為:11100 11001 10011 10010 00111 00010。由于后續要使用的是base32編碼,每5個二進制數對應一個32進制數,所以這里將每5個二進制位轉換成十進制位,得到28,25,19,18,7,2。 對照base32編碼表,得到對應的編碼為:wtmk72。

    可以在geohash.org/網站對上述結果進行驗證,驗證結果如下:

    驗證結果的前幾位與我們的計算結果一致。如果我們利用二分法獲取二進制編碼時迭代更多次,就會得到驗證網站中這樣的位數更多的更精確結果。

    GeoHash字符串的長度與精度的對應關系如下:

    面數據GeoHash編碼實現

    上一節介紹的標準GeoHash算法只能用來計算二維點坐標對應的GeoHash編碼,我們的場景中還需要計算面數據(即GIS中的POLYGON多邊形對象)對應的GeoHash編碼,需要擴展算法來實現。

    算法思路是,先找到目標Polygon的最小外接矩形MBR,計算此MBR西南角坐標對應的GeoHash編碼。然后用GeoHash編碼的逆算法,反解出此編碼對應的矩形GeoHash塊。以此GeoHash塊為起點,循環往東、往北找相鄰的同等大小的GeoHash塊,直到找到的GeoHash塊完全超出MBR的范圍才停止。如此找到的多個GeoHash塊,邊緣上的部分可能與目標Polygon完全不相交,這部分塊需要通過計算剔除掉,如此一來可以減少后續不必要的計算量。

    上面的例子中最終得到的結果高清大圖如下,其中藍色的GeoHash塊是與原始Polygon部分相交的,橘黃色的GeoHash塊是完全被包含在原始Polygon內部的。

    上述算法總結成流程圖如下:

    求臨近GeoHash塊的快速算法

    上一節對面數據進行GeoHash編碼的流程圖中標記為綠色和橘黃色的兩步,分別是要尋找相鄰的東邊或北邊的GeoHash字符串。

    傳統的做法是,根據當前GeoHash塊的反解信息,求出相鄰塊內部的一點,在對這個點做GeoHash編碼,即為相鄰塊的GeoHash編碼。如下圖,我們要計算"wtmk72"周圍的8個相鄰塊的編碼,就要先利用GeoHash逆算法將"wtmk72"反解出4個頂點的坐標N1、N2、N3、N4,然后由這4個坐標計算出右側鄰接塊內部的任意一點坐標N5,再對N5做GeoHash編碼,得到的“wtmk78”就是我們要求的右邊鄰接塊的編碼。按照同樣的方法,求可以求出"wtmk72"周圍總共8個鄰接塊的編碼。

    這種方法需要先解碼一次再編碼一次,比較耗時,尤其是在指定的GeoHash字符串長度較長需要循環較多次的情況下。

    通過觀察GeoHash編碼表的規律,結合GeoHash編碼使用的Z階曲線的特性,驗證了一種通過查表來快速求相鄰GeoHash字符串的方法。

    還是以“wtmk72”這個GeoHash字符串為例,對應的10進制數是“28,25,19,18,7,2”,轉換成二進制就是11100 11001 10011 10010 00111 00010。其中,w對應11100,這5個二進制位分別代表“經 緯 經 緯 經”;t對應11001,這5個二進制位分別代表“緯 經 緯 經 緯”。由此推廣開來可知,GeoHash中的奇數位字符(本例中的'w'、'm'、'7')代表的二進制位分別對應“經 緯 經 緯 經”,偶數位字符(本例中的't'、'k'、'2')代表的二進制位分別對應“緯 經 緯 經 緯”。

    'w'的二進制11100,轉換成方位含義就是“右 上 右 下 左”。't'的二進制11001,轉換成方位含義就是“上 右 下 左 上”。

    根據這個字符與方位的轉換關系,我們可以知道,奇數位上的字符與位置對照表如下:

    偶數位上的字符與位置對照表如下:

    這里可以看到一個很有意思的現象,奇數位的對照表和偶數位對照表存在一種轉置和翻轉的關系。

    有了以上兩份字符與位置對照表,就可以快速得出每個字符周圍的8個字符分別是什么。而要計算一個給定GeoHash字符串周圍8個GeoHash值,如果字符串最后一位字符在該方向上未超出邊界,則前面幾位保持不變,最后一位取此方向上的相鄰字符即可;如果最后一位在此方向上超出了對照表邊界,則先求倒數第二個字符在此方向上的相鄰字符,再求最后一個字符在此方向上相鄰字符(對照表環狀相鄰字符);如果倒數第二位在此方向上的相鄰字符也超出了對照表邊界,則先求倒數第三位在此方向上的相鄰字符。以此類推。

    以上面的“wtmk72”舉例,要求這個GeoHash字符串的8個相鄰字符串,實際就是求尾部字符‘2’的相鄰字符。‘2’適用偶數對照表,它的8個相鄰字符分別是‘1’、‘3’、‘9’、‘0’、‘8’、‘p’、‘r’、‘x’,其中‘p’、‘r’、‘x’已經超出了對照表的下邊界,是將偶數位對照表上下相接組成環狀得到的相鄰關系。所以,對于這3個超出邊界的“下方”相鄰字符,需要求倒數第二位的下方相鄰字符,即‘7’的下方相鄰字符。‘7’是奇數位,適用奇數位對照表,‘7’在對照表中的“下方”相鄰字符是‘5’,所以“wtmk72”的8個相鄰GeoHash字符串分別是“wtmk71”、“wtmk73”、“wtmk79”、“wtmk70”、“wtmk78”、“wtmk5p”、“wtmk5r”、“wtmk5x”。利用此相鄰字符串快速算法,可以大大提高上一節流程圖中面數據GeoHash編碼算法的效率。

    高效建立海量點數據與面數據的關系

    建立海量點數據與面數據的關系的思路是,先將需要匹配的商品GPS數據(點數據)、商圈AOI數據(面數據)按照前面所述的算法,分別計算同等長度的GeoHash編碼。每個點數據都對應唯一一個GeoHash字符串;每個面數據都對應一個或多個GeoHash編碼,這些編碼要么是“完全包含字符串”,要么是“部分包含字符串”。

    a)將每個商品的GeoHash字符串與商圈的“完全包含字符串”進行join操作。join得到的結果中出現的<商品,商圈>數據就是能夠確定的“某個商品屬于某個商圈”的關系。

    b)對于剩下的還未被確定關系的商品,將這些商品的GeoHash字符串與商圈的“部分包含字符串”進行join操作。join得到的結果中出現的<商品,商圈>數據是有可能存在的“商品屬于某個商圈”的關系,接下來對這批數據中的商品gps和商圈AOI數據進行幾何學關系運算,進而從中篩選出確定的“商品屬于某個商圈”的關系。

    如圖,商品1的點數據GeoHash編碼為"wtmk70j",與面數據的“完全包含字符串wtmk70j”join成功,所以可以直接確定商品1屬于此面數據。

    商品2的點數據GeoHash編碼為“wtmk70r”,與面數據的“部分包含字符串wtmk70r”join成功,所以商品2疑似屬于面數據,具體是否存在包含關系,還需要后續的點面幾何學計算來確定。 商品3的點數據GeoHash編碼與面數據的任何GeoHash塊編碼都匹配不上,所以可以快速確定商品3不屬于此面數據。

    實際應用中,原始的海量商品GPS范圍散布在全國各地,海量商圈數據也散布在全國各個不同的城市。經過a)步驟的操作后,大部分的商品數據已經確定了與商圈的從屬關系。剩下的未能匹配上的商品數據,經過b)步驟的GeoHash匹配后,可以將后續“商品-商圈幾何學計算”的運算量從“1個商品 x 全國所有商圈”笛卡爾積的量級,降低為“1個商品 x 1個(或幾個)商圈”笛卡爾積的量級,減少了絕大部分不必要的幾何學運算,而這部分運算是非常耗時的。

    在閑魚的實際應用中,10億商品和1萬商圈數據,使用本文的快速算法,只需要 10億次GeoHash點編碼 + 1萬次GeoHash面編碼 + 500萬次“點是否在面內部”幾何學運算,粗略換算為基本運算需要的次數約為1800億次,運算量遠小于傳統方法的2億億次基本運算。使用阿里巴巴的離線計算平臺,本文的算法在不到一天的時間內就完成了全部計算工作。

    另外,對于給定的點和多邊形,通過幾何學計算包含關系的算法不止一種,最常用的算法是射線法。簡單來說,就是從這個點出發做一條射線,判斷該射線與多邊形的交點個數是奇數還是偶數。如果是奇數,說明點在多邊形內;否則,點在多邊形外。

    延伸

    面對海量點面數據的空間關系劃分,本文采用是的通過GeoHash來降低計算量的思路,本質上來說是利用了空間索引的思想。事實上,在GIS領域有多種實用的空間索引,常見的如R樹系列(R樹、R+樹、R*樹)、四叉樹、K-D樹、網格索引等,這些索引算法各有特點。本文的思路不僅能用來處理點—面關系的相關問題,還可以用來快速處理點—點關系、面—面關系、點—線關系、線—線關系等問題,比如快速確定大范圍類的海量公交站臺與道路的從屬關系、多條道路或鐵路是否存在交點等問題。

    歡迎大家和閑魚團隊交流討論相關的算法優化,也歡迎各路高手加入阿里巴巴——閑魚團隊,和我們一起用技術改變世界。

    簡歷投遞:guicai.gxy@alibaba-inc.com

    參考資料:

    [1]https://en.wikipedia.org/wiki/Geohash

    [2]https://en.wikipedia.org/wiki/Pointinpolygon

    [3]https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon [4]https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html

    [5]http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves


    每天一篇技術文章,

    看不過癮?

    關注“阿里巴巴機器智能”微信公眾號

    發現更多AI干貨。

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的基于快速GeoHash,如何实现海量商品与商圈的高效匹配?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲高清视频在线播放 | 久久国产精品一区二区 | 国产男女猛烈无遮挡免费观看网站 | 少妇高潮一区二区三区99 | 九九少妇 | 69视频网址 | 欧美八区 | 成人毛片在线精品国产 | 爽天天天天天天天 | av大全在线播放 | 日本在线有码 | 91精品综合久久久久久 | 国产欧美视频一区二区三区 | 综合激情四射 | 亚洲日本色图 | xxx国产| 野外做受又硬又粗又大视频√ | 人人爽人人爽人人片av | gv天堂gv无码男同在线观看 | 国产免费毛卡片 | 18欧美性xxxx极品hd | 日韩图片区 | 99精品无码一区二区 | 国产视频精品自拍 | 日本超碰在线 | www.久久精品视频 | 久久婷婷丁香 | 国产又大又粗又爽的毛片 | 在线观看免费高清在线观看 | 亚洲激情二区 | 精品视频久久久久 | 91二区| 亚洲av人无码激艳猛片服务器 | 欧美视频三区 | 校园春色亚洲激情 | 日本aaa级片 | 青青草日韩| 国产人妻久久精品一区二区三区 | 国产黑丝一区二区 | 91国偷自产一区二区三区观看 | 羞羞成人 | av动漫免费看 | 红桃一区二区三区 | 在线成人毛片 | 国产欧美在线观看不卡 | 亚洲综合第一 | 色婷婷六月 | 国产伦理精品 | 国产精品视频免费在线观看 | 天堂久久精品忘忧草 | 女大学生的家政保姆初体验 | 国产成人啪免费观看软件 | 91蜜桃网站 | 欧美一区二区三区视频在线 | 在线碰| 中文文字幕文字幕高清 | 亚洲精品v天堂中文字幕 | 黄色录像a级片 | 一区二区美女 | 日韩丰满少妇 | 国产成人超碰人人澡人人澡 | 亚洲淫欲 | 色哟哟视频网站 | 香蕉视频啪啪 | 香蕉人人精品 | 依人久久 | 精品人人妻人人澡人人爽牛牛 | 国产中文字幕一区二区 | 一本一道波多野结衣一区二区 | 激情婷婷| 大地资源高清播放在线观看 | 狠狠干五月| 999国产精品视频免费 | 黄页网站视频 | 天天射狠狠干 | www.欧美| 日韩高清精品免费观看 | 日韩欧美在线一区二区 | 久久久黄色网 | 农村少妇久久久久久久 | 男人午夜剧场 | 成人久久精品人妻一区二区三区 | 熟女少妇一区二区 | 婷婷精品进入 | 潘金莲激情呻吟欲求不满视频 | 黄色一级片 | 亚洲天堂第一页 | 国产精品野外户外 | 欧美乱操| 白嫩少妇激情无码 | 射综合网| 女优色图 | 天天天天天天操 | 国产成人av电影 | 国产91丝袜在线18 | 欧美日韩国产一区二区三区在线观看 | 亚洲va韩国va欧美va精品 | 69精品丰满人妻无码视频a片 | 亚洲国产精品成人午夜在线观看 |