নিম্নলিখিত সমস্যার জন্য একটি সাবকিউবিক অ্যালগরিদম বিদ্যমান?


11

n×nA=(aij)

i,j,kmax(aij,aik,ajk)
1i<j<knO(n3)

3
মনে রাখবেন যে প্রদত্ত গ্রাফে ত্রিভুজগুলির সংখ্যা গণনার তুলনায় এটি কমপক্ষে কঠোর । যদি আপনার ইনপুট ম্যাট্রিক্স একটি গ্রাফ এনকোড করে যেমন "0" একটি প্রান্ত নির্দেশ করে এবং "1" অনুপস্থিত প্রান্তকে নির্দেশ করে, তবে যদি হয় এবং কেবল সেখানে থাকে নোড , , এবং দ্বারা গঠিত ত্রিভুজ এবং অন্যথায় এটি । max(aij,aik,ajk)=0ijk1
Jukka Suomela

1
আমি মনে করি ত্রিভুজ গণনার জন্য একমাত্র পরিচিত উল্লেখযোগ্য সাবকিউবিক অ্যালগরিদমগুলি দ্রুত ম্যাট্রিক্সের গুণটির উপর ভিত্তি করে? এই সমস্যাটিতে এখানে সেই কৌশলগুলি প্রয়োগ করা কঠিন হতে পারে। এছাড়াও, আপনি যদি ব্যবহারিক কিছু সন্ধান করছেন, দ্রুত ম্যাট্রিক্স গুণনের ভিত্তিতে যে কোনও কিছুই সহায়ক হবে না।
Jukka Suomela

উত্তর:


3

বেশ ব্যবহারিক পদ্ধতির বিদ্যমান যে কাজ সময়, যেখানে প্রসেসর শব্দ বিট সংখ্যা। মূল ধারণাটি হ'ল আপনি ক্রমবর্ধমান ক্রমে ম্যাট্রিক্সের উপাদানগুলির উপর একের পর এক পুনরাবৃত্তি করুন (নির্বিচারে সম্পর্ক ছিন্ন করুন) এবং "তাদের স্যুইচ করুন"। এই মুহুর্তটি বিবেচনা করুন যখন কিছু ট্রিপল of স্যুইচ করা থাকে। সরলতার জন্য, এর অনুমান করা বলল উপাদান যে দিন । শেষ উপাদানটি চালু করা হলে এখনই উত্তরে ট্রিপলের মান যুক্ত হওয়া স্বাভাবিক। সুতরাং আমাদের সম্ভাব্য এর সংখ্যা গণনা করতে হবে এবংO(n3/w)waij,aik,ajkaijkaikajkইতিমধ্যে চালু আছে (এটি ত্রিপের সংখ্যা হবে, এখানে the সর্বাধিক উপাদান, সুতরাং সেগুলি এখনই পুরোপুরি স্যুইচ করা হয়েছিল)। এখানে আমরা বিট অপ্টিমাইজেশান ব্যবহার করে নিষ্পাপ বাস্তবায়নকে গতিময় করতে পারি ।aijO(n)

বিশদের জন্য আপনি সি ++ 11 এ নিম্নলিখিত প্রয়োগগুলি উল্লেখ করতে পারেন যা , জন্য কাজ করা উচিত (এটি খুব অনুকূল নয়; তবে এটি এখনও কমপক্ষে আমার মেশিনে বৃহত্তর মার্জিন দ্বারা জন্য পরাজিত করে)।n5000|aij|109n=5000

// code is not very elegant, 
// but should be understandable
// here the matrix a has dimensions n x n
// a has to be symmetric!
int64_t solve (int n, const vector<vector<int32_t>> &a)
{
        std::vector<boost::dynamic_bitset<int64_t>> mat
        (n, boost::dynamic_bitset<int64_t>(n));

        vector<pair<int, int>> order;
        for (int j = 1; j < n; j++)
        for (int i = 0; i < j; i++)
            order.emplace_back(i, j);
        sort(order.begin(), order.end(),
            [&] (const pair<int, int> &l, const pair<int, int> &r) 
            {return a[l.first][l.second] < a[r.first][r.second];});

        int64_t ans = 0;
        for (const auto &position : order)
        {
            int i, j;
            tie (i, j) = position;
            mat[i][j] = mat[j][i] = 1;
            // here it is important that conditions 
            // mat[i][i] = 0 and mat[j][j] = 0 always hold
            ans += (mat[i] & mat[j]).count() * int64_t(a[i][j]);
        }

        return ans;
}

যদি আপনি বিট অপটিমাইজেশন প্রতারণামূলক ব্যবহার বিবেচনা করে থাকেন তবে আপনি এখানে একই ফলাফলের জন্য চারটি রুশিয়ান পদ্ধতি ব্যবহার করতে পারেন, একটি এলগরিদম উপস্থাপন করতে পারেন যা কম ব্যবহারিক হওয়া উচিত (কারণ বেশিরভাগ আধুনিক হার্ডওয়্যারে বেশ বড়) তাত্ত্বিকভাবে ভাল। প্রকৃতপক্ষে, আসুন এবং ম্যাট্রিক্সের প্রতিটি সারি 0 পূর্ণসংখ্যার থেকে পর্যন্ত রাখি , যেখানে তম সংখ্যাটি রয়েছে অ্যারে টির মধ্যে একচেটিয়া সমেত সারিটির বিটগুলির সাথে মিলে যায়O(n3/logn)wblog2nnb02b1iibmin(n,(i+1)b)0-indexation। আমরা সময়ে এই জাতীয় দুটি ব্লকের স্কেলার পণ্যগুলি পূর্বনির্ধারণ করতে পারি । ম্যাট্রিক্সে একটি অবস্থান আপডেট করা দ্রুত কারণ আমরা কেবল একটি পূর্ণসংখ্যা পরিবর্তন করছি। সারিগুলির স্কেলার পণ্যটি অনুসন্ধান করতে এবং কেবল সারিগুলির সাথে সম্পর্কিত অ্যারেগুলিতে পুনরাবৃত্তি করুন, সারণীতে সংশ্লিষ্ট ব্লকের স্কেলার পণ্যগুলি সন্ধান করুন এবং প্রাপ্ত পণ্যগুলি যোগ করুন।O(22bb)ij

