বাউন্ডেড ন্যাপস্যাক সমস্যাটিকে 0/1 ন্যাপস্যাক সমস্যায় রূপান্তর করা


12

আমি একটি সমস্যা জুড়ে দৌড়েছি যেখানে লক্ষ্য ছিল ডায়নামিক প্রোগ্রামিং (অন্যান্য পদ্ধতির পরিবর্তে) ব্যবহার করা। বিস্তৃত হওয়ার জন্য একটি দূরত্ব এবং বিভিন্ন দৈর্ঘ্যের তারগুলির একটি সেট রয়েছে। দূরত্বটি ঠিকভাবে ছড়িয়ে দিতে নূন্যতম সংখ্যক কেবলের প্রয়োজন কী?

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

উদাহরণস্বরূপ, প্রদত্ত তারগুলি:
1 x 10 ফুট,
1 x 7ft,
1 x 6ft,
5 x 3ft,
6 x 2ft,
7 x 1ft

যদি লক্ষ্য স্প্যানটি 13 ফিট হয় তবে ডিপি অ্যালগরিদম দূরত্বটি বিস্তারে 7 + 6 বাছাই করে। একটি লোভী অ্যালগরিদম 10 + 3 বাছাই করত তবে এটি ন্যূনতম সংখ্যক কেবলের জন্য একটি টাই। 15 ফুট বিস্তৃত করার চেষ্টা করার সময় সমস্যাটি দেখা দেয়। ডিপি অ্যালগরিদম 4 টি তারের জন্য 6 + 3 + 3 + 3 বাছাই শেষ করেছে, যখন লোভী অ্যালগরিদম সঠিকভাবে কেবল 3 কেবল তার জন্য 10 + 3 + 2 বাছাই করে।

যাইহোক, 0/1 তে আবদ্ধ রূপান্তরিত করার জন্য কিছু হালকা স্ক্যানিং করা দেখে মনে হচ্ছে একাধিক আইটেমকে {পি, 2 পি, 4 পি ... convert এ রূপান্তর করার সুপরিচিত পদ্ধতির মতো} আমার প্রশ্ন হ'ল পি + 2 পি + 4 পি যদি একাধিক আইটেমের সংখ্যার যোগ না করে তবে এই রূপান্তরটি কীভাবে কাজ করবে। উদাহরণস্বরূপ: আমার কাছে 5 3 ​​ফিট কেবল রয়েছে। আমি খুব ভালভাবে {3, 2x3, 4x3 add যুক্ত করতে পারি না কারণ 3 + 2x3 + 4x3> 5x3। পরিবর্তে আমি কি {3, 4x3? যুক্ত করব?

[আমি বর্তমানে "ওরেগন ট্রেইল ন্যাপস্যাক সমস্যা" কাগজটি ছাঁটাই করার চেষ্টা করছি, তবে বর্তমানে এটি ব্যবহার করা পদ্ধতির মতো দেখে মনে হচ্ছে গতিশীল প্রোগ্রামিং নেই]]


1
আমি মনে করি হবে এই অধিক উপযুক্ত math.stackexchange.com বা এমনকি mathoverflow.net
ওবেদের

3
আমি জেনেরিক স্ট্যাকওভারফ্লোতে এবং এখানে ছিঁড়ে গিয়েছিলাম। উভয় সাইটে প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী পড়া, এই সাইটটি প্রথমে ডেটা কাঠামো এবং অ্যালগরিদমগুলি তালিকাবদ্ধ করে। গণিত সাইটের জন্য প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী পড়তে দেখে মনে হচ্ছে পরিবর্তে সিস্টিওরি সাইটটিতে জিজ্ঞাসা করার পরামর্শ দেওয়া হচ্ছে।
এন্টি 21

উত্তর:


1

এটি আপনার কোডে কিছু ভুল হতে পারে। আমি নরিশকিনের দ্বারা উল্লিখিত ডিপি প্রোগ্রামটি লিখেছিলাম। লক্ষ্য স্প্যান 13 এর জন্য এটি 6 + 7 এবং 15 এর জন্য এটি 2 + 6 + 7 প্রতিবেদন করে।

# weight: cable length
# total weight: target span
# value: 1 for each cable
# want minimum number of cables, i.e. minimum total value

def knapsack_01_exact_min(weights, values, W):
    # 0-1 knapsack, exact total weight W, minimizing total value
    n = len(weights)
    values = [0] + values
    weights = [0] + weights
    K = [[0 for i in range(W+1)] for j in range(n+1)]
    choice = [[0 for i in range(W+1)] for j in range(n+1)]
    for i in range(1, n+1):
        for w in range(1, W+1):
            K[i][w] = K[i-1][w]
            choice[i][w] = '|'
            if w >= weights[i]:
                t = K[i-1][w-weights[i]]
                if (w==weights[i] or t) and (K[i][w]==0 or t+values[i] < K[i][w]):
                    choice[i][w] = '\\'
                    K[i][w] = t+values[i]
    return K[n][W], choice

def print_choice(choice, weights):
    i = len(choice)-1
    j = len(choice[0])-1
    weights = [0] + weights
    while i > 0 and j > 0:
        if choice[i][j]=='\\':
            print weights[i],
            j -= weights[i]
        i -= 1
    print

lens = [10, 7, 6] + 5*[3] + 6*[2] + 7*[1]
values = (3+5+6+7)*[1]
span = 13
v, choice = knapsack_01_exact_min(lens, values, span)
print "need %d cables to span %d:" % (v,span),
print_choice(choice, lens)

span = 15
v, choice = knapsack_01_exact_min(lens, values, span)
print "need %d cables to span %d:" % (v,span),
print_choice(choice, lens)

