2008-08-18 9 views
8

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

Array 
(
    [leg0] => Array 
     (
      [UPS] => Array 
       (
        [days] => 1 
        [cost] => 5000 
       ) 

      [FedEx] => Array 
       (
        [days] => 2 
        [cost] => 3000 
       ) 

      [Conway] => Array 
       (
        [days] => 5 
        [cost] => 1000 
       ) 

     ) 

    [leg1] => Array 
     (
      [UPS] => Array 
       (
        [days] => 1 
        [cost] => 3000 
       ) 

      [FedEx] => Array 
       (
        [days] => 2 
        [cost] => 3000 
       ) 

      [Conway] => Array 
       (
        [days] => 3 
        [cost] => 1000 
       ) 

     ) 

    [leg2] => Array 
     (
      [UPS] => Array 
       (
        [days] => 1 
        [cost] => 4000 
       ) 

      [FedEx] => Array 
       (
        [days] => 1 
        [cost] => 3000 
       ) 

      [Conway] => Array 
       (
        [days] => 2 
        [cost] => 5000 
       ) 

     ) 

) 

आप प्रोग्राम सबसे अच्छा संयोजन खोजने के बारे में कैसे जाना होगा?

मेरे सबसे अच्छे प्रयास अब तक (तीसरे या चौथे एल्गोरिथ्म) है:

  1. प्रत्येक पैर
  2. के लिए सबसे लंबे समय तक शिपर का पता लगाएं हटा सबसे "महंगा" एक
  3. प्रत्येक पैर के लिए सबसे सस्ता शिपर का पता लगाएं
  4. की गणना कुल लागत & दिनों
  5. दिनों कर रहे हैं स्वीकार्य, खत्म, बाकी, गोटो 1

PHP में जल्दी मज़ाक उड़ाया-अप (ध्यान दें कि परीक्षण सरणी नीचे कामयाबी से काम करता है, लेकिन यदि आप इसे ऊपर से परीक्षण सरणी के साथ प्रयास करें, यह सही संयोजन नहीं मिल रहा है):

$shippers["leg1"] = array(
    "UPS" => array("days" => 1, "cost" => 4000), 
    "Conway" => array("days" => 3, "cost" => 3200), 
    "FedEx" => array("days" => 8, "cost" => 1000) 
); 

$shippers["leg2"] = array(
    "UPS" => array("days" => 1, "cost" => 3500), 
    "Conway" => array("days" => 2, "cost" => 2800), 
    "FedEx" => array("days" => 4, "cost" => 900) 
); 

$shippers["leg3"] = array(
    "UPS" => array("days" => 1, "cost" => 3500), 
    "Conway" => array("days" => 2, "cost" => 2800), 
    "FedEx" => array("days" => 4, "cost" => 900) 
);  

$times = 0; 
$totalDays = 9999999; 

print "<h1>Shippers to Choose From:</h1><pre>"; 
print_r($shippers); 
print "</pre><br />"; 

while($totalDays > $maxDays && $times < 500){ 
      $totalDays = 0; 
      $times++; 
      $worstShipper = null; 
      $longestShippers = null; 
      $cheapestShippers = null; 

      foreach($shippers as $legName => $leg){ 
       //find longest shipment for each leg (in terms of days) 
       unset($longestShippers[$legName]); 
       $longestDays = null;   

       if(count($leg) > 1){ 
        foreach($leg as $shipperName => $shipper){ 
         if(empty($longestDays) || $shipper["days"] > $longestDays){ 
          $longestShippers[$legName]["days"] = $shipper["days"]; 
          $longestShippers[$legName]["cost"] = $shipper["cost"]; 
          $longestShippers[$legName]["name"] = $shipperName; 
          $longestDays = $shipper["days"]; 
         } 
        }   
       } 
      } 

      foreach($longestShippers as $leg => $shipper){ 
       $shipper["totalCost"] = $shipper["days"] * $shipper["cost"]; 

       //print $shipper["totalCost"] . " &lt;?&gt; " . $worstShipper["totalCost"] . ";"; 

       if(empty($worstShipper) || $shipper["totalCost"] > $worstShipper["totalCost"]){ 
        $worstShipper = $shipper; 
        $worstShipperLeg = $leg; 
       } 
      } 

      //print "worst shipper is: shippers[$worstShipperLeg][{$worstShipper['name']}]" . $shippers[$worstShipperLeg][$worstShipper["name"]]["days"]; 
      unset($shippers[$worstShipperLeg][$worstShipper["name"]]); 

      print "<h1>Next:</h1><pre>"; 
      print_r($shippers); 
      print "</pre><br />"; 

      foreach($shippers as $legName => $leg){ 
       //find cheapest shipment for each leg (in terms of cost) 
       unset($cheapestShippers[$legName]); 
       $lowestCost = null; 

       foreach($leg as $shipperName => $shipper){ 
        if(empty($lowestCost) || $shipper["cost"] < $lowestCost){ 
         $cheapestShippers[$legName]["days"] = $shipper["days"]; 
         $cheapestShippers[$legName]["cost"] = $shipper["cost"]; 
         $cheapestShippers[$legName]["name"] = $shipperName; 
         $lowestCost = $shipper["cost"]; 
        } 
       } 

       //recalculate days and see if we are under max days... 
       $totalDays += $cheapestShippers[$legName]['days']; 
      } 
      //print "<h2>totalDays: $totalDays</h2>"; 
     } 

     print "<h1>Chosen Shippers:</h1><pre>"; 
     print_r($cheapestShippers); 
     print "</pre>"; 

