বৃহত্তম উত্তল বহুভুজের ক্ষেত্রটি সন্ধান করুন


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) ।
মার্টিন ইন্ডার

@ মার্টিনবাটনার দুঃখের বিষয়, আমি নিজেই এই পরীক্ষার কেসটি তৈরি করতে পারি না কারণ আমার নিজের কাজ করার বাস্তবায়ন নেই। সমস্যাটি বরং জটিল
or

@xnor এর কয়েকটি উদাহরণ পাওয়া যাবে
orlp

"দশমিক বিন্দুর পরে 2 অঙ্কের কম হবে না"?
ডেভিডসি

উত্তর:


12

জাভাস্ক্রিপ্ট ES6, 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. এই বিন্দুটিকে শৃঙ্খলে যুক্ত করুন, বর্তমান চেইন এবং পয়েন্টগুলির তালিকার সাথে প্রথম ধাপ থেকে পুনরাবৃত্তি করুন।
  5. যদি কোনও পয়েন্ট না থাকে এবং চেইনে কমপক্ষে 3 পয়েন্ট থাকে তবে এটি একটি বৈধ উত্তল বহুভুজ। এই বহুভুজগুলির বৃহত্তম অঞ্চলটি মনে রাখবেন।

এছাড়াও, একটি অপ্টিমাইজেশন হিসাবে, আমরা চেনের প্রাথমিক জোড়াটি যাচাই করা হিসাবে রেকর্ড করি, সুতরাং চেইনের যে কোনও জায়গায় এই জুটিটি দেখার পরে কোনও অনুসন্ধান তত্ক্ষণাত অনুসন্ধান বন্ধ করে দিতে পারে, কারণ এই জুটির সাথে বৃহত্তম বহুভুজ ইতিমধ্যে পাওয়া গেছে।

এই অ্যালগরিদমটি কখনও দুবার বহুভুজ খুঁজে পাওয়া উচিত নয় এবং আমি পরীক্ষামূলকভাবে এটি যাচাই করেছি।


2
+1, এটি একটি আশ্চর্যজনক উত্তর। আপনি প্রতিস্থাপন করতে সক্ষম হতে পারেন ===এবং !==সঙ্গে ==এবং !=, কিন্তু আমি নিশ্চিত আপনার কোড বুঝে হতে পারে না ...
jrich

1
ধন্যবাদ! সেই নির্দিষ্ট === এবং! == অবজেক্টগুলির সাথে তুলনা করা হচ্ছে, তাই না, দুঃখের সাথে। এটি সূচকগুলি তুলনা করত, তবে (x,i)=>p.i==i(১৩ টি চর) x=>p===xঅপ্টিমাইজেশনের পরেও (৮ টি অক্ষর) থেকে কিছুটা দীর্ঘ longer
রিকোচেট 1 কে

2
সেখানে @Lembik জন্য একটি ব্যাখ্যা আছে
ricochet1k

1
আপনি লিঙ্কযুক্ত SO প্রশ্নের মন্তব্যে উল্লিখিত O (n ^ 3) রেকর্ডটিকে প্রহার করেছেন বলে মনে হচ্ছে!

1
ঠিক আছে, আমি যেখানে বিশ্বাস করি না সেখানে পৌঁছে যাচ্ছি এটি সম্ভব যে এটি হে (এন ^ 3) এর চেয়ে কম স্থানে চলে। আমি অ্যালগরিদমিক জটিলতায় খুব নতুন।
রিকোচেট 1 কে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.