আপনি যদি ইনপুট দৈর্ঘ্যের ক্রমটি সামঞ্জস্য করেন তবে এটি অন্যান্য অনুকূল সমাধান দিতে পারে। উদাহরণস্বরূপ, lens = 5*[3] + 6*[2] + 7*[1] + [10, 7, 6]15 = 10 + 2 + 3 দেবে।


আপনি যদি এই বিবৃতিটি পেলেন: 'যদি (ডাব্লু-ওজন [i] == 0 বা টি) এবং (কে [আই] [ডব্লিউ] == 0 বা টি + মানগুলি [i] <কে [আমি] [ডাব্লু] ): '? যদি এখন আমার ডিপি অ্যালগরিদমের উত্সটি ভুলে যান তবে আমার কোনও শূন্য চেক নেই, কেবলমাত্র '(টি + মান [i] <কে [i] [ডব্লু]]' জন্য পরীক্ষা করুন
এন্টস

1
আপনি নিখুঁত মোট ওজনের জন্য সমাধান করছেন , এর অর্থ হ'ল যখনই কোনও আইটেম বাছাই করা হয় তখন আমাদের সঠিক ওজন (বর্তমান পদক্ষেপের) পূরণ হয়েছে কিনা তা নিশ্চিত করা দরকার। সুতরাং, যখন আমরা কোনও আইটেম বাছাই করার সিদ্ধান্ত নিই, তখন দ্বিতীয় ধারাটি "টি + মানগুলি [i] <কে [i] [ডাব্লু]" নিশ্চিত করে যে আমাদের একটি মোট মোট মান থাকবে; তবে তার আগে, আমাদের প্রয়োজনীয় ওজনও পূর্ণ পূরণ করতে হবে, অর্থাৎ প্রথম আই -1 আইটেমগুলি অবশ্যই ওজন (ডাব্লু-ওজন [i]) পূর্ণ পূরণ করতে সক্ষম হবে, সুতরাং প্রথম ধারা "যদি কে [আই -1] [w -উয়েটস [i]] "(আমি এটির জন্য একটি অস্থায়ী পরিবর্তনশীল টি ব্যবহার করছি)।
jsz

দুটি অতিরিক্ত চেক "ডাব্লু == ওজন [i]" এবং "কে [আই] [ডাব্লু] == 0" রয়েছে; সেগুলি প্রয়োজনীয় এবং টেবিলগুলি কীভাবে শুরু করা হয় তার কারণে; আমি মনে করি আপনি এটি তৈরি করতে সক্ষম হবেন তাই আমি বিশদে যাব না। (আমি ডাব্লু-ওজন পরিবর্তন করেছি [i] == 0 থেকে ডাব্লু == ওজন [i]; এটি আরও পরিষ্কার হওয়া উচিত)।
jsz

1

আমি যেভাবে বাউন্ডেড ন্যাপস্যাক সমস্যাটি 0/1 এর মধ্যে রূপান্তর করতে দেখেছি তা হল একাধিক অভিন্ন আইটেম। যদি আপনার নীচের আইটেমগুলি থাকে (ওজন, ইউটিলিটি হিসাবে দেওয়া হয়):

  • 2 এক্স 1, 2
  • 3 এক্স 2, 3

আপনি এটিকে আইটেমটি ব্যবহার করে 0/1 সমস্যায় রূপান্তরিত করবেন

  • ১, ২
  • ১, ২
  • 2, 3
  • 2, 3
  • 2, 3

এবং এটি সমাধান করার জন্য একটি 0/1 অ্যালগরিদম ব্যবহার করুন। আপনার কাছে সমান নির্ভুলতার একাধিক সমাধান থাকতে পারে তাই আপনি একটি স্বেচ্ছাসেবক নির্বাচন করেন।


এখন আপনার তারের সমস্যা সম্পর্কে: আমার কেবলের দৈর্ঘ্যটি হ'ল দৈর্ঘ্য এবং প্রতিটি তারের মান হুবহু হবে (এটি কল করুন 1, যদিও কোনও ধনাত্মক মান কাজ করবে)। এখন, আপনার পছন্দের ন্যাপস্যাক সমাধানের অ্যালগরিদম ব্যবহার করুন তবে আপনি যেখানে সাধারণত একটি (আংশিক) সমাধান বেছে নেবেন যা মান সর্বাধিক করে তোলে, সেখানে এটি ন্যূনতম একটি নির্বাচন করুন। এছাড়াও, ক্ষমতার সমতুল্য মোট ওজন না থাকা সমস্ত সমাধান উপেক্ষা করুন। যদি কেউ চায় তবে আমি প্রকৃত কোড সহ আরও কংক্রিট অ্যালগরিদম লিখতে (চেষ্টা করার) চেষ্টা করতে পারি।


হ্যাঁ, ওজন এবং মান পূরণ করতে আমি ঠিক তাই করছি। আমি সর্বনিম্নের চেয়ে সর্বাধিক মানের জন্য কম্পিউটিং করছিলাম। আপনার পরামর্শ অনুসারে আমি এখনই কোডটি গণনা করার জন্য কোডটি পরিবর্তন করেছি এবং ডিপি টেবিলের সারি 0 ম্যাক্সিনটি হতে আরম্ভ করেছি। তবুও একই ফলাফল, ন্যাপস্যাক সমস্যার জন্য ডায়নামিক প্রোগ্রামিং সলিউশনটি এখনও 10 + 3 + 2 বা 7 + 6 + 2 এর পরিবর্তে 6 + 3 + 3 + 3 বাছাই শেষ করে।
পিঁপড়া
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.