#python
#python
Вопрос:
Я написал следующую программу на Python:
Эта программа генерирует 2D-список размером 30×30 и случайным образом размещает 10 меток вокруг сетки. Я хочу модифицировать эту программу, чтобы она непрерывно генерировала это 30×30 2D при размещении меток и останавливалась только тогда, когда каждая метка находится на заданном расстоянии друг от друга (например, минимум на расстоянии 5 метров). Я знаю, что для этого мне пришлось бы использовать теорему Пифагора, но не уверен, как реализовать ее в моем коде.
import random
listSize = 30
marks = 10
grid = []
for i in range(listSize):
grid.append([0] * listSize)
for i in range(marks):
x = random.randint(0, listSize - 1)
y = random.randint(0, listSize - 1)
grid[x][y] = 1
for row in grid:
print(row)
Комментарии:
1. Ваш вопрос мне непонятен. Что вы подразумеваете под
stop only when each mark is a set amount of spaces apart
. Установить количество пробелов отдельно от предыдущей отметки?2. Никакие 2 метки не могут быть ближе 5 метров друг к другу для всех 10 меток.
3. Вместо того, чтобы постоянно создавать новые сетки, почему бы просто не разместить метки в соответствии с ограничениями?
4. Поскольку размещаемые метки генерируются случайным образом (посмотрите на мой код)
5. Таким образом, в этом случае расстояние между вашими метками должно быть больше, чем 5.Am я прав?
Ответ №1:
Вместо того, чтобы хранить метки в сетке, вы должны создать список дополнений, в котором хранятся позиции x, y каждой метки, а затем перебирать их, чтобы проверить, удовлетворяет ли каждая пара условию. Итак, что-то вроде этого:
import math
points = [(0,0), (5,10), (100,200)]
for n, point_n in enumerate(points):
for point_m in points[n 1:]:
if math.dist(point_n, point_m) < 5:
print('distance less than 5!')
Примечание math.dist
доступно только в Python3.8 и выше, вам придется самостоятельно кодировать функцию расстояния в более низких версиях.
Ответ №2:
Вот несколько наивный подход «попадание или промах»:
from math import sqrt
from random import randint
from itertools import combinations
def dist(p,q):
return sqrt((p[0]-q[0])**2 (p[1]-q[1])**2)
def rand_points(n,k):
"""picks n random points with coordinates in range(k)"""
#assumes that this is feasible!
choices = set()
for _ in range(n):
while True:
p = (randint(0,k-1),randint(0,k-1))
if p not in choices:
choices.add(p)
break
return list(choices)
def check_points(points,min_dist):
"""checks if each point is at least min_dist away from other points"""
return all(dist(p,q) >= min_dist for p,q in combinations(points,2))
def find_points(grid_size,num_points,min_dist,max_trials = 1000):
for trial in range(max_trials):
points = rand_points(num_points,grid_size)
if check_points(points,min_dist):
return points
Например:
>>> find_points(30,10,5)
[(26, 9), (6, 0), (29, 23), (17, 13), (12, 19), (2, 22), (2, 28), (3, 9), (1, 16), (18, 5)]
Конечно, легко загрузить такой список точек в сетку:
def grid_from_points(grid_size,points):
grid = [[0]*grid_size for _ in range(grid_size)]
for p,q in points:
grid[p][q] = 1
return grid
points = rand_points(num_points,grid_size)
if check_points(points,min_dist):
return points