Вы можете использовать хеширование с большим эффектом:
hash each point (keeping track of which list it is in)
for each pair of points (a,b) and (c,d):
if (a,d) exists in another list, and (c,b) exists in yet another list:
yield rectangle(...)
Когда я говорю exists
, я имею в виду сделать что-то вроде:
hashesToPoints = {}
for p in points:
hashesToPoints.setdefault(hash(p),set()).add(p)
for p1 in points:
for p2 in points:
p3,p4 = mixCoordinates(p1,p2)
if p3 in hashesToPoints[hash(p3)] and {{p3 doesn't share a bin with p1,p2}}:
if p4 in hashesToPoints[hash(p4)] and {{p4 doesn't share a bin with p1,p2,p3}}:
yield Rectangle(p1,p2)
ЭтоO(#bins^2 * items_per_bin^2)
~ 30000, что очень быстро в вашем случае с 18 массивами и 10 items_per_bin - намного лучше, чем внешний подход к продукту, который ... намного хуже с O(items_per_bin^#bins)
~ 3 трлн.=)
младший sidenote:
Вы можете уменьшить как основание, так и показатель степени в своих вычислениях, сделав несколько проходов "сокращения".например,
remove each point that is not corectilinear with another point in the X or Y direction
then maybe remove each point that is not corectilinear with 2 other points, in both X and Y direction
Вы можете сделать это, отсортировав по X-координате, повторите для Y-координаты, по O(P log(P))
времени по количеству точек.Вы можете сделать это одновременно с хешированием.Если плохой парень организует ваш вклад, он может заставить эту оптимизацию вообще не работать.Но в зависимости от вашего дистрибутива вы можете увидеть значительное ускорение.