亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在python中獲取起始坐標和結束坐標之間的“n”個隨機點?

如何在python中獲取起始坐標和結束坐標之間的“n”個隨機點?

千萬里不及你 2023-08-08 15:38:00
我有一個起始坐標(x1,y1)和一個結束坐標(x2,y2)。我想在開始和結束坐標之間生成“n”個隨機點,沒有任何重復。如何用 python 做到這一點?我知道一個簡單的方法是生成“n”個 x 值和“n”個 y 值。所以我們得到 n*n 對,我在其中選擇“n”,沒有重復。這樣我可能無法獲得隨機點的均勻分布。還有其他方法可以做到這一點嗎?編輯:我需要由起始坐標和結束坐標作為對角形成的矩形中的浮點坐標。
查看完整描述

1 回答

?
回首憶惘然

TA貢獻1847條經驗 獲得超11個贊

長話短說:


from random import uniform



def gen_coords(x1, y1, x2, y2, n):

    result = set()

    # loops for each addition, avoiding duplicates

    while len(result) < n:

        result.add((uniform(x1, x2), uniform(y1, y2)))

    return result

可以說,實際上:


from random import uniform



def gen_coords(x1, y1, x2, y2, n):

    return [(uniform(x1, x2), uniform(y1, y2)) for _ in range(n)]

考慮到碰撞的可能性很小。

假設“起始坐標和終止坐標之間”是指在笛卡爾坐標系(即平面、2D)中這兩個角之間的矩形截面中。

并假設充分實現“均勻分布”,忽略浮點值的非均勻分布。(即,在任何相等長度的間隔上,浮點值的數量不是完全相同,也不是連續體中浮點值之間的恒定距離)

基本上有三種方法可以確保隨機生成的點不重復:

  1. 從可能值的集合中選擇它們,刪除每個選擇以避免再次選擇;

  2. 在允許的空間內生成值,將每個選擇與之前的選擇進行檢查,以避免添加重復項(并重新選擇值,直到生成新值);

  3. 生成值并添加到集合中,直到達到所需的集合大小,生成后刪除重復項(如果有)并重復該過程直至完成。

如果從中選取值的空間大小與目標集大小相似,第一個選項可能是一個不錯的選擇。然而,當在某些空間中選取具有隨機浮點坐標的點時,這種情況不太可能發生。

第二種選擇是最直接的,但如果目標集大小很大,則計算成本可能會很高,因為每個新選擇都會導致更多比較。

第三種選擇涉及更多一些,但在候選目標集完成之前避免進行比較,如果沖突的可能性很小,這當然是最佳選擇。

作為第二個選擇的變體,您可以選擇一個目標數據結構,完全避免添加重復項,依靠語言/解釋器比用該語言編寫的任何算法更有效地執行檢查。

在Python中,這意味著使用 aset而不是 a list,這是實現結果的最快方法,并且可能是您在第三個選項中檢查重復項的方法 - 所以您也可以立即使用它并使用第二個選項的變體。

請注意,如果您嘗試在選擇函數的范圍內創建大于選擇函數域的集合,則第二個和第三個選項都有一個重大缺陷。但對于給定的問題,除了非常大的“n”之外,這是不可能的。

解決方案(將第二個選項與第三個選項進行比較):

from random import uniform

from timeit import timeit



def pick_coords_restricted(x1, y1, x2, y2, n):

    result = set()

    # loops for each addition, avoiding duplicates

    while len(result) < n:

        result.add((uniform(x1, x2), uniform(y1, y2)))

    return result



def pick_coords_checked(x1, y1, x2, y2, n):

    result = []

    # loops once for attempt, checking after each iteration

    while len(set(result)) < n:

        if len(result) > 0:

            result = list(set(result))

            result += [(uniform(x1, x2), uniform(y1, y2)) for _ in range(n - len(result))]

        else:

            result = [(uniform(x1, x2), uniform(y1, y2)) for _ in range(n)]

    return result



print(timeit(lambda: pick_coords_restricted(0, 0, 1, 1, 1000), number=10000))

print(timeit(lambda: pick_coords_checked(0, 0, 1, 1, 1000), number=10000))

結果(在我的硬件上):


4.3799341

3.9363368000000003

我得到了一致的、但稍微更好的函數結果pick_coords_checked——我贊成第一個實現的清晰度。


查看完整回答
反對 回復 2023-08-08
  • 1 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號