哪個省能稱為「九省通衢」?

2021-09-12 15:36:00 字數 3254 閱讀 5184

撲上有位網友發起了乙個很有意思的話題,《湖北是唯一乙個到各省區最多只要跨過兩個省的省份嗎?》這在地理裡是個多階空間鄰接矩陣的問題。我覺得這個問題可以作為學習r語言中spdep包的入門吧。順手解決了一下。中國地圖的向量資料是我從高德上抓取的。先畫乙個中國地圖

用的包主要是以上這麼幾個。畫圖的話也可以用ggplot2

所謂空間鄰接矩陣,也就是記錄地理實體之間空間鄰接關係的矩陣。比如江蘇與安徽有著共同的省界,那就記錄為1,這種直接相鄰的1階空間相鄰。而江蘇與湖北之間隔了乙個安徽,這就是2階空間相鄰了。(廣義上說,這一類矩陣應該叫空間距離矩陣。鄰接關係可以看做是拓撲學意義上的距離吧(好像是)。而構建空間距離矩陣是開展空降計量經濟學等空間分析的基礎。)下面回到問題本身。我們如果用空間鄰接關係的語言來重新描述一下這個問題,那就是湖北是中國唯一的其1+2+3階空間鄰接矩陣就包含了中國所有省份的省份嗎?果然就不說人話了,哈哈。

下面,我們首先構建所有省份的1階空間鄰接矩陣。

china_nb=poly2nb(as(china_province,'spatial'),queen=f,

row.names = china_province$name)

poly2nb我感覺是spdep這個包中最基礎的函式了,我比較習慣使用sf物件,而spdep這些包都有些年頭了,其空間物件基本都是圍繞sp包來構建的,所以首先要進行物件的轉換。queen這個引數是用來設定判別兩個多邊形是否空間相鄰的方式。一般來說有三種,都是按照西洋棋上棋子的走法來命名的。分別有bishop(共頂點),rook(共邊),queen(共邊或共點)。

poly2nb這個函式的結果是乙個nb型別的物件,這是這個包專用的乙個物件。實質就是把空間鄰接矩陣按行降解了,不以0\1來記錄空間鄰接關係,而是把與行多邊形鄰接的多邊形的編號記錄了下來。長這個樣子

這樣的形式相對矩陣形式看起來更直觀一些,但在解決我們這個問題時並不好用,因為我需要進一步把1-2階空間鄰接矩陣的資訊儲存在乙個矩陣中,而這個形式顯然拓展性是不好的。在r中針對不規則list物件的操作還是有些麻煩的,後面進行是否包含所有省份的驗證時也不好操作,所以我們還是要把它轉換成矩陣形式。在此之前,有個問題是需要注意的。那就是海南和台灣兩個省與大陸是通過海洋相連的,反映到空間鄰接矩陣中就是這兩個省是沒有鄰居的。那麼也就不會有更高階的鄰接關係。那麼如果不做人為限定,原題目就是無法解決的。我這裡人為限定海南和台灣分別與其空間距離上最為接近的廣東和福建相鄰。一定要注意對稱性,有聯絡的省份之間都要賦值

china_nb[[17]]=(1 %>% as.integer) 

china_nb[[26]]=(15 %>% as.integer)

china_nb[[1]]=c(17,china_nb[[1]]) %>% as.integer

china_nb[[15]]=c(26,china_nb[[15]]) %>% as.integer

這裡的數字全是我原資料中各省份排列的順序。注意的是nb物件中的值只能是整數型別,而r語言預設是numeric,這裡還要先進行型別轉換。

這樣全中國所有的省份都有1階鄰居了,我們可以用乙個函式一步得到多個高階鄰接矩陣。

nb_lag=nblag(china_nb,maxlag = 3)
為什麼說poly2nb這個函式基礎呢?因為spdep包中很多函式接收的物件就是nb型別的。maxlag這個引數用來限定高階鄰接矩陣的階數,設定為2就生成連個list物件。兩個list物件都是nb型別。

我們要分別展開為矩陣。

nb_m1=nb2mat(nb_lag[[1]],style='b')

nb_m2=nb2mat(nb_lag[[2]],style='b')

nb_m3=nb2mat(nb_lag[[3]],style='b')

#style引數用來限定展開矩陣的型別,詳

情參見幫助文件

展開後的矩陣是這樣的。按行相加(nb_m1 %>% rowsums),就可以知道每個省有多少1階鄰居了。

一階時這樣。

陝西作為中國的大地原點所在的省份擁有8個鄰居,而作為祖國邊境省份的內蒙古也同樣擁有8個鄰居恐怕也是大家沒有想到的吧。超長的東西跨度使得內蒙古成為包括了祖國東中西部的省份。湖北的優勢則並不突出。

把1階和2階矩陣相加,就可以得到2階內的情況了。我們直接來看看3階的情況(2階相加的結果是沒有能聯通全國的省份。)

九省聯考 2018

發現狀態數很少,直接搜即可。不難發現這個偏序關係形成了一棵樹。本來以為直接貪心即可,即把 a 排序,然後 dfs bfs 一遍直接安排權值,類似於這樣 void dfs1 int u void dfs2 int u 不出我所料,這份簡單的 沒有過,被這組資料叉掉了 2 2.0 1 1 1 2發現這樣...

九省聯考2018遊記

day0 上午到學校,去tututu寢室,入坑荒野求生,真tm好玩 雖然只打了一把 下午坐高鐵去sh,發現sh非正式選手只有hez的。day1 開局看t1,沒意識到狀態數是個組合數,於是寫了個程式算狀態數,還寫掛了 include int n 10,m 10,f 15 15 i,j,k int ma...

九省聯考 秘密襲擊

剛開始看起來像樹形dp,卻感覺無從下手 其實正解是fft 每個值的排名往上回溯時都會改變,後效性滿滿的。根本不是一次樹形dp能解決的。那麼,每個值對其他值的排名有什麼影響呢?我們發現只有比val i 大的值才會影響它的排名。不妨每次取乙個點出來,令值大於改點的值變為1,小於改點的值變為0,問題就轉化...