एल्गोरिथ्म / डेटा संरचना का जवाब देने के लिए "मैं सामग्री के इस सेट के साथ क्या व्यंजन बना सकता हूं?"


11

औपचारिक रूप से, s ( U , Q ) = { V | वीयू और वीक्यू } जहां यू , क्यू , और वी सभी सेट का प्रतिनिधित्व करते हैं, और यू , और अधिक विशेष, सेट का एक सेट का प्रतिनिधित्व करता है। उदाहरण के लिए, यू एक कुकबुक में विभिन्न व्यंजनों के लिए आवश्यक अवयवों का एक सेट (सेट) हो सकता है क्यू के साथ सामग्री का सेट जो मैं वी का प्रतिनिधित्व करता हूं एक नुस्खा है जो मैं उन सामग्रियों के साथ बना सकता हूं। क्वेरी s ( U , Q)) प्रश्न से मेल खाती है "मैं इन सामग्रियों के साथ क्या बना सकता हूं?"

क्या मैं के लिए देख रहा हूँ एक डेटा प्रतिनिधित्व कि अनुक्रमित है यू इस तरह से है कि यह की कुशल प्रश्नों का समर्थन करता है रों ( यू , क्यू ) जहां क्यू और के सभी सदस्यों यू आम तौर पर सभी के सदस्यों के संघ की तुलना में छोटा हो जाएगा यू । इसके अलावा, मैं चाहूंगा कि यह कुशलतापूर्वक यू को अपडेट करने में सक्षम हो (जैसे, एक नुस्खा जोड़ें या निकालें)।

मैं मदद नहीं कर सकता, लेकिन सोचता हूं कि इस समस्या को अच्छी तरह से समझा जाना चाहिए, लेकिन मैं इसके लिए कोई नाम या संदर्भ नहीं पा सका हूं। क्या किसी को इसे कुशलतापूर्वक या ऐसी जगह पर हल करने की रणनीति के बारे में पता है जहां मैं इसके बारे में अधिक पढ़ सकता हूं?

जहाँ तक एक समाधान के बारे में सोचने के बाद, मुझे लगा कि मुझे सेट यू के लिए एक निर्णय पेड़ बनाना है । पेड़ में प्रत्येक नोड पर, सवाल "क्या आपके घटक सूची में x है ?" यू के सदस्यों की संख्या को अधिकतम करने के लिए चुने गए एक्स के साथ पूछा जाएगा जो उत्तर द्वारा समाप्त हो जाते हैं। जैसे ही यू अपडेट होता है, सही परिणाम खोजने के लिए आवश्यक प्रश्नों की संख्या को कम करने के लिए इस निर्णय पेड़ को फिर से संतुलित करने की आवश्यकता होगी। एक और विचार यू का प्रतिनिधित्व करने के लिए है एक n -dimensional बूलियन 'ऑक्ट्री' (जहां एन अद्वितीय सामग्री की संख्या है) की तरह कुछ के साथ ।

मेरा मानना ​​है कि "इन सामग्रियों के साथ क्या व्यंजन बनाया जा सकता है?" कुकबुक में कार्टेसियन उत्पाद (व्यंजनों के लिए आवश्यक सामग्री के सेट) को लेने के लिए उत्तर दिया जा सकता है, जिसमें किसी एक की पॉवरसेट के साथ रेसिपी और जोड़े के लिए परिणामित ऑर्डर किए गए जोड़े को फ़िल्टर करना है जिसमें दोनों तत्व समान हैं, लेकिन यह एक नहीं है कुशल समाधान, और मैं इस बारे में पूछ रहा हूं कि इस तरह के ऑपरेशन का अनुकूलन कैसे किया जाए; कोई इसे SQL में कैसे लिखेगा, यह कुशल होगा और SQL ऐसा क्या करता है जिससे यह कुशल हो सके?

यद्यपि मैं व्यंजनों की एक रसोई की किताब का चित्रण और सामग्री के एक सेट का उपयोग करता हूं, लेकिन मैं आशा करता हूं कि 'व्यंजनों' की संख्या और 'सामग्री' की संख्या बहुत बड़ी होगी (प्रत्येक के सैकड़ों सैकड़ों तक), हालांकि अवयवों की संख्या किसी दिए गए नुस्खा में और किसी दिए गए घटक सेट में अवयवों की संख्या अपेक्षाकृत छोटी होगी (शायद एक ठेठ 'नुस्खा' के लिए लगभग 10-50 और एक ठेठ 'घटक सेट' के लिए लगभग 100)। इसके अतिरिक्त, सबसे सामान्य ऑपरेशन क्वेरी एस ( यू , क्यू ) होगा, इसलिए यह सबसे इष्टतम होना चाहिए। इसका यह भी अर्थ है कि एक क्रूर बल एल्गोरिथ्म जिसमें हर नुस्खा की जांच करने या हर घटक पर काम करने की आवश्यकता होती है, हालांकि यह अपने आप ही अवांछित रूप से धीमा होगा। चालाक कैशिंग के साथ,


1
ऐसी समस्या जो SQL डेटाबेस के साथ आसानी से हल हो जानी चाहिए।
रॉबर्ट हार्वे

