কোনও স্ট্যাকের কোনও অবস্থানে কোনও আইটেম স্থানান্তর করতে ন্যূনতম পদক্ষেপগুলি কীভাবে খুঁজে পাবেন?


12

স্ট্যাক

এন এর সাথে স্ট্যাকের সংখ্যা এন এবং এনপিএস স্ট্যাকের একটি সেট দেওয়া হয়েছে এবং পি স্ট্যাকের ক্ষমতা হওয়ায় আমি কীভাবে নোড থেকে কিছু স্বেচ্ছাসেবক অবস্থান বিতে নোড থেকে ন্যূনতম স্বাপগুলি গণনা করতে পারি? আমি একটি গেম ডিজাইন করছি, এবং শেষ লক্ষ্যটি হ'ল সমস্ত স্ট্যাককে বাছাই করা যাতে সেগুলি সব একই রঙের হয়।

# Let "-" represent blank spaces, and assume the stacks are
stacks = [
           ['R', 'R', 'R', 'R'], 
           ['Y', 'Y', 'Y', 'Y'], 
           ['G', 'G', 'G', 'G'], 
           ['-', '-', '-', 'B'], 
           ['-', 'B', 'B', 'B']
         ]

আমি "B" Insert করতে চান, stacks[1][1]যেমন যে stacks[1] = ["-", "B", "Y", "Y"]। এটি করার জন্য প্রয়োজনীয় ন্যূনতম সংখ্যা আমি কীভাবে নির্ধারণ করতে পারি?

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

সম্পাদন করা

প্রয়োজনীয় পদক্ষেপের ন্যূনতম সংখ্যার গণনা করার জন্য আমি এই ফাংশনটি লিখেছি: স্ট্যাকস: স্ট্যাকের টুকরোগুলি প্রতিনিধিত্ব করে অক্ষরের তালিকার তালিকা [২] [0] স্ট্যাকের শীর্ষ [0] স্ট্যাক_ইন্ড: সূচকের সূচক এই স্ট্যাকটি যে টুকরোটি প্রয়োজন_পিস যুক্ত হবে: যে অংশটি স্ট্যাকের সাথে যুক্ত করা উচিত need_index: সেই সূচি যেখানে টুকরোটি থাকা উচিত

def calculate_min_moves(stacks, stack_ind, needs_piece, needs_index):
    # Minimum moves needed to empty the stack that will receive the piece so that it can hold the piece
    num_removals = 0
    for s in stacks[stack_ind][:needs_index+1]:
        if item != "-":
            num_removals += 1

    min_to_unlock = 1000
    unlock_from = -1
    for i, stack in enumerate(stacks):
        if i != stack_ind:
            for k, piece in enumerate(stack):
                if piece == needs_piece:
                    if k < min_to_unlock:
                        min_to_unlock = k
                        unlock_from = i

    num_free_spaces = 0
    free_space_map = {}

    for i, stack in enumerate(stacks):
        if i != stack_ind and i != unlock_from:
            c = stack.count("-")
            num_free_spaces += c
            free_space_map[i] = c

    if num_removals + min_to_unlock <= num_free_spaces:
        print("No shuffling needed, there's enough free space to move all the extra nodes out of the way")
    else:
        # HERE
        print("case 2, things need shuffled")

সম্পাদনা: স্ট্যাকের উপর পরীক্ষার কেস:

stacks = [
           ['R', 'R', 'R', 'R'], 
           ['Y', 'Y', 'Y', 'Y'], 
           ['G', 'G', 'G', 'G'], 
           ['-', '-', '-', 'B'], 
           ['-', 'B', 'B', 'B']
         ]

