python удалить прямоугольники из списка в l oop на расстоянии - PullRequest
1 голос
/ 02 марта 2020

У меня есть объект, представляющий прямоугольник в python, который выглядит следующим образом:

class cords:
    x_start = -1
    x_end = -1
    y_start = -1
    y_end = -1

    def __init__(self, x_start, x_end, y_start, y_end):
        self.x_start = x_start
        self.x_end = x_end
        self.y_start = y_start
        self.y_end = y_end

Теперь у меня есть список cords с именем new_cords со значениями, подобными этому:

x_start: 508, x_end: 530, y_start: 843, y_end: 869
x_start: 508, x_end: 530, y_start: 843, y_end: 870
x_start: 401, x_end: 451, y_start: 582, y_end: 620
x_start: 467, x_end: 513, y_start: 583, y_end: 621
x_start: 466, x_end: 512, y_start: 634, y_end: 672
x_start: 533, x_end: 585, y_start: 534, y_end: 561
x_start: 528, x_end: 576, y_start: 583, y_end: 622

Я хочу удалить из new_cords прямоугольников, которые находятся на расстоянии 3 друг от друга, чтобы уменьшить сходные прямоугольники.

Я написал это:

for c_out in new_cords:
    for c_in in new_cords:
        if abs(c_out.x_start - c_in.x_start) < 3 or abs(c_out.x_end - c_in.x_end) < 3 or abs(c_out.y_start - c_in.y_start) < 3 or abs(c_out.y_end - c_in.y_end) < 3:
            new_cords.remove(c_out)

Но я получаю исключения, потому что он удаляет несуществующие значения, и я не получаю правильный список.

Что не так с моим алгоритмом?

РЕДАКТИРОВАТЬ: алгоритм должен удалять только один из них. Например, A и B близки, поэтому мы должны удалить A (или B), но не оба из них

1 Ответ

2 голосов
/ 02 марта 2020

Задача, которую я понимаю, состоит в том, чтобы удалить некоторые из прямоугольников в списке, чтобы оставшиеся прямоугольники не были слишком похожими. 1004 *.

Следующее решение не является оптимальным, но может сделать оставшееся число максимально большим:

def remove_similar(cord_list):
    is_similar = (
        lambda n1, n2: abs(n1.x_start - n2.x_start) < 3
        or abs(n1.x_end - n2.x_end) < 3
        or abs(n1.y_start - n2.y_start) < 3
        or abs(n1.y_end - n2.y_end) < 3
    )

    res = []
    while cord_list:
        c_in = cord_list.pop()
        cord_list = [n for n in cord_list if not is_similar(n, c_in)]
        res.append(c_in)
    return res

Чтобы убедиться в правильности кода, я запускаю 1000 тестов в списке из 100 прямоугольников:

import numpy as np


def build_test(size):
    return [cords(*np.random.randint(0, 1000, 4).tolist()) for _ in range(size)]


def check(cord_list):
    assert not any(
        [n1 != n2 and too_close(n1, n2) for n1 in cord_list for n2 in cord_list]
    )
    return len(cord_list)


res_size_mean = 0
for _ in range(1000):
    new_cords = build_test(100)
    res = remove_similar(new_cords)
    res_size_mean += check(res) / 1000

print(res_size_mean)
# 53.591999999999736
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...