1
आपके अतिरिक्त विवरण के आधार पर, यह एक ऑर्बिट्ज़-स्केल समस्या की तरह लगता है। ऑर्बिट्ज़ का खोज इंजन एक लिस्प इंजन का उपयोग करता है जो एक अरब या तो डेटा बिंदुओं से गुजरता है ताकि उन उड़ानों की सूची प्राप्त हो जो आपके विशिष्ट यात्रा कार्यक्रम के लिए उपयुक्त होंगी। यह गैर-कार्यात्मक आवश्यकता है कि इसे 10 सेकंड या उससे कम समय में एक समाधान वापस करना होगा। यहां देखें paulgraham.com/carl.html , हालांकि ध्यान दें कि जानकारी काफी पुरानी है।
रॉबर्ट हार्वे

यह प्रश्न बहुत व्यापक है और इसके दो हिस्से हैं: एक डेटा संरचना और मौजूदा व्यंजनों को खोजने के लिए एल्गोरिथ्म जो अवयवों के सबसेट हैं, और बड़े डेटा के लिए इसे कैसे स्केल करें। मेरा लेना यह है कि यह दो प्रश्न होने चाहिए। जब तक आप अल्गोरिथम भाग को कम नहीं कर लेते, तब तक आप बड़े डेटा भाग को संबोधित नहीं कर सकते। user16054 ने पहले ही इस बात के लिए सहायता प्राप्त कर ली है कि कैसे रिलेशनल डेटाबेस प्रतिनिधित्व में तालिकाओं का उपयोग किया जाता है। यदि यह प्रश्न एल्गोरिथ्म / डेटास्ट्रक्चर भाग में संकुचित है, या एक अन्य स्वतंत्र प्रश्न पूछा गया था, तो मैं सुझाव दे सकता हूं।
चट्टानी

जवाबों:


4

आपके द्वारा दिए गए नंबरों के लिए, बस इसे बाध्य करें।

यहाँ एक जावास्क्रिप्ट प्रोग्राम है जो ब्रूट को डीबी में 10 सामग्री, डीबी में 10 व्यंजनों के लिए मजबूर करता है, प्रत्येक रेसिपी में 2 सामग्री की आवश्यकता होती है, और मेरे पास 5 सामग्रियां उपलब्ध हैं:

var i, j;
var numIngredients = 10;
var numRecipes = 10;
var numIngredientsPerRecipe = 2;
var numIngredientsInQuery = 5;

function containsAll(needles, haystack){ 
  var i, len;
  for(i = 0 , len = needles.length; i < len; i++){
      if(haystack.indexOf(needles[i]) == -1) {
          return false;
      }
  }
  return true;
}

// Set up a fake DB of recipes
var ingredients = [];
for (i = 0; i < numIngredients; i++) {
    ingredients.push(i);
}
console.log('Here are the ingredients:', ingredients);

var recipes = [];
for (i = 0; i < numRecipes; i++) {
    var neededIngredients = [];
    for (j = 0; j < numIngredientsPerRecipe; j++) {
        neededIngredients.push(Math.floor(Math.random() * numRecipes));
    }
    recipes.push({ recipeId: i, needed: neededIngredients});
}
console.log('Here are the recipes:', recipes);

// Set up a fake query
var ingredientsAvailable = [];
for (i = 0; i < numIngredientsInQuery; i++) {
    ingredientsAvailable.push(Math.floor(Math.random() * numRecipes));
}

console.log("Here's a query:", ingredientsAvailable);

//Time how long brute force takes
var start = Date.now();
var result = [];
for (i = 0; i < numRecipes; i++) {
    var candidateRecipe = recipes[i];
    if (containsAll(candidateRecipe.needed, ingredientsAvailable)) {
        result.push(candidateRecipe);
    }
}
var end = Date.now();
console.log('Found ' + result.length + ' recipes in ' + (end - start) + ' milliseconds.');
console.log(result);

यह 0 मिलीसेकंड में चलता है। मैंने इन छोटी संख्याओं को चुना ताकि आप इसे खुद को एक-दो बार चला सकें और अपने आप को समझा सकें कि यह वही है जो आप चाहते हैं और अपेक्षाकृत बग से मुक्त हैं।

अब इसे बदल दें ताकि हमारे पास डीबी में 1'000'000 सामग्री, डीबी में 1'000'000 व्यंजन, प्रति नुस्खा 50 सामग्री और मेरे लिए 100 सामग्री उपलब्ध हो। यानी मान जो आपके द्वारा दिए गए सबसे बड़े उपयोग के मामले में सभी के बराबर या अधिक हैं।

यह नोडज के तहत 125 मिलीसेकंड में चलता है, और यह डंबेस्ट कार्यान्वयन के साथ है जिसमें अनुकूलन का कोई प्रयास नहीं है।


1
जब तक ओपी की आवश्यकताएं नहीं बदलती हैं, तब तक इस तरह का तरीका नहीं अपनाने का कोई कारण नहीं है। चतुर डेटा संरचना? नहीं, काफी तेज? हाँ। बनाए रखने और समझने में आसान? सबसे निश्चित रूप से।
जे ट्राना
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.