मुझे लगता है कि मुझे वास्तव में कुछ प्रकार की चीज करना पड़ सकता है जहां मैं सचमुच प्रत्येक संयोजन को एक-एक करके (लूप की श्रृंखला के साथ) जोड़ता हूं और प्रत्येक का कुल "स्कोर" जोड़ता हूं, और सबसे अच्छा पाते हैं ....

संपादित करें: स्पष्टीकरण के लिए, यह "होमवर्क" असाइनमेंट नहीं है (मैं स्कूल में नहीं हूं)। यह काम पर मेरी वर्तमान परियोजना का हिस्सा है।

आवश्यकताएं (हमेशा के रूप में) लगातार बदल रही हैं। अगर मुझे इस समस्या पर काम करना शुरू करने पर वर्तमान बाधाएं दी गईं, तो मैं ए * एल्गोरिदम (या डिजस्ट्रा या सबसे छोटा पथ या सरल या कुछ) के कुछ संस्करण का उपयोग कर रहा हूं। लेकिन सब कुछ मोर्फ़िंग और बदल रहा है, और यह मुझे उस स्थान पर लाता है जहां मैं अभी हूं।

तो मुझे लगता है कि इसका मतलब है कि मुझे इस बिंदु पर किए गए सभी बकवासों को भूलना होगा और बस मुझे पता है कि मुझे क्या जाना चाहिए, जो एक पथ खोज एल्गोरिदम है।

+0

+1 "इस बकवास को कुचलने और दिमाग की स्थिति" के साथ मॉर्फिंग-ओवर-टाइम आवश्यकताओं के साथ +1 के लिए +1। – Alex

उत्तर

8

shortest path algorithms में से कुछ को डिजस्ट्रा की तरह बदल सकता है, प्रत्येक मार्ग को वज़न कम करने के लिए, लेकिन समय की ट्रैक भी रखता है और समय सीमा पर जाकर बंद हो जाता है यदि समय आपकी सीमा से अधिक हो। आपको सबसे सस्ता मिलना चाहिए जो आपको

5

आपके जैसा लगता है जैसे "रैखिक प्रोग्रामिंग समस्या" कहा जाता है। यह होमवर्क समस्या की तरह लगता है, कोई अपराध नहीं।

एलपी समस्या के शास्त्रीय समाधान को "सिंपलक्स विधि" कहा जाता है। यह गूगल।

हालांकि, उस विधि का उपयोग करने के लिए, आपको अपनी आवश्यकताओं का वर्णन करने के लिए सही ढंग से तैयार की गई समस्या होनी चाहिए।

फिर भी, सभी संभावित पथों का आकलन करना संभव हो सकता है, क्योंकि आपके पास इतना छोटा सेट है। हालांकि, ऐसी चीज स्केल नहीं होगी।

5

Dijkstra's algorithm के लिए एक नौकरी की तरह लगता है:

