[英]Optimizing an algorithm in Python
問題:假設我們有一組 n 個頂點 A = {0, 1,..., n-1} 並且給定了一些頂點在 A 中的三角形集合 B。例如,我們可以有 n = 5 和 B = {[1, 2, 3], [2, 3, 4], [1, 2, 4]}(但不是 [1, 2, 2],因為三角形需要是非退化的)。 從那里您可以通過以下規則將它們粘合在一起來生成新的三角形:取三個三角形,使得每兩個三角形都有一個公共邊,並且所有三個三角形都有一個公共頂點(見圖)。 例如,上面的三個三角形將被粘在一起以創建一個三角形 [1, 3, 4]。 我的目標是編寫一個算法,然后繼續創建新的三角形直到它可以,然后檢查它是否可以生成所有 n * (n - 1) * (n - 2) / 6 個可能的非退化三角形。
這是我在 python 中的代碼:
import random
# lists all the pairs of distinct integers in [0, n - 1]
def connections(n):
result = []
for i in range(n):
for j in range(i+1, n):
result.append([i, j])
return result
# makes a list of all possible triangles with vertices in [0, n - 1]
def all_faces(n):
result = []
for i in connections(n):
for j in range(i[1] + 1, n):
result.append(i + [j])
return result
def my_algorithm(n, faces):
generalized_faces = faces
new_faces = []
number_new_faces = len(generalized_faces)
i = 0
# generate new triangles from the existing ones in generalized_faces
# and then add them in new_faces. Repeat the loop while new_faces is nonempty.
while len(new_faces) > 0 or i == 0:
generalized_faces.extend(new_faces)
length = len(generalized_faces)
if i > 0:
number_new_faces = len(new_faces)
new_faces = []
if length == n * (n - 1) * (n - 2) / 6:
return True
for i in range(length - number_new_faces, length):
[a, b, c] = generalized_faces[i]
for j in range(n):
if j not in [a, b, c]:
triangle1 = [a, b, j]
triangle1.sort()
triangle2 = [b, c, j]
triangle2.sort()
triangle3 = [a, c, j]
triangle3.sort()
if triangle1 in new_faces + generalized_faces and triangle2 in new_faces + generalized_faces:
final_triangle = [a, c, j]
final_triangle.sort()
if final_triangle not in new_faces + generalized_faces:
new_faces.append(final_triangle)
if triangle1 in new_faces + generalized_faces and triangle3 in new_faces + generalized_faces:
final_triangle = [b, c, j]
final_triangle.sort()
if final_triangle not in new_faces + generalized_faces:
new_faces.append(final_triangle)
if triangle2 in new_faces + generalized_faces and triangle3 in new_faces + generalized_faces:
final_triangle = [a, b, j]
final_triangle.sort()
if final_triangle not in new_faces + generalized_faces:
new_faces.append(final_triangle)
i += 1
return len(generalized_faces) == n * (n - 1) * (n - 2) / 6
# returns some subset of all_faces(n)
def choose_faces(n, p):
return [x for x in all_faces(n) if random.random() < p]
# tests the probability of success in m trials depending on probability p
def test(n, m, p):
result = 0.0
for _ in range(m):
faces = choose_faces(n, p)
if my_algorithm(n, faces):
result += 1.0
return result/(float(m))
我遇到了兩個問題:
我的代碼非常慢,即使只有 n = 30。
一些輸出看起來可疑,但我找不到錯誤。
我的問題是:是否有可能使該算法快速運行,例如 n = 1000,其中 B 是 n 個頂點上所有可能的非退化三角形的相當大的子集? 如果是這樣,可能的實施方式是什么?
我來上鈎……
我不確定你是否需要三角形粘合規則,除非這是強制性的。
為什么這還不夠:
from itertools import combinations
all_triangles = combinations(A, 3)
這將產生一個生成器,該生成器將生成所有 3 頂點組合而不會重復,也不會退化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.