গ্রাফের দীর্ঘতম চক্র


18

একটি নির্দেশিত গ্রাফ দেওয়া হয়েছে, দীর্ঘতম চক্র আউটপুট।

বিধি

  • যে কোনও যুক্তিসঙ্গত ইনপুট ফর্ম্যাট অনুমোদিত (যেমন প্রান্ত তালিকা, সংযোগ ম্যাট্রিক্স)।
  • লেবেলগুলি গুরুত্বপূর্ণ নয়, সুতরাং আপনার প্রয়োজনীয় লেবেলগুলি এবং / অথবা ইচ্ছাগুলির উপরে আপনি কোনও বিধিনিষেধ আরোপ করতে পারেন, যতক্ষণ না সেগুলিতে ইনপুটটিতে প্রদত্ত অতিরিক্ত তথ্য না থাকে (যেমন আপনার চক্রের নোডগুলি প্রয়োজন হয় না পূর্ণসংখ্যা সহ লেবেলযুক্ত এবং অন্যান্য নোডগুলিকে বর্ণমালাযুক্ত স্ট্রিং সহ লেবেলযুক্ত)।
  • একটি চক্র হ'ল নোডগুলির ক্রম যা সমস্ত সংযুক্ত থাকে এবং কোনও নোডের পুনরাবৃত্তি হয় না [1, 2, 3, 1], চক্রের শুরু এবং শেষ ( একটি চক্র, তবে [1, 2, 3, 2, 1]তা নয়) ব্যতীত অন্য কোনও নোডের পুনরাবৃত্তি হয় না।
  • যদি গ্রাফটি অ্যাসাইক্লিক হয় তবে দীর্ঘতম চক্রের দৈর্ঘ্য 0 থাকে এবং সুতরাং একটি খালি আউটপুট পাওয়া যায় (উদাঃ খালি তালিকা, কোনও আউটপুট মোটেও নয়)।
  • চক্রের নোডের তালিকার শেষে প্রথম নোডটি পুনরাবৃত্তি করা alচ্ছিক ( [1, 2, 3, 1]এবং [1, 2, 3]একই চক্রকে বোঝান)।
  • যদি একই দৈর্ঘ্যের একাধিক চক্র থাকে তবে যে কোনও একটি বা সমস্তই আউটপুট হতে পারে।
  • বিল্টিনগুলি অনুমোদিত, তবে যদি আপনার সমাধানটি একটি ব্যবহার করে তবে আপনাকে বিকল্প বিকল্প সমাধান অন্তর্ভুক্ত করতে উত্সাহিত করা হবে যা ক্ষুদ্রতর বিল্টিনগুলি ব্যবহার করে না (যেমন একটি বিল্টিন যা সমস্ত চক্রকে আউটপুট করে)। যাইহোক, বিকল্প সমাধানটি আপনার স্কোরের দিকে মোটেই গণনা করবে না, সুতরাং এটি সম্পূর্ণ alচ্ছিক।

পরীক্ষার মামলা

এই পরীক্ষার ক্ষেত্রে ইনপুটটি প্রান্তগুলির একটি তালিকা হিসাবে দেওয়া হয় (যেখানে প্রথম উপাদানটি উত্স নোড এবং দ্বিতীয় উপাদানটি গন্তব্য নোড) এবং আউটপুটটি প্রথম / শেষ নোডের পুনরাবৃত্তি ছাড়াই নোডের একটি তালিকা।