উপরের অনুচ্ছেদ পূর্ণসংখ্যার সঙ্গে যে অপারেশন অনুমান নেওয়া সময়। এটি বেশ সাধারণ অনুমান , কারণ এটি সাধারণত অ্যালগরিদমের তুলনামূলক গতি পরিবর্তন করে না (উদাহরণস্বরূপ, আমরা যদি এই অনুমানটি ব্যবহার না করি তবে ব্রুটি ফোর্স পদ্ধতিটি আসলে সময়ে কাজ করে (এখানে আমরা বিট ক্রিয়াকলাপগুলিতে সময় পরিমাপ করি) যদি some কিছু ধ্রুবক জন্য কমপক্ষে to পর্যন্ত পূর্ণ মানগুলির সাথে পূর্ণসংখ্যার মানগুলি গ্রহণ করি (এবং অন্যথায় আমরা দিয়ে সমস্যাটি সমাধান করতে পারি) যাইহোক ম্যাট্রিক্সের গুণগুলি); তবে উপরের চারটি রুশিয়ান পদ্ধতি ব্যবহারের জন্য প্রস্তাবিতnO(1)O(n3logn)aijnεε>0O(nε)O(n3/logn) সেই ক্ষেত্রে আকারের সংখ্যার ক্রিয়াকলাপ ; সুতরাং এটি বিট অপারেশন করে, যা মডেল পরিবর্তন সত্ত্বেও ব্রুট ফোর্সের চেয়ে ভাল)O(logn)O(n3)

পদ্ধতির অস্তিত্ব সম্পর্কে প্রশ্নটি এখনও আকর্ষণীয়।O(n3ε)

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


প্রথমত, আপনার পরামর্শটি বাস্তবে ব্যবহারিক দিক থেকে সহায়ক বলে মনে হচ্ছে, আমি সম্ভবত এটি ব্যবহারের ক্ষেত্রে ব্যবহার করে দেখতে পারি। ধন্যবাদ! দ্বিতীয়ত, আপনার অ্যালগরিদমগুলি গণনা সংক্রান্ত জটিলতা কোনও নির্দিষ্ট প্রস্থের সংখ্যাসূচক প্রকারের জন্য এখনও । আপনি পদ্ধতির বিষয়ে বিস্তারিত বলতে পারেন? আমি কিভাবে আমরা স্কালে পণ্য খুঁজে পাইনি পাবেন না এবং তুলনায় দ্রুততর (যা যদি আমরা তাদের সব উপাদান অ্যাক্সেস প্রয়োজন হতে হবে)। O(n3)O(n3/logn)mat[i]mat[j]O(n)
ব্যবহারকারী 89217

এছাড়াও, আপনার কোডটি সংজ্ঞা দেয় না matযা গুরুত্বপূর্ণ বলে মনে হচ্ছে। আমি বুঝতে পারি যে এটি কীভাবে সংজ্ঞায়িত করা যেতে পারে তবে আমি অবাক হয়েছি যে (mat[i] & mat[j]).count()কোনও এসটিএল ধারক দিয়ে কাঙ্ক্ষিত কাজ করবে কিনা ।
ব্যবহারকারী 89217

1
সম্পর্কিত mat- আমার ধারণা আমাদের অবশ্যই ব্যবহার করা উচিত std::vector<boost::dynamic_bitset<int64_t>>
ব্যবহারকারী 89217

সম্পর্কিত mat: হ্যাঁ, আমার মনে আসলে স্ট্যান্ডার্ড বিটসেট ছিল তবে boost::dynamic_bitsetএটি ক্ষেত্রে আরও ভাল, কারণ এর আকারটি সংকলন-সময় ধ্রুবক হতে হবে না। এই বিশদটি যুক্ত করতে এবং চারটি রুশিয়ান পদ্ধতির ব্যাখ্যা করতে উত্তরটি সম্পাদনা করবে।
কাবান -5

1
দুর্দান্ত, এটি আমার কাছে দৃ looks় মনে হচ্ছে। একটি ছোটখাটো বিষয়: যেহেতু ট্রান্সডাইকোটমাস মডেল ধরে নিয়েছে যে আমরা এ মেশিনের শব্দের উপর ক্রিয়াকলাপ পরিচালনা করতে পারি, তাই কোনও স্কেলারের পণ্যকে প্রাক্কলন করার দরকার নেই। প্রকৃতপক্ষে, মডেল ধরে নেয় যে , সুতরাং কমপক্ষে মতোই ভাল । এবং, যেমন আপনি বলেছেন, স্কেলার পণ্যগুলির প্রাক্কলকুলেশন কোনও ব্যবহারিক ধারণা দেয় না (একটি অ্যারের চেহারা বাইনারি অপের চেয়ে ধীর হবে)। O(1)wlog2nO(n3/w)O(n3/logn)
ব্যবহারকারী 89217
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.