मेरे पास एक वस्तु है जो इस तरह दिखने वाले अजगर में एक आयत का प्रतिनिधित्व करती है:
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)
लेकिन मुझे अपवाद मिलते हैं क्योंकि यह उन मानों को हटा देता है जो मौजूद नहीं हैं और मुझे सही सूची नहीं मिलती है।
मेरे एल्गोरिदम में क्या गलत है?
संपादित करें: एल्गोरिदम को उनमें से केवल एक को हटाना चाहिए। उदाहरण के लिए, ए और बी करीब हैं, इसलिए हमें ए (या बी) को हटाना चाहिए, लेकिन दोनों को नहीं
2 जवाब
आपको उस सूची से आइटम नहीं हटाना चाहिए, जिस पर आप पुनरावृति कर रहे हैं। इसके बजाय एक नई सूची बनाएं जिसमें ऐसे आइटम हों जिन्हें नहीं हटाया जाना चाहिए:
new_cords = [ c_out for c_out in new_cords for c_in in new_cords if not (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) ]
(कृपया अपनी स्थिति की उपेक्षा पर ध्यान दें)
जो कार्य मैं समझता हूं वह सूची में से कुछ आयतों को हटाना है ताकि शेष आयत बहुत समान न हों।
बचे हुए आयतों की संख्या को अधिकतम करना वास्तव में एक ग्राफ़ सिद्धांत समस्या है।
निम्नलिखित समाधान इष्टतम नहीं है, लेकिन शेष संख्या को यथासंभव बड़ा बना सकता है:
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
यह सुनिश्चित करने के लिए कि कोड मान्य है, मैं 100 आयतों की सूची में 1000 परीक्षण चलाता हूं:
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
if c_out == c_in: continue
शर्त के कारण हटा दिया जाएगा
संबंधित सवाल
नए सवाल
python
पायथन एक बहु-प्रतिमान है, गतिशील रूप से टाइप किया हुआ, बहुउद्देशीय प्रोग्रामिंग भाषा है। यह एक साफ और एक समान वाक्यविन्यास सीखने, समझने और उपयोग करने के लिए त्वरित होने के लिए डिज़ाइन किया गया है। कृपया ध्यान दें कि अजगर 2 आधिकारिक तौर पर 01-01-2020 के समर्थन से बाहर है। फिर भी, संस्करण-विशिष्ट पायथन सवालों के लिए, [अजगर -२.०] या [अजगर -३.x] टैग जोड़ें। पायथन वेरिएंट (जैसे, ज्योथन, PyPy) या लाइब्रेरी (उदा।, पांडस और न्यूमपी) का उपयोग करते समय, कृपया इसे टैग में शामिल करें।