निम्नलिखित समस्या के लिए एक सबकुबिक एल्गोरिथ्म मौजूद है?


11

एक सममित वास्तविक मैट्रिक्स को देखते हुए , क्या एक एल्गोरिथम है जो योग गणना करता है सभी 1 \ leq i <j <k \ leq n समय-जटिलता के साथ O (n ^ 3) से बेहतर है ?n×nA=(aij)

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

3
ध्यान दें कि यह किसी दिए गए ग्राफ़ में त्रिकोणों की संख्या गिनने में कम से कम उतना ही कठिन है । यदि आपका इनपुट मैट्रिक्स एक ग्राफ को एन्कोड करता है जैसे कि "0" एक किनारे को इंगित करता है और "1" एक लापता किनारे को इंगित करता है, तो max(aij,aik,ajk)=0 यदि और केवल यदि वहां है एक त्रिभुज है जो nodes i , j , और k द्वारा बनता है k, और अन्यथा यह 1
जुक्का सुकोला

1
मुझे लगता है कि त्रिभुज गिनती के लिए एकमात्र ज्ञात महत्वपूर्ण सबकुबिक एल्गोरिदम तेज मैट्रिक्स गुणन पर आधारित हैं? इस समस्या में उन तकनीकों को यहाँ लागू करना मुश्किल हो सकता है। इसके अलावा, यदि आप कुछ व्यावहारिक तलाश रहे हैं, तो तेज मैट्रिक्स गुणन पर आधारित कुछ भी मददगार नहीं होगा।
जुल्का सुमेला

जवाबों:


3

समय में काम करने वाले काफी व्यावहारिक दृष्टिकोण मौजूद है , जहां प्रोसेसर शब्द में बिट्स की संख्या है। मुख्य विचार यह है कि आप मैट्रिक्स के तत्वों पर बढ़ते क्रम में एक-एक करके पुनरावृत्ति करते हैं (मनमाने ढंग से संबंध तोड़ते हैं) और "उन्हें स्विच करें"। उस क्षण पर विचार करें जब कुछ ट्रिपल का सबसे बड़ा तत्व चालू है। सरलता के लिए, मान हैं कि उक्त तत्व । जब अंतिम तत्व स्विच किया जाता है, तो उत्तर में ट्रिपल के मूल्य को जोड़ना स्वाभाविक है। इसलिए हमें संभावित की संख्या को गिनना होगा जैसे औरO(n3/w)waij,aik,ajkaijkaikajkपहले से ही चालू हैं (जो कि की संख्या होगी, यहां सबसे बड़ा तत्व है, इसलिए उन्हें अभी-अभी पूरी तरह से स्विच किया गया था)। यहां हम बिट ऑप्टिमाइज़ेशन का उपयोग करके भोले कार्यान्वयन को गति दे सकते हैं ।aijO(n)

अधिक जानकारी के लिए आप C ++ 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;
}

यदि आप बिट ऑप्टिमाइज़ेशन धोखा का उपयोग करने पर विचार करते हैं, तो आप एक ही परिणाम के लिए चार रूसी विधि का उपयोग कर सकते हैं, एक एल्गोरिथ्म, जो कम व्यावहारिक होना चाहिए (क्योंकि अधिकांश आधुनिक हार्डवेयर पर बहुत बड़ा है) लेकिन सैद्धांतिक रूप से बेहतर है। वास्तव में, हम चुनते हैं और मैट्रिक्स की प्रत्येक पंक्ति को पूर्णांक से से , जहाँ -th संख्या है सरणी पंक्ति के बिट्स से मेल खाती है जिसमें समावेशी से लेकर में अनन्य हैO(n3/logn)wblog2nnb02b1iibmin(n,(i+1)b)0-indexation। हम समय में इस तरह के हर दो ब्लॉक के अदिश उत्पादों को पहले से तैयार कर सकते हैं । मैट्रिक्स में एक स्थिति अपडेट करना तेज़ है क्योंकि हम केवल एक पूर्णांक बदल रहे हैं। पंक्तियों के अनुरूप और पंक्तियों के स्केलर उत्पाद को खोजने के लिए, उस पंक्तियों के अनुरूप सरणियों पर तालिका में संबंधित ब्लॉकों के स्केलर उत्पादों को देखें और प्राप्त उत्पादों को योग करें।O(22bb)ij

उपरोक्त अनुच्छेद पूर्णांकों के साथ कि आपरेशन मान लिया गया है ले समय। यह काफी आम धारणा है , क्योंकि यह आमतौर पर एल्गोरिदम की तुलनात्मक गति को नहीं बदलता है (उदाहरण के लिए, यदि हम उस धारणा का उपयोग नहीं करते हैं, तो ब्रूट बल विधि वास्तव में समय में काम करती है (यहाँ हम बिट संचालन में समय को मापते हैं) यदि पूर्ण मान के साथ पूर्णांक मानों को कम से कम कुछ निरंतर (और अन्यथा हम साथ समस्या को हल कर सकते हैं मैट्रिक्स गुणन वैसे भी); हालाँकि उपरोक्त चार रूसी पद्धति का उपयोग करता है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)
user89217

साथ ही, आपका कोड परिभाषित नहीं करता है matजो महत्वपूर्ण प्रतीत होता है। मैं समझता हूं कि इसे कैसे परिभाषित किया जा सकता है, लेकिन मुझे आश्चर्य है कि अगर (mat[i] & mat[j]).count()यह किसी एसटीएल कंटेनर के साथ वांछित होगा।
user89217

1
के बारे में mat- मुझे लगता है कि हमें इसका उपयोग करना चाहिए std::vector<boost::dynamic_bitset<int64_t>>
user89217

के बारे में mat: हाँ, मेरे पास वास्तव में मानक बिटसेट था, लेकिन boost::dynamic_bitsetइस मामले में और भी बेहतर है, क्योंकि इसके आकार को संकलन-समय स्थिर नहीं होना है। इस विवरण को जोड़ने और चार रूसी दृष्टिकोण को स्पष्ट करने के लिए उत्तर को संपादित करेंगे।
कबन -5

1
महान, यह मुझे ठोस दिखता है। एक मामूली बिंदु: चूंकि ट्रांसडिसोटोमस मॉडल मानता है कि हम में मशीन शब्दों पर संचालन कर सकते हैं , इसलिए किसी भी स्केलर उत्पादों को पहले से तैयार करने की आवश्यकता नहीं है। वास्तव में, मॉडल मानता है कि , इसलिए कम से कम जितना अच्छा है । और, जैसा कि आप कहते हैं, स्केलर उत्पादों को पहले से तैयार करने का कोई व्यावहारिक अर्थ नहीं है (एक सरणी देखो बाइनरी ऑप की तुलना में धीमी होगी)। O(1)wlog2nO(n3/w)O(n3/logn)
14:89 बजे यूज़र89217
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.