Case 1: stacks[4][1] should be 'G'
Move 'B' from stacks[4][1] to stacks[3][2]
Move 'G' from stacks[2][0] to stacks[4][1]
num_removals = 0 # 'G' is directly accessible as the top of stack 2
min_to_unlock = 1 # stack 4 has 1 piece that needs removed
free_spaces = 3 # stack 3 has free spaces and no pieces need moved to or from it
moves = [[4, 3], [2, 4]]
min_moves = 2
# This is easy to calculate
Case 2: stacks[0][3] should be 'B'
Move 'B' from stacks[3][3] to stack[4][0]
Move 'R' from stacks[0][0] to stacks[3][3]
Move 'R' from stacks[0][1] to stacks[3][2]
Move 'R' from stacks[0][2] to stacks[3][1]
Move 'R' from stacks[0][3] to stacks[3][0]
Move 'B' from stacks[4][0] to stacks[0][3]
num_removals = 0 # 'B' is directly accessible 
min_to_unlock = 4 # stack 0 has 4 pieces that need removed
free_spaces = 3 # If stack 3 and 4 were switched this would be 1
moves = [[3, 4], [0, 3], [0, 3], [0, 3], [0, 3], [4, 0]]
min_moves = 6
#This is hard to calculate

আসল কোড বাস্তবায়ন যে অংশটি কঠিন তা নয়, এটি একটি অ্যালগরিদমকে কীভাবে কার্যকর করতে হবে তা নির্ধারণ করে যা আমি যে সমস্যার সাথে লড়াই করছি sol

প্রতি @ YonIif অনুরোধ হিসাবে আমি একটি তৈরি করেছি সারকথা সমস্যার জন্য।

এটি যখন চলতে থাকে, তখন এটি স্ট্যাকের একটি এলোমেলো অ্যারে তৈরি করে এবং একটি এলোমেলো টুকরো বেছে নেয় যা এলোমেলো স্থানে একটি এলোমেলো স্ট্যাকের মধ্যে inোকানো প্রয়োজন।

এটি চালানো কনসোলে এই বিন্যাসের কিছু মুদ্রণ করে।

All Stacks: [['-', '-', 'O', 'Y'], ['-', 'P', 'P', 'O'], ['-', 'P', 'O', 'Y'], ['Y', 'Y', 'O', 'P']]
Stack 0 is currently ['-', '-', 'O', 'Y']
Stack 0 should be ['-', '-', '-', 'P']

অবস্থা হালনাগাদ

আমি এই সমস্যাটি কোনওভাবে সমাধান করতে খুব দৃ determined ়প্রতিজ্ঞ

মনে রাখবেন যে মামলার সংখ্যা হ্রাস করার উপায় রয়েছে, যেমন মন্তব্যগুলিতে @ হান্স ওলসন উল্লিখিত হিসাবে। এই সমস্যাটির বিষয়ে আমার সাম্প্রতিকতম পদ্ধতির মধ্যে উল্লিখিতগুলির মতো একই নিয়মের একটি সেট বিকাশ করা এবং একটি প্রজন্মের অ্যালগরিদমে তাদের নিয়োগ করা হয়েছে।

বিধি যেমন:

কখনও কোনও পদক্ষেপের বিপরীতে যাবেন না। 1-> 0 থেকে যান 0-> 1 (কোনও অর্থবোধ করে না)

টানা কখনও টুকরো টানা দু'বার নাও। 0 -> 1 থেকে 1 -> 3 থেকে কখনও সরাবেন না

স্ট্যাকস [এক্স] থেকে স্ট্যাক [ওয়াই] এর দিকে কিছুটা সরানো দেওয়া হয়েছে, তারপরে কিছুসংখ্যক পদক্ষেপ, তারপর স্ট্যাকস [ওয়াই] থেকে স্ট্যাকস [জেড] তে সরানো, যদি স্ট্যাকগুলি [জেড] একই অবস্থায় থাকে তবে সরানো যখন স্ট্যাকস [এক্স] থেকে স্ট্যাকের দিকে [ওয়াই] ঘটেছে, স্ট্যাকগুলি [এক্স] থেকে সরাসরি স্ট্যাকের দিকে সরিয়ে [মুছে ফেলা] [মুছে ফেলা]

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

হালনাগাদ