डिज्कस्ट्रा एल्गोरिथ्म, 1959 में डच कंप्यूटर वैज्ञानिक Edsger डिज्कस्ट्रा द्वारा नियोजित, 1 एक ग्राफ खोज एल्गोरिथ्म है कि गैर के साथ एक ग्राफ के लिए एकल स्रोत कम से कम पथ समस्या का हल है नकारात्मक किनारे पथ लागत, एक सबसे छोटा रास्ता पेड़ outputting। यह एल्गोरिदम अक्सर रूटिंग में उपयोग किया जाता है।

विकिपीडिया लेख में कार्यान्वयन विवरण भी हैं।

3

यदि मुझे पता था कि मुझे केवल पूर्व निर्धारित समय में 5 शहरों से निपटना पड़ा था, और आसन्न शहरों के बीच केवल 3 मार्ग थे, तो मैं बलपूर्वक बल दूंगा यह। सुरुचिपूर्ण होने में कोई बात नहीं।

यदि दूसरी ओर, यह एक होमवर्क असाइनमेंट था और मुझे एक एल्गोरिदम उत्पन्न करना था जो वास्तव में स्केल कर सकता था, तो शायद मैं एक अलग दृष्टिकोण लेता।

-1

मुझे लगता है कि डिजस्ट्रा का एल्गोरिदम एक छोटा रास्ता खोजने के लिए है।

cmcculloh कम से कम लागत की तलाश कर रहा है कि वह 5 दिनों में उस बाधा के अधीन है।

तो, केवल सबसे तेज़ तरीका ढूंढने से उसे सस्ता नहीं मिलेगा, और सस्ती के लिए वहां पहुंचने से, उसे आवश्यक समय में नहीं मिलेगा।

2

यह knapsack problem है। वजन पारगमन के दिन होते हैं, और लाभ $ 5000 होना चाहिए - पैर की लागत। सभी नकारात्मक लागतों को हटा दें और वहां से जाओ!

2

जैसा बाल्टीमर्क ने कहा, यह मूल रूप से एक रैखिक प्रोग्रामिंग समस्या है। यदि केवल शिपर्स के लिए गुणांक (शामिल किए गए 1, शामिल नहीं किए गए 0) प्रत्येक पैर के लिए (बाइनरी) पूर्णांक नहीं थे, तो यह अधिक आसानी से सुलभ होगा। अब आपको कुछ (बाइनरी) पूर्णांक रैखिक प्रोग्रामिंग (आईएलपी) हेरिस्टिक्स खोजने की जरूरत है क्योंकि समस्या एनपी-हार्ड है। लिंक के लिए Wikipedia on integer linear programming देखें; मेरे रैखिक प्रोग्रामिंग पाठ्यक्रम पर हमने कम से कम Branch and bound का उपयोग किया था।

दरअसल अब मैं इसके बारे में सोचता हूं, यह विशेष मामला वास्तविक आईएलपी के बिना हल करने योग्य है क्योंकि दिन की मात्रा < = 5 है जब तक कि यह पहली पसंद के लिए सबसे सस्ता वाहक चुनकर शुरू करें (Conway 5 : 1000)। इसके बाद आप फिर से सबसे सस्ती चुनते हैं, जिसके परिणामस्वरूप 8 दिन और 4000 मुद्रा इकाइयां बहुत अधिक होती हैं, इसलिए हम इसे रोक देते हैं। दूसरों को भी कोशिश करके हम देखते हैं कि वे सभी परिणाम दिन> 5 इसलिए हम पहली पसंद पर वापस आते हैं और दूसरे सबसे सस्ता (फेडेक्स 2: 3000) और फिर आखिरी में फेडेक्स में दूसरे और फिर कोशिश करते हैं। यह हमें कुल 4 दिन और 9 000 मुद्रा इकाइयां देता है।

हम तब पेड़ में अन्य खोजों को छेड़छाड़ करने के लिए इस लागत का उपयोग कर सकते हैं, जो कि कुछ उप-स्तरीय परिणाम के परिणामस्वरूप बड़े होते हैं, जिसे हमने पहले ही पाया है और उस बिंदु से उस उप-धारा को छोड़ दिया है। यह केवल तब तक काम करता है जब तक हम जानते हैं कि उपट्री में खोज बेहतर परिणाम नहीं देगी, जैसा कि हम यहां करते हैं जब लागत नकारात्मक नहीं हो सकती है।

आशा है कि इस रैंपिंग ने थोड़ा सा मदद की है :)।

संबंधित मुद्दे