[(0, 0), (0, 1)] -> [0]
[(0, 1), (1, 2)] -> []
[(0, 1), (1, 0)] -> [0, 1]
[(0, 1), (1, 2), (1, 3), (2, 4), (4, 5), (5, 1)] -> [1, 2, 4, 5]
[(0, 1), (0, 2), (1, 3), (2, 4), (3, 0), (4, 6), (6, 8), (8, 0)] -> [0, 2, 4, 6, 8]
[(0, 0), (0, 8), (0, 2), (0, 3), (0, 9), (1, 0), (1, 1), (1, 6), (1, 7), (1, 8), (1, 9), (2, 1), (2, 3), (2, 4), (2, 5), (3, 8), (3, 1), (3, 6), (3, 7), (4, 1), (4, 3), (4, 4), (4, 5), (4, 6), (4, 8), (5, 0), (5, 8), (5, 4), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 9), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 8), (7, 9), (8, 0), (8, 1), (8, 2), (8, 5), (8, 9), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6)] -> [0, 9, 6, 7, 8, 2, 5, 4, 3, 1]
[(0, 0), (0, 2), (0, 4), (0, 5), (0, 7), (0, 9), (0, 11), (1, 2), (1, 4), (1, 5), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 3), (2, 4), (2, 5), (2, 6), (3, 0), (3, 1), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 11), (4, 1), (4, 3), (4, 7), (4, 8), (4, 9), (4, 10), (4, 11), (5, 0), (5, 4), (5, 6), (5, 7), (5, 8), (5, 11), (6, 0), (6, 8), (6, 10), (6, 3), (6, 9), (7, 8), (7, 9), (7, 2), (7, 4), (7, 5), (8, 8), (8, 9), (8, 2), (8, 4), (8, 7), (9, 0), (9, 1), (9, 2), (9, 3), (9, 6), (9, 10), (9, 11), (10, 8), (10, 3), (10, 5), (10, 6), (11, 2), (11, 4), (11, 5), (11, 9), (11, 10), (11, 11)] -> [0, 11, 10, 6, 9, 3, 8, 7, 5, 4, 1, 2]

আপনার সমস্ত উদাহরণগুলিতে আপনার আউটপুটটি নূন্যতম সূচকের সাথে শুরু হয়। এটি কি প্রয়োজন?
দাদা

@ দাদা না, এটি পরীক্ষার ক্ষেত্রে কেবল একটি কাকতালীয় ঘটনা। আউটপুটটি চক্রের প্রথম নোড দিয়ে শুরু হবে (এবং বিকল্পভাবে শেষ হবে)।
মেগো

আপনার শেষ বিন্দু সহ বা বিনা বাক্সে বিন্যাস বাছাই করা উচিত এবং চ্যালেঞ্জটিতে কিছুই যুক্ত করা উচিত।
যাদু অক্টোপাস উরান

5
নিবন্ধন করুন শেষ নোডটি যদি ছেড়ে যায় তবে তা অন্তর্ভুক্ত থাকে (যেহেতু এটি প্রথম নোডের সমান)। প্রথম নোডটির পুনরাবৃত্তি না করা বাছাই করা গল্ফে আরও স্বাধীনতার অনুমতি দেয়।
মেগো

উত্তর:


4

গণিত, 80 58 বাইট

জংহওয়ান মিনকে ধন্যবাদ দিয়ে পুরো 22 বাইট সংরক্ষণ করা হয়েছে