@ রুটটিউর উত্তরের জন্য ধন্যবাদ আমার কিছুটা ব্রেকথ্রু হয়েছিল, যা আমি এখানে রূপরেখা করব।

যুগান্তকারী

লক্ষ্যটির উচ্চতা নির্ধারণ করুন কারণ লক্ষ্য টুকরোটি অবশ্যই গন্তব্য স্ট্যাকের মধ্যে স্থাপন করতে হবে।

যখনই কোনও গোলের টুকরো সূচক <= স্ট্যাক_ উচ্চতা - গোলের উচ্চতায় স্থাপন করা হয়, ক্লিয়ার_পাথ () পদ্ধতির মাধ্যমে সর্বদা বিজয়ের সংক্ষিপ্ত পথ হবে।

Let S represent some solid Piece.

আই ই

Stacks = [ [R, R, G], [G, G, R], [-, -, -] ]
Goal = Stacks[0][2] = R
Goal Height = 2.
Stack Height - Goal Height = 0

এমন কিছু স্ট্যাক দেওয়া stack[0] = R, গেমটি জিতেছে।

                       GOAL
[ [ (S | -), (S | -), (S | -) ], [R, S, S], [(S | - ), (S | -), (S | -)] ]

যেহেতু এটি জানা যায় যে এগুলি সর্বদা কমপক্ষে স্ট্যাক_ উচ্চতা ফাঁকা স্থান উপলব্ধ, তাই সবচেয়ে খারাপ সম্ভাব্য কেসটি হ'ল:

 [ [ S, S, !Goal ], [R, S, S], [-, -, -]

যেহেতু আমরা জানি গোলের পিসটি লক্ষ্য গন্ত্রে থাকতে পারে না বা খেলাটি জিততে পারে না। এক্ষেত্রে ন্যূনতম সংখ্যক মুভগুলির প্রয়োজনীয় পদক্ষেপগুলি হবে:

(0, 2), (0, 2), (0, 2), (1, 0)

Stacks = [ [R, G, G], [-, R, R], [-, -, G] ]
Goal = Stack[0][1] = R
Stack Height - Goal Height = 1

এমন কিছু স্ট্যাক দেওয়া stack[1] = R, গেমটি জিতেছে।

              GOAL
[ [ (S | -), (S | -), S], [ (S | -), R, S], [(S | -), (S | -), (S | -)]

আমরা জানি কমপক্ষে 3 টি ফাঁকা জায়গা উপলব্ধ আছে, তাই সবচেয়ে খারাপ সম্ভাব্য কেসটি হ'ল:

[ [ S, !Goal, S], [S, R, S], [ -, -, - ]

এক্ষেত্রে ন্যূনতম সংখ্যাটি চালগুলি হবে:

(1, 2), (0, 2), (0, 2), (1, 0)

এটি সব ক্ষেত্রে ধরে রাখবে।

সুতরাং, গোলের উচ্চতাতে বা ততোধিক গোলের টুকরো স্থাপনের জন্য প্রয়োজনীয় ন্যূনতম পদক্ষেপের সন্ধান করার ক্ষেত্রে সমস্যাটি হ্রাস পেয়েছে।

এটি সমস্যাটিকে ধারাবাহিক উপ-সমস্যার মধ্যে বিভক্ত করে:

  1. গন্তব্য স্ট্যাকের যখন তার অ্যাক্সেসযোগ্য টুকরা থাকে! = লক্ষ্য টুকরা, সেই টুকরোটির জন্য কোনও বৈধ অবস্থান আছে কিনা তা নির্ধারণ করে, বা অন্য টুকরোগুলি অদলবদল করার সময় টুকরোটি সেখানে থাকা উচিত কিনা তা নির্ধারণ করে।

  2. যখন গন্তব্য স্ট্যাকের তার অ্যাক্সেসযোগ্য টুকরা == লক্ষ্য টুকরা থাকে, এটি নির্ধারিত করে যে এটি প্রয়োজনীয় লক্ষ্য উচ্চতাতে সরিয়ে নেওয়া যেতে পারে এবং অথবা অন্যটি অদলবদল করার সময় টুকরোটি থাকা উচিত কিনা।

  3. উপরের দুটি ক্ষেত্রে যখন অন্য টুকরোগুলি অদলবদল করা প্রয়োজন তখন লক্ষ্য টুকরোটি লক্ষ্য উচ্চতায় পৌঁছানো সম্ভব করার জন্য কোন টুকরোগুলি অদলবদল করতে হবে তা নির্ধারণ করে।

গন্তব্য স্ট্যাকের সর্বদা এর ক্ষেত্রে প্রথমে মূল্যায়ন করা উচিত।

আই ই

stacks = [ [-, R, G], [-, R, G], [-, R, G] ]

Goal = stacks[0][1] = G

লক্ষ্য স্ট্যাক চেক করা প্রথমে বাড়ে:

(0, 1), (0, 2), (1, 0), (2, 0) = 4 Moves

লক্ষ্য স্ট্যাক উপেক্ষা:

(1, 0), (1, 2), (0, 1), (0, 1), (2, 0) = 5 Moves

2
আপনি কি * চেষ্টা করেছেন ? এটি ডিজকস্ট্রার অ্যালগরিদমের সাথে মোটামুটি মিল তবে কখনও কখনও এটি যথেষ্ট দ্রুত হয়।
ইয়োনলিফ

1
আপনি কি দয়া করে গিথুব রেপো লিঙ্কটি ভাগ করতে পারেন? আমি ঠিক আছে যদি আমি নিজেকে পরীক্ষা করতে চাই। @ ট্রিস্টেন
ইউনলিফ

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

1
@ ডারিওহেট এই বিষয়টি নিয়েই আমি উদ্বিগ্ন ছিলাম! আমি আমার আঙ্গুলগুলি পেরিয়ে দিয়েছিলাম যে এটি এনপি-হার্ড সমস্যা হয়ে শেষ হবে না, তবে আমারও মনে হয়েছিল যে এটি এক হতে পারে। আমি জেনেটিক অ্যালগরিদমের সাথে আরও ভাল ভাগ্যবান হয়েছি এবং কিছু বিশেষ স্কোরিং ফাংশন যা চালগুলি স্কোর করে। আমি হ্যানয়ের সালিশী টাওয়ারগুলি একবার দেখে নেব! পরামর্শের জন্য ধন্যবাদ.
ট্রিস্টেন

1
যদি আপনি ধাঁধাটি এলোমেলোভাবে জেনারেট করার চেষ্টা করেন - স্পষ্টত অপ্রয়োজনীয় চালগুলি মুছে ফেলার কথা মনে রাখবেন (সামনের দিকে এগিয়ে যাওয়ার পরে কিছুটা সরিয়ে নেওয়া বা দুটি পদক্ষেপে একটি পদক্ষেপ নেওয়ার সময় যখন যথেষ্ট হবে; এবং সম্ভবত অপ্রাসঙ্গিক চলনের সাথে মিশ্রিতও থাকবেন)।
হ্যানস ওলসন

উত্তর:


1

আমি দুটি বিকল্প নিয়ে এসেছি, তবে তাদের মধ্যে কেউই সময় মতো 2 কেস সমাধান করতে সক্ষম নয়। প্রথম বিকল্পটি আপনার * (এন) হিসাবে একটি স্ট্রিং দূরত্ব পরিমাপ সহ এ * ব্যবহার করছে, দ্বিতীয় বিকল্পটি আইডিএ *। আমি অনেকগুলি স্ট্রিং মিলের ব্যবস্থা গ্রহণ করেছি, আমি আমার পদ্ধতির উপরে স্মিথ-ওয়াটারম্যান ব্যবহার করেছি। দ্রুত সমস্যাটি চিকিত্সা করার জন্য আমি আপনার স্বরলিপি পরিবর্তন করেছি। আমি প্রতিটি অঙ্কের শেষে সংখ্যার যোগ করেছি একটি টুকরো দু'বার সরানো হয়েছে কিনা তা পরীক্ষা করতে check

আমি যে কেসগুলিতে পরীক্ষা করেছি সেগুলি এখানে:

start = [
 ['R1', 'R2', 'R3', 'R4'], 
 ['Y1', 'Y2', 'Y3', 'Y4'], 
 ['G1', 'G2', 'G3', 'G4'], 
 ['B1'], 
 ['B2', 'B3', 'B4']
]

case_easy = [
 ['R', 'R', 'R', 'R'], 
 ['Y', 'Y', 'Y', 'Y'], 
 ['G', 'G', 'G'], 
 ['B', 'B'], 
 ['B', 'B', 'G']
]


case_medium = [
 ['R', 'R', 'R', 'R'], 
 ['Y', 'Y', 'Y', 'B'], 
 ['G', 'G', 'G'], 
 ['B'],
 ['B', 'B', 'G', 'Y']
]

case_medium2 = [
 ['R', 'R', 'R' ], 
 ['Y', 'Y', 'Y', 'B'], 
 ['G', 'G' ], 
 ['B', 'R', 'G'],
 ['B', 'B', 'G', 'Y']
]

case_hard = [
 ['B'], 
 ['Y', 'Y', 'Y', 'Y'], 
 ['G', 'G', 'G', 'G'], 
 ['R','R','R', 'R'], 
 ['B','B', 'B']
]

এখানে একটি * কোড রয়েছে:

from copy import deepcopy
from heapq import *
import time, sys
import textdistance
import os

def a_star(b, goal, h):
    print("A*")
    start_time = time.time()
    heap = [(-1, b)]
    bib = {}
    bib[b.stringify()] = b

    while len(heap) > 0:
        node = heappop(heap)[1]
        if node == goal:
            print("Number of explored states: {}".format(len(bib)))
            elapsed_time = time.time() - start_time
            print("Execution time {}".format(elapsed_time))
            return rebuild_path(node)

        valid_moves = node.get_valid_moves()
        children = node.get_children(valid_moves)
        for m in children:
          key = m.stringify()
          if key not in bib.keys():
            h_n = h(key, goal.stringify())
            heappush(heap, (m.g + h_n, m)) 
            bib[key] = m

    elapsed_time = time.time() - start_time
    print("Execution time {}".format(elapsed_time))
    print('No Solution')

আইডিএ * কোডটি এখানে:

#shows the moves done to solve the puzzle
def rebuild_path(state):
    path = []
    while state.parent != None:
        path.insert(0, state)
        state = state.parent
    path.insert(0, state)
    print("Number of steps to solve: {}".format(len(path) - 1))
    print('Solution')

def ida_star(root, goal, h):
    print("IDA*")
    start_time = time.time()
    bound = h(root.stringify(), goal.stringify())
    path = [root]
    solved = False
    while not solved:
        t = search(path, 0, bound, goal, h)
        if type(t) == Board:
            solved = True
            elapsed_time = time.time() - start_time
            print("Execution time {}".format(elapsed_time))
            rebuild_path(t)
            return t
        bound = t

def search(path, g, bound, goal, h):

    node = path[-1]
    time.sleep(0.005)
    f = g + h(node.stringify(), goal.stringify())

    if f > bound: return f
    if node == goal:
        return node

    min_cost = float('inf')
    heap = []
    valid_moves = node.get_valid_moves()
    children = node.get_children(valid_moves)
    for m in children:
      if m not in path:
        heappush(heap, (m.g + h(m.stringify(), goal.stringify()), m)) 

    while len(heap) > 0:
        path.append(heappop(heap)[1])
        t = search(path, g + 1, bound, goal, h)
        if type(t) == Board: return t
        elif t < min_cost: min_cost = t
        path.pop()
    return min_cost

class Board:
  def __init__(self, board, parent=None, g=0, last_moved_piece=''):
    self.board = board
    self.capacity = len(board[0])
    self.g = g
    self.parent = parent
    self.piece = last_moved_piece

  def __lt__(self, b):
    return self.g < b.g

  def __call__(self):
    return self.stringify()

  def __eq__(self, b):
    if self is None or b is None: return False
    return self.stringify() == b.stringify()

  def __repr__(self):
    return '\n'.join([' '.join([j[0] for j in i]) for i in self.board])+'\n\n'

  def stringify(self):
    b=''
    for i in self.board:
      a = ''.join([j[0] for j in i])
      b += a + '-' * (self.capacity-len(a))

    return b

  def get_valid_moves(self):
    pos = []
    for i in range(len(self.board)):
      if len(self.board[i]) < self.capacity:
        pos.append(i)
    return pos

  def get_children(self, moves):
    children = []
    for i in range(len(self.board)):
      for j in moves:
        if i != j and self.board[i][-1] != self.piece:
          a = deepcopy(self.board)
          piece = a[i].pop()
          a[j].append(piece)
          children.append(Board(a, self, self.g+1, piece))
    return children

ব্যবহার:

initial = Board(start)
final1 = Board(case_easy)
final2 = Board(case_medium)
final2a = Board(case_medium2)
final3 = Board(case_hard)

x = textdistance.gotoh.distance

a_star(initial, final1, x)
a_star(initial, final2, x)
a_star(initial, final2a, x)

ida_star(initial, final1, x)
ida_star(initial, final2, x)
ida_star(initial, final2a, x)

0

মন্তব্যে আপনি বলেছিলেন যে ক্ষমতা পি সহ এন স্ট্যাক রয়েছে এবং সর্বদা পি খালি জায়গা থাকে। যদি এটি হয় তবে মনে হয় এই অ্যালগরিদম elseআপনার কোডের দফাতে কাজ করবে (যেমন কখন num_removals + min_to_unlock > num_free_spaces):

  1. পছন্দসই টুকরোটি সন্ধান করুন যা স্ট্যাকের শীর্ষের নিকটে রয়েছে।
  2. পছন্দসই টুকরোটির উপরে থেকে সমস্ত টুকরোটি এমনভাবে সরান যাতে একটি স্ট্যাক থাকে (গন্তব্য স্ট্যাক নয়) উপরে একটি ফাঁকা জায়গা থাকে। প্রয়োজনে গন্তব্য স্ট্যাক বা অন্য স্ট্যাক থেকে টুকরো সরান। যদি একমাত্র উন্মুক্ত স্থানটি গন্তব্য স্ট্যাকের শীর্ষস্থানীয় হয় তবে অন্য স্ট্যাকের শীর্ষটি খোলার জন্য সেখানে একটি টুকরো স্থানান্তর করুন। এটি সর্বদা সম্ভব, কারণ পছন্দসই টুকরোটির উপরে থেকে সরে যাওয়ার জন্য খোলা জায়গা এবং সর্বাধিক পি -1 টুকরা রয়েছে।
  3. পছন্দসই টুকরোটি একটি স্ট্যাকের শীর্ষে ফাঁকা জায়গায় নিয়ে যান।
  4. গন্তব্য খোলা না হওয়া পর্যন্ত গন্তব্য স্ট্যাক থেকে টুকরো সরান।
  5. কাঙ্ক্ষিত টুকরোটি গন্তব্যে নিয়ে যান।

আমি এই উত্তরটি খনন করতে গত কয়েক ঘন্টা ব্যয় করেছি এবং আমি মনে করি সেখানে কিছু থাকতে পারে। যদি সম্ভব হয়, আপনি কীভাবে পছন্দসই টুকরোটির উপরে থাকা টুকরোগুলি সরানোর বিষয়ে আরও কিছু তথ্য সরবরাহ করতে পারেন? কোন স্ট্যাকগুলি সেগুলিতে স্থানান্তরিত করবেন তা আপনি কীভাবে নির্ধারণ করবেন? সম্ভবত কিছুটা psuedocode / কোড। এটি এখনও পর্যন্ত সমাধানের পক্ষে এটিই আমি অবশ্যই সবচেয়ে কাছের।
ট্রাইস্টেন

0

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

তাহলে পি কি? প্রতিটি কলামের জন্য পি সংজ্ঞায়িত করুন যে ব্লকগুলির সংখ্যা এখনও সেই কলামের সমস্ত রং পছন্দসই রঙের আগে অপসারণ করতে হবে। সুতরাং ধরুন আমরা লাল ব্লকগুলি বামতম স্তম্ভের শেষের দিকে যেতে চাই (আমি পরে এটিতে ফিরে আসব), এবং ধরুন নীচে একটি লাল ব্লক রয়েছে, তারপরে একটি হলুদ রয়েছে, তার উপরে আরও একটি ব্লক রয়েছে যে, এবং তারপর একটি খালি স্থান। তারপরে এই কলামটির জন্য পি = 2 (সমস্তগুলি লাল হওয়ার আগে দুটি ব্লক অপসারণ)। সমস্ত কলামের জন্য পি গণনা করুন। খালি শেষ হওয়া উচিত কলামের জন্য, p এর মধ্যে থাকা ব্লকের সংখ্যার সমান (তাদের সবকটিই যাওয়া উচিত)। বর্তমান অবস্থার জন্য পি হ'ল সমস্ত কলামের জন্য সমস্ত পি এর যোগফল।

যখন পি = 0 হয়, সমস্ত কলামে একই রঙ থাকে এবং একটি কলাম খালি থাকে, সুতরাং খেলাটি শেষ হয়েছে।

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

সুতরাং আমরা প্রতিটি রঙের শেষ কোথায় হওয়া উচিত তা কীভাবে নির্ধারণ করব? মূলত প্রতিটি সম্ভাবনার জন্য পি নির্ধারণ করে। উদাহরণস্বরূপ, লাল / হলুদ / সবুজ / খালি দিয়ে শুরু করুন, পি গণনা করুন, তারপরে লাল / হলুদ / খালি / সবুজ যান, পি গণনা করুন ইত্যাদি। সর্বনিম্ন পি দিয়ে প্রারম্ভিক অবস্থান নিন। এটি এন লাগে! গণনার। N = 8 এর জন্য এটি 40320, যা করণীয়। খারাপ খবরটি হ'ল আপনাকে সমান সর্বনিম্ন পি সহ সমস্ত সূচনা অবস্থান পরীক্ষা করতে হবে। সুসংবাদটি হ'ল আপনি বাকীটি ভুলে যেতে পারেন।

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

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

এই সমস্তগুলি আপনার গণনার সময়কে হ্রাস করতে হবে।


1
আমি মনে করি আপনি প্রশ্নটি ভুল বুঝেছেন! যদিও এটি প্রশ্নের পিছনে প্রেরণা। প্রশ্নটি হল একটি একক টুকরো, একক স্থানে নিয়ে যাওয়ার ন্যূনতম সংখ্যাটি সন্ধান করা। প্রশ্নটি স্ট্যাকগুলি বাছাই করার জন্য ন্যূনতম সংখ্যাগুলির সন্ধানের জন্য ছিল না, যদিও এটি প্রশ্নের পিছনে প্রেরণা। তবে, পি এর সেই স্কোরিংয়ের সাথে আপনি ভুল হয়ে যাবেন। এমন অনেকগুলি উদাহরণ রয়েছে যেখানে "খারাপ চালগুলি" রয়েছে যা প্রথমে পি বাড়িয়ে তোলে, এবং পরে দ্রুত হারে এটি হ্রাস করে। এই বলে যে, সম্ভবত আপনার উত্তরটির কোনও প্রাসঙ্গিকতা নেই বলে প্রশ্নটি পুনরায় পড়ুন।
3:44

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