सबसे बड़ा उत्तल बहुभुज का क्षेत्रफल ज्ञात कीजिए


28

पूर्णांक निर्देशांक की एक सूची को देखते हुए, सबसे बड़ी उत्तल बहुभुज का क्षेत्रफल ज्ञात करें जिसे आप इस सूची से बना सकते हैं -

  • प्रत्येक शीर्ष सूची में है
  • सूची का कोई भी तत्व बहुभुज के भीतर निहित नहीं है।

उदाहरण:

(0, 0) (8, 0) (0, 1) (3, 1) (7, 1) (1, 2) (5, 2) (9, 2) (2, 3) (5, 3) (7, 3) (3, 4) (5, 5) (11, 5)

कल्पना:

o       o
o  o   o
 o   o   o
  o  o o
   o
     o     o

सबसे बड़ा उत्तल बहुभुज जो आप इससे बना सकते हैं वह यह है:

o     
o  o  
 o   o
  o  o
   o
     o

12 के एक क्षेत्र के साथ।


आप किसी भी उचित प्रारूप में निर्देशांक की सूची ले सकते हैं, और दशमलव बिंदु के बाद 2 अंकों से कम नहीं के साथ सबसे बड़े उत्तल बहुभुज के क्षेत्र को आउटपुट (अपनी पसंद की भाषा के लिए उपयुक्त तरीके से) करना चाहिए।

इसके अतिरिक्त, आपको कुछ प्रकार के एल्गोरिदम को नियोजित करना होगा, न कि केवल सभी बिंदुओं के सबसेट को बल देना चाहिए। इसे लागू करने के लिए, आपके प्रोग्राम को आधुनिक पीसी पर एक मिनट के भीतर 50 कोने की सूची को हल करना होगा।

बाइट्स में सबसे छोटा कोड जीतता है।


क्या आप सबसे खराब स्थिति के लिए एक तेज़ एल्गोरिथम के बारे में जानते हैं?
xnor

3
यदि आप 100 कोने पर एक समय सीमा लागू करना चाहते हैं, तो आपको संभवतः कम से कम एक ऐसा परीक्षण मामला शामिल करना चाहिए (आदर्श रूप से कई, उदाहरण के लिए, जहां सभी 100 कोने समाधान का हिस्सा हैं, एक जहां 99 हैं, और एक जहां केवल 10 हैं) ।
मार्टिन एंडर

@ मार्टिनबटनर अफसोस की बात यह है कि मैं इस परीक्षण के मामले को उत्पन्न नहीं कर सकता क्योंकि मेरे पास स्वयं कार्य कार्यान्वयन नहीं है। समस्या बल्कि मुश्किल है :)
orlp

@xnor एक दो उदाहरण यहां देखे जा सकते हैं
orlp

"दशमलव बिंदु के बाद 2 अंकों से कम नहीं?"
डेविड सी

जवाबों:


12

जावास्क्रिप्ट ईएस 6, 738 बाइट्स

((V,C,L,r,k,n,A,G,F,e,i,j,q)=>p=>{p=p.map((p,i)=>({i:i,x:p[0],y:p[1]}));A=(f,p,a,b,v,i)=>{for(i=p[n],v=V(a,b);i--;)if(f(v,V(a,p[i])))return 1};G=(p,i,a)=>{for(i=p[n]-1,a=C(p[i],p[0]);i--;)a+=C(p[i],p[i+1]);if((a/=2)>r)r=a};F=(p,s,l,f,a,b,v)=>(l=s[n],f=s[0],a=s[l-2],b=s[l-1],e[a.i][b.i]||A((a,b)=>C(a,b)?0:a.x<0==b.x<0&&a.y<0==b.y<0&&L(a)>L(b),p,a,b)?0:(p=(v=V(a,b),p[k](x=>C(v,V(a,x))>=0)),A((a,b)=>C(a,b)>0,p,b,f)?0:(p.map(q=>F(p[k](r=>q!==r),[...s,q])),s[2]&&!p[n]&&!e[b.i][f.i]?G(s):0)));e=p.map(x=>p.map(y=>x===y));for(i=p[n];i--;){for(j=i;j--;){q=p[k]((p,x)=>x-i&&x-j);F(q,[p[i],p[j]]);F(q,[p[j],p[i]]);e[i][j]=e[j][i]=1}}console.log(r)})((a,b)=>({x:b.x-a.x,y:b.y-a.y}),(a,b)=>a.x*b.y-a.y*b.x,v=>v.x*v.x+v.y*v.y,0,'filter','length')

यहाँ एक ES5 या उससे कम संस्करण है जो बिना ब्राउजिंग के अधिकांश ब्राउज़र और नोड में काम करना चाहिए: 827 बाइट्स

eval("(%V,C,L,r,k,n,A,G,F,e,i,j,q){@%p){p=p.map(%p,i){@{i:i,x:p[0],y:p[1]}});A=%f,p,a,b,v,i){for(i=p[n],v=V(a,b);i--;)if(f(v,V(a,p[i])))@1};G=%p,i,a){for(i=p[n]-1,a=C(p[i],p[0]);i--;)a+=C(p[i],p[i+1]);if((a/=2)>r)r=a};F=%p,s,l,f,a,b,v){@(l=s[n],f=s[0],a=s[l-2],b=s[l-1],e[a.i][b.i]||A(%a,b){@C(a,b)!=0?0:a.x<0==b.x<0&&a.y<0==b.y<0&&L(a)>L(b)},p,a,b)?0:(p=(v=V(a,b),p[k](%x){@C(v,V(a,x))>=0})),A(%a,b){@C(a,b)>0},p,b,f)?0:(p.forEach(%q){@F(p[k](%r){@q!==r}),s.concat([q]))}),s[2]&&p[n]==0&&!e[b.i][f.i]?G(s):0)))};e=p.map(%x,i){@p.map(%y,j){@i==j})});for(i=p[n];i--;){for(j=i;j--;){q=p[k](%p,x){@x!=i&&x!=j});F(q,[p[i],p[j]]);F(q,[p[j],p[i]]);e[i][j]=e[j][i]=1}}console.log(r)}})(%a,b){@{x:b.x-a.x,y:b.y-a.y}},%a,b){@a.x*b.y-a.y*b.x},%v){@v.x*v.x+v.y*v.y},0,'filter','length')".replace(/%/g,'function(').replace(/@/g,'return '))