(FindCycle[#,∞,All]/.{}->{Cases[#,v_v_]})[[-1,;;,1]]&

তিনটি বাইট বেসরকারী ব্যবহারের চরিত্র U+F3D5উপস্থাপন করে \[DirectedEdge]। প্রথম যুক্তির সাথে খাঁটি ফাংশনটি #নির্দেশিত প্রান্তগুলির একটি তালিকা হতে পারে expected Allসর্বাধিক Infinityমধ্যে দৈর্ঘ্যের চক্র সন্ধান করেGraph@# , তারপরে স্ব-লুপের তালিকা সহ খালি তালিকাটি প্রতিস্থাপন করে। চক্রগুলি প্রান্তগুলির তালিকা হিসাবে প্রতিনিধিত্ব করা হয় এবং দৈর্ঘ্য অনুসারে বাছাই করা হয়, সুতরাং আমরা সর্বশেষ এ জাতীয় চক্রটি গ্রহণ করি, তারপরে এর সমস্ত প্রান্ত থেকে আমরা প্রথম আর্গুমেন্টটি গ্রহণ করি যাতে আমরা নির্দিষ্ট আউটপুট ফর্ম্যাটে উল্লম্বগুলির একটি তালিকা পাই।

যদি কেবল গণিতই দৈর্ঘ্যের চক্র হিসাবে লুপগুলি চিকিত্সা করে 1( গুরুত্ব সহকারে AcyclicGraphQ @ CycleGraph[1, DirectedEdges -> True]দেয় True) তবে আমরা অন্য 26বাইটগুলি সংরক্ষণ করতে পারি :

FindCycle[#,∞,All][[-1,;;,1]]&

1
আপনার প্রয়োজন হবে না MaximalByকারণ ফলাফল FindCycleইতিমধ্যে দৈর্ঘ্য অনুসারে বাছাই করা হয়েছে (শেষ উপাদানটি দীর্ঘতম)। এছাড়াও, প্রথম আর্গুমেন্টের FindCycleতালিকা \[DirectedEdge](ক এর পরিবর্তে Graph) হতে পারে। প্লাস, আপনি 2-বাইট ব্যবহার করতে পারেন ;;(= 1;;-13-বাইট পরিবর্তে) Allমধ্যে Partএকটি বাইট সংরক্ষণ করুন। -22 বাইট (58 বাইট):(FindCycle[#,∞,All]/.{}->{Cases[#,v_v_]})[[-1,;;,1]]&
জংহওয়ান মিন

3

হাস্কেল , 157 154 150 বাইট

import Data.List
g#l=nub[last$(e:d):[d|p==last q||e`elem`init d]|d@(p:q)<-l,[e,f]<-g,p==f]
h g=snd$maximum$((,)=<<length)<$>[]:until((==)=<<(g#))(g#)g

এটি অনলাইন চেষ্টা করুন!

অনেকগুলি বাইট সংরক্ষণ করার জন্য @ লাইকনি এবং @ জিগ্রাবকে ধন্যবাদ!

এটি একটি খুব অদক্ষ প্রোগ্রাম:

প্রথম ফাংশন #পাথ একটি তালিকা লাগে lউপাদান প্রসারিত করতে এবং চেষ্টা (সংখ্যার তালিকার একটি তালিকা) lএর প্রতি সম্ভব প্রান্ত (দৈর্ঘ্য 2 একটি তালিকা) prepending দ্বারা gপ্রতিটি উপাদানে l। এটি তখনই ঘটে যখন উপাদানটি lইতিমধ্যে একটি চক্র নয় এবং যদি নতুন নোড যা প্রেন্ট করা হবে তা ইতিমধ্যে এর উপাদানটিতে অন্তর্ভুক্ত না রয়েছে l। যদি এটি ইতিমধ্যে একটি চক্র হয় তবে আমরা কোনও কিছু আগেই চালিত না করে আবার নতুন পাথের তালিকায় যুক্ত করি, যদি আমরা এটি প্রসারিত করতে পারি তবে আমরা বর্ধিত পথটিকে নতুন তালিকায় যুক্ত করি, অন্যথায় আমরা এটিকে নতুন তালিকায় যুক্ত করি না ।

এখন ফাংশনটি hবারবার সেই পাথগুলি প্রসারিত করার চেষ্টা করে (প্রান্তগুলির তালিকার সাথে নিজেই শুরু হয়) যতক্ষণ না আমরা একটি নির্দিষ্ট পয়েন্টে পৌঁছায়, অর্থাৎ আমরা আর কোনও পথ প্রসারিত করতে পারি না। এই মুহুর্তে আমাদের তালিকায় কেবল চক্র রয়েছে। তারপরে এটি কেবল দীর্ঘতম চক্রটি বাছাইয়ের বিষয়। স্পষ্টতই এই তালিকাতে চক্রগুলি একাধিকবার উপস্থিত হয় যেহেতু একটি চক্রের প্রতিটি সম্ভাব্য চক্র ঘূর্ণন আবার চক্র।


আপনি প্রথম বন্ধনীর মধ্যে ফেলে দিতে পারেন (p:q)<-l
লাইকনি

এবং <$>পরিবর্তে ব্যবহারmap করাতে অন্য একটি বাইট সংরক্ষণ করা উচিত ((,)=<<length)<$>[]:
লাইকনি

@ লাইকনি আপনাকে অনেক ধন্যবাদ!
flawr

চূড়ান্ত লাইনের পরে আপনার কাছে অতিরিক্ত জায়গা রয়েছে। এছাড়াও, করছেনd@(p:q)<-l কিছু বাইট সংরক্ষণ করে।
জাগারব

ওহ, d@(p:q)সত্যিই দুর্দান্ত, আমাকে দেখানোর জন্য আপনাকে ধন্যবাদ!
flawr

2

পাইথ, 20 বাইট

eMefqhMT.>{eMT1s.pMy

পরীক্ষা স্যুট

প্রান্তগুলির একটি তালিকা নেয় যেমন উদাহরণগুলির মধ্যে।

ব্যাখ্যা:

eMefqhMT.>{eMT1s.pMy
eMefqhMT.>{eMT1s.pMyQ    Variable introduction
                   yQ    Take all subsets of the input, ordered by length
                .pM      Reorder the subsets in all possible ways
               s         Flatten
                         (This should be a built in, I'm going to make it one.)
   f                     Filter on (This tests that we've found a cycle)
    qhMT                 The list of first elements of edges equals
           eMT           The last elements
         .>   1          Rotated right by 1
        {                Deduplicated (ensures no repeats, which would not be a
                         simple cycle)
  e                      Take the last element, which will be the longest one.
eM                       Take the last element of each edge, output.

2

বাশ + বিসডুটিলস, 129 বাইট

sed 's/^\(.*\) \1$/x \1 \1 x/'|sort|(tsort -l>&-)|&tr c\\n '
 '|sed 's/x //g'|awk 'm<NF{m=NF;gsub(/[^0-9 ] ?/,"");print}'|tail -1

tsort সমস্ত ভারী উত্তোলন করে, তবে এর আউটপুট ফর্ম্যাটটি বরং অনন্য এবং এটি দৈর্ঘ্যের চক্র সনাক্ত করতে পারে না Note নোট করুন যে এটি GNU tsort এর সাথে কাজ করে না।

প্রতিপাদন

--- t1 ---
0
--- t2 ---
--- t3 ---
0 1
--- t4 ---
1 2 4 5
--- t5 ---
0 2 4 6 8
--- t6 ---
0 2 1 6 3 7 4 8 9 5
--- t7 ---
0 11 10 3 1 2 4 7 5 8 9 6

2

জাভাস্ক্রিপ্ট (ES6), 173 163 156 145 139 বাইট

সংরক্ষিত 5 বাইট @ নীলকে ধন্যবাদ

f=(a,m,b=[])=>a.map(z=>!([x,y]=z,m&&x-m.slice(-1))&&b.length in(c=(n=m||[x],q=n.indexOf(y))?~q?b:f(a.filter(q=>q!=z),[...n,y]):n)?b=c:0)&&b

পরীক্ষার স্নিপেট


অবশ্যই কোনও সরল পুরানো স্যুইচ করা mapআপনাকে কয়েকটা বাইট বাঁচায়?
নীল

@ নীল এটি হতে হবে .filter().map(), তাই প্রায় অবশ্যই না। স্যুইচটি আমাকে 10 বাইট বাঁচিয়েছে (যদিও এটি এখনকার মতো পুরো গল্ফ ছিল না)
ETH প্রোডাকশনগুলি

আমি আপনাকে বোঝার ফলাফলটি ব্যবহার করতে দেখছি না, সুতরাং ব্যবহারের পরিবর্তে a.filter(z=>!e).map(z=>d)আপনি ব্যবহার করতে পারেন a.map(z=>e?0:d)
নীল

আপনি ঠিক বলেছেন, আমি 5 বাইট সংরক্ষণের জন্য সমস্ত কিছু একত্রিত করতে পারি। এবং আমি ঠিক বুঝতে পেরেছিলাম যে আমার আর দরকার নেই a+a?:-)
ETH প্রোডাকশনগুলি

ডাউনভাইটার দয়া করে কী ভুল বলতে পারেন? এটি ভুল আউটপুট উত্পাদন করে?
ETH প্রোডাকশনগুলি

2

হাস্কেল , 109 108 বাইট

import Data.List
f g=last$[]:[b|n<-[1..length g],e:c<-mapM(\_->g)[1..n],b<-[snd<$>e:c],b==nub(fst<$>c++[e])]

একটি নিখুঁত বল সমাধান: ইনপুট দৈর্ঘ্য না হওয়া পর্যন্ত ক্রমবর্ধমান দৈর্ঘ্যের প্রান্তের সমস্ত তালিকা তৈরি করুন, চক্রগুলি রাখুন, শেষটি ফিরে আসুন। বিন্যাসে গ্রাফ নেয় [(1,2),(2,3),(2,4),(4,1)]এটি অনলাইন চেষ্টা করুন!

ব্যাখ্যা

f g=                    -- Define function f on input g as
  last$                 -- the last element of the following list
  []:                   -- (or [], if the list is empty):
  [b|                   --  lists of vertices b where
   n<-[1..length g],    --  n is between 1 and length of input,
   e:c<-                --  list of edges with head e and tail c is drawn from
    mapM(\_->g)[1..n],  --  all possible ways of choosing n edges from g,
   b<-[snd<$>e:c],      --  b is the list of second elements in e:c,
   b==                  --  and b equals
    nub(fst<$>c++[e])]  --  the de-duplicated list of first elements
                        --  in the cyclic shift of e:c.

অবশেষে কী চলছে তা বুঝতে না পারতে এখনই সময় লেগেছে, পথ / চক্র অনুসন্ধানের অংশটি সত্যই চালাক, আমি অবাক!
flawr

@ ফ্লোয়ার ধন্যবাদ! ঠিক আছে, এটি উপস্থিত হয় যে ইসাকাক আমার আগে একই অ্যালগরিদমটি মূলত ব্যবহৃত হয়েছিল।
জাগারব

0

ম্যাটল্যাব, 291 260 বাইট

একটি অ্যাডিজেন্সি ম্যাট্রিক্স গ্রহণ করে Aযেখানে একটি প্রান্তটি ইন (i,j)দ্বারা নির্দেশিত হয় এবং1A(i,j)A অন্যান্য সমস্ত এন্ট্রিগুলিতে শূন্য হয়। আউটপুট দীর্ঘতম চক্রের একটি তালিকা। কোনও চক্র না থাকলে তালিকাটি খালি রয়েছে এবং চক্র থাকলে তালিকার শুরু এবং শেষের পয়েন্ট অন্তর্ভুক্ত রয়েছে। এটি ব্যবহার করে1 বেসড ইনডেক্সিং ।

এই সমাধান গ্রাফ সম্পর্কিত কোনও অন্তর্নির্মিত ফাংশন ব্যবহার করে না।

function c=f(A);N=size(A,1);E=eye(N);c=[];for j=1:N;l=g(j);if numel(l)>numel(c);c=l;end;end;function p=g(p)if ~any(find(p(2:end)==p(1)))e=E(p(end),:)Q=find(e*A)k=[];for q=Q;if ~ismember(q,p(2:end))n=g([p,q]);if numel(n)>numel(k);k=n;end;end;end;p=k;end;end;end

দুর্ভাগ্যক্রমে এটি ট্রিআইটঅনলাইনে চালিত হয় না কারণ এটি কোনও ফাংশনের মধ্যে কোনও ফাংশন ব্যবহার করে যা পুনরাবৃত্ত হয়। অল্প বিস্তৃত পরিবর্তন আপনাকে অষ্টম-অনলাইনলাইন.টনে চেষ্টা করার অনুমতি দেয়

একেবারে শেষ পরীক্ষার ক্ষেত্রে আমি একটি বিকল্প দীর্ঘতম চক্র পেয়েছি [0 2 1 4 3 5 7 8 9 11 10 6 0](এই স্বীকৃতিটি 0-ভিত্তিক সূচক ব্যবহার করে)

ব্যাখ্যা

এখানে মূল পদ্ধতিরটি হ'ল আমরা প্রতিটি নোড থেকে একটি বিএফএস করি এবং যত্ন নেব যে আমরা আরম্ভের নোড ব্যতীত আর কোনও মধ্যবর্তী নোড না ঘুরে দেখছি। এই ধারণার সাহায্যে আমরা সমস্ত সম্ভাব্য চক্র সংগ্রহ করতে পারি এবং সহজেই দীর্ঘতমটিকে বেছে নিতে পারি।

function c=f(A);
N=size(A,1);
E=eye(N);
c=[]; % current longest cycle
for j=1:N;                                      % iterate over all nodes
    l=getLongestCycle(j);                       % search the longest cycle through the current node
    if numel(l)>numel(c);                       % if we find a longer cycle, update our current longest cycle
        c=l;
    end;

end;

    function p=getLongestCycle(p);              % get longest cycle from p(1) using recursion
        if ~any(find(p(2:end)==p(1)));          % if we just found a cycle, return the cycle do nothing else, OTHERWISE:
            e=E(p(end),:);                      % from the last node, compute all outgoing edges
            Q=find(e*A);                        
            k=[];                               
            for q=Q;                            % iterate over all outogoin edges
                if ~ismember(q,p(2:end));       % if we haven't already visited this edge,
                    n=getLongestCycle([p,q]);   % recursively search from the end node of this edge
                    if numel(n)>numel(k);       % if this results in a longer cycle, update our current longest cycle
                        k=n;
                    end;
                end;
            end;
            p=k;
        end;
    end; 
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.