कोड एक अनाम फ़ंक्शन देता है। एक पैरामीटर के रूप में, यह बिंदुओं की एक सरणी लेता है, जैसे [[0,1],[2,3],[4,5]]। इसे उपयोग करने के लिए आप इसे var f=पहले रख सकते हैं , या यदि आप इसे कमांड लाइन से उपयोग करना चाहते हैं, (process.argv[2].replace(/ /g,'').slice(1,-1).split(')(').map((x)=>x.split(',')))तो अंत में जोड़ें , और इसे कॉल करेंnode convpol.js '(1,2)(3,4)(5,6)'

चुनौती के लिए धन्यवाद! जैसा कि कोई संदर्भ कार्यान्वयन नहीं है, मैं यह साबित नहीं कर सकता कि यह सही है, लेकिन यह बिंदु सूची के क्रमपरिवर्तन के लिए कम से कम संगत है। मैंने लगभग नहीं सोचा था कि यह काम करने वाला था, क्योंकि डिबगिंग कोड वाले संस्करण, यहां तक ​​कि विकलांग भी, वैसे भी घातीय समय वृद्धि के साथ बहुत धीमे थे। मैंने इसे वैसे भी गोल्फ करने का फैसला किया, और यह देखकर खुश था कि यह मेरी मशीन पर 50 अंक के लिए 2 सेकंड से कम हो गया। यह 1 मिनट में लगभग 130 अंक की गणना कर सकता है।

एल्गोरिथ्म के समान है ग्राहम स्कैन के , सिवाय इसके कि इसे हर जगह खाली उत्तल पतवारों की खोज करनी है।

व्याख्या

यहां एल्गोरिदम कैसे काम करता है, इसका एक उच्च-स्तरीय अवलोकन है। इस एल्गोरिथ्म का मांस सिर्फ काउंटर-क्लॉकवाइज उत्तल छोरों के लिए खोज रहा है जो एक बिंदु को संलग्न नहीं करते हैं। प्रक्रिया कुछ इस प्रकार है:

  1. अंकों की एक जोड़ी, और अन्य सभी बिंदुओं की एक सूची के साथ शुरू करें।
  2. यदि सूची में किसी बिंदु के माध्यम से बिंदुओं की वर्तमान जोड़ी बिल्कुल जाती है, तो रुकें।
  3. वर्तमान जोड़ी के सभी बिंदुओं को दक्षिणावर्त फ़िल्टर करें, क्योंकि वे बहुभुज अवतल बनाते हैं।
  4. बचे सभी बिंदुओं के लिए, निम्नलिखित करें:
    1. यदि इस बिंदु से श्रृंखला के पहले बिंदु तक कोई रेखा किसी भी बिंदु पर दक्षिणावर्त घूमती है या घेरती है, तो इस बिंदु को छोड़ दें, क्योंकि कोई भी पॉलीगॉन बिंदु को घेरेगा।
    2. इस बिंदु को श्रृंखला में जोड़ें, वर्तमान श्रृंखला और अंकों की सूची के साथ चरण 1 से पुनरावृत्ति करें।
  5. यदि कोई अंक नहीं बचा था, और श्रृंखला में कम से कम 3 अंक हैं, तो यह एक वैध उत्तल बहुभुज है। इन बहुभुज का सबसे बड़ा क्षेत्र याद रखें।

इसके अलावा, एक अनुकूलन के रूप में, हम जाँच के रूप में श्रृंखला की प्रारंभिक जोड़ी को रिकॉर्ड करते हैं, इसलिए श्रृंखला में कहीं भी इस जोड़ी को देखने के बाद कोई भी खोज तुरंत खोज को रोक सकती है, क्योंकि इस जोड़ी के साथ सबसे बड़ा बहुभुज पहले ही मिल चुका है।

इस एल्गोरिथ्म को कभी भी दो बार बहुभुज नहीं मिलना चाहिए, और मैंने इसे प्रयोगात्मक रूप से सत्यापित किया है।


2
+1, यह एक अद्भुत उत्तर है। आप को बदलने ===और !==साथ ==देने में सक्षम हो सकता है !=, लेकिन मैं आपके कोड को समझे बिना सुनिश्चित नहीं हो सकता ...
jrich

1
धन्यवाद! वे विशेष रूप से === और! == वस्तुओं की तुलना कर रहे हैं, इसलिए, दुख की बात है। यह सूचकांकों की तुलना करता था, लेकिन (x,i)=>p.i==i(13 वर्ण) x=>p===xअनुकूलन के बाद भी (8 वर्ण) की तुलना में थोड़ा लंबा है ।
ricochet1k

2
आपके लिए एक स्पष्टीकरण है @Lembik
ricochet1k

1
आपको लगता है कि O (n ^ 3) के रिकॉर्ड को पीटा गया है, जो कि SO से जुड़े प्रश्नों की टिप्पणियों में उल्लिखित है!

1
ठीक है, मुझे विश्वास है कि मुझे विश्वास नहीं हो रहा है कि यह संभव है कि यह O (n ^ 3) से कम हो। मैं एल्गोरिथम जटिलता के लिए बहुत नया हूं।
ricochet1k
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.