برنامه نویسی

رونمایی از پشت پرده: تسلط بر تکنیک های جستجوی و هرس اول

Backtracking یک روش سیستماتیک برای تکرار از طریق تمام تنظیمات احتمالی یک مشکل است. اغلب برای حل مشکلات در جایی که باید دنباله ای از تصمیمات اتخاذ شود ، استفاده می شود و هر تصمیم به مجموعه جدیدی از امکانات منتهی می شود. استفاده از پشتی استفاده می کند عمق اول جستجو (DFS) برای کشف فضای دولت ، و آن را استخدام می کند توابع هرس برای از بین بردن مسیرهای نامعتبر یا زیر حد متوسط ​​در مراحل جستجو.


مؤلفه های مشکلات برگشت

  1. حالت اولیه: نقطه شروع مشکل.
  2. حالت هدف/هدف: راه حل مورد نظر.
  3. حالتهای متوسط: کشورهایی که هنگام حرکت از حالت اولیه به حالت هدف تولید می شوند.
  4. مسیر: دنباله حالتها از حالت اولیه به حالت هدف.
  5. عملگر: قوانین یا اقداماتی که یک حالت را به دیگری تبدیل می کنند.
  6. تابع هرس: یک اکتشافی برای از بین بردن حالت های نامعتبر یا زیر حد اولیه.

الگوریتم پشت پرده

  1. با حالت اولیه شروع کنید.
  2. برای کشف تمام حالتهای ممکن از DFS استفاده کنید.
  3. اگر یک حالت نامعتبر است (بر اساس عملکرد هرس) ، عقب بکشید و مسیر دیگری را امتحان کنید.
  4. اگر یک کشور وضعیت هدف است ، راه حل را برگردانید.
  5. تکرار کنید تا تمام حالتهای ممکن مورد بررسی قرار گیرد یا راه حل پیدا شود.

مشکلات مثال با استفاده از backtracking حل شده است

1 مشکل قفل 3 رقمی

  • حالت اولیه: “111”
  • حالت هدف: ترکیب صحیح (به عنوان مثال ، “352”)
  • عملگر: افزایش هر رقم توسط 1 (از 1 تا 9).
  • تابع هرس: اگر یک رقم صحیح است (به عنوان مثال ، “کلیک”) ، آن را برطرف کرده و به رقم بعدی حرکت کنید.

اجرای:

function findLockCombination(target) {
    function backtrack(combination, index) {
        if (combination === target) {
            console.log("Found combination:", combination);
            return true;
        }
        if (index >= 3) return false;

        for (let i = 1; i <= 9; i++) {
            const newCombination = combination.slice(0, index) + i + combination.slice(index + 1);
            if (newCombination[index] === target[index]) {
                console.log("Click at position", index + 1, "with digit", i);
                if (backtrack(newCombination, index + 1)) return true;
            }
        }
        return false;
    }

    backtrack("111", 0);
}

const targetCombination = "352";
findLockCombination(targetCombination);
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


2 مشکل راهبان و شیاطین

  • حالت اولیه: 3 راهب ، 3 شیاطین و قایق در ساحل سمت چپ.
  • حالت هدف: همه راهبان و شیاطین در ساحل راست.
  • عملگر: 1 یا 2 نفر را در قایق حرکت دهید.
  • تابع هرس: اطمینان حاصل کنید که راهبان هرگز توسط شیاطین در هر یک از ساحل ها بیشتر نیستند.

اجرای:

function solveMonksAndDemons() {
    const initialState = { left: { monks: 3, demons: 3 }, right: { monks: 0, demons: 0 }, boat: "left" };
    const visited = new Set();

    function isSafe(state) {
        const { left, right } = state;
        return (
            (left.monks === 0 || left.monks >= left.demons) &&
            (right.monks === 0 || right.monks >= right.demons)
        );
    }

    function backtrack(state, path = []) {
        const key = JSON.stringify(state);
        if (visited.has(key)) return false;
        visited.add(key);

        if (state.left.monks === 0 && state.left.demons === 0) {
            console.log("Solution found:", path);
            return true;
        }

        const { left, right, boat } = state;
        const moves = [
            { monks: 1, demons: 0 },
            { monks: 2, demons: 0 },
            { monks: 0, demons: 1 },
            { monks: 0, demons: 2 },
            { monks: 1, demons: 1 },
        ];

        for (const move of moves) {
            if (
                (boat === "left" && left.monks >= move.monks && left.demons >= move.demons) ||
                (boat === "right" && right.monks >= move.monks && right.demons >= move.demons)
            ) {
                const newLeft = {
                    monks: left.monks - (boat === "left" ? move.monks : -move.monks),
                    demons: left.demons - (boat === "left" ? move.demons : -move.demons),
                };
                const newRight = {
                    monks: right.monks - (boat === "right" ? move.monks : -move.monks),
                    demons: right.demons - (boat === "right" ? move.demons : -move.demons),
                };
                const newState = {
                    left: newLeft,
                    right: newRight,
                    boat: boat === "left" ? "right" : "left",
                };

                if (isSafe(newState) && backtrack(newState, [...path, newState])) {
                    return true;
                }
            }
        }
        return false;
    }

    backtrack(initialState);
}

solveMonksAndDemons();
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


3 مشکل کشاورز ، بز ، کلم و گرگ

  • حالت اولیه: کشاورز ، بز ، کلم و گرگ در ساحل سمت چپ.
  • حالت هدف: همه در ساحل راست.
  • عملگر: کشاورز می تواند یک مورد (بز ، کلم یا گرگ) را در قایق ببرد.
  • تابع هرس: اطمینان حاصل کنید که بز تنها با کلم باقی نماند و گرگ با بز تنها باقی نمی ماند.

اجرای:

function solveFarmerProblem() {
  const initialState = {
    left: ["farmer", "goat", "cabbage", "wolf"],
    right: [],
    boat: "left",
  };
  const visited = new Set();

  function isSafe(state) {
    const unsafe = (side) =>
      (side.includes("goat") &&
        side.includes("cabbage") &&
        !side.includes("farmer")) ||
      (side.includes("wolf") &&
        side.includes("goat") &&
        !side.includes("farmer"));

    return !(unsafe(state.left) || unsafe(state.right));
  }

  function stateKey(state) {
    return JSON.stringify(state);
  }

  function backtrack(state, path = []) {
    if (state.left.length === 0) {
      console.log("Solution found:", path);
      return true;
    }

    const key = stateKey(state);
    if (visited.has(key)) return false;
    visited.add(key);

    const { left, right, boat } = state;
    const fromShore = boat === "left" ? left : right;

    // Possible moves: Farmer alone or Farmer + one item
    for (const item of [...fromShore, null]) {
      if (item === null || item !== "farmer") {
        let newLeft = [...left];
        let newRight = [...right];

        if (boat === "left") {
          newLeft = newLeft.filter((x) => x !== "farmer" && x !== item);
          newRight = [...newRight, "farmer"];
          if (item) newRight.push(item);
        } else {
          newRight = newRight.filter((x) => x !== "farmer" && x !== item);
          newLeft = [...newLeft, "farmer"];
          if (item) newLeft.push(item);
        }

        const newState = {
          left: newLeft,
          right: newRight,
          boat: boat === "left" ? "right" : "left",
        };

        if (isSafe(newState) && backtrack(newState, [...path, newState])) {
          return true;
        }
      }
    }

    return false;
  }

  backtrack(initialState);
}

solveFarmerProblem();
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


4 مشکل کوزه آب

  • حالت اولیه: هر دو کوزه خالی هستند.
  • حالت هدف: 2 گالن در کوزه 4 گالن.
  • عملگر: پر ، خالی یا آب را بین کوزه ها پر کنید.
  • تابع هرس: از تجدید نظر در ایالات جلوگیری کنید.

اجرای:

function solveWaterJug() {
    const initialState = { jug4: 0, jug3: 0 };
    const target = 2;
    const visited = new Set();

    function backtrack(state, path = []) {
        const key = `${state.jug4},${state.jug3}`;
        if (visited.has(key)) return false;
        visited.add(key);

        if (state.jug4 === target) {
            console.log("Solution found:", path);
            return true;
        }

        const { jug4, jug3 } = state;
        const moves = [
            { jug4: 4, jug3 }, // Fill jug4
            { jug4, jug3: 3 }, // Fill jug3
            { jug4: 0, jug3 }, // Empty jug4
            { jug4, jug3: 0 }, // Empty jug3
            { jug4: Math.max(0, jug4 - (3 - jug3)), jug3: Math.min(3, jug3 + jug4) }, // Pour jug4 to jug3
            { jug4: Math.min(4, jug4 + jug3), jug3: Math.max(0, jug3 - (4 - jug4)) }, // Pour jug3 to jug4
        ];

        for (const move of moves) {
            if (backtrack(move, [...path, move])) {
                return true;
            }
        }
        return false;
    }

    backtrack(initialState);
}

solveWaterJug();
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


نکات کلیدی:

  1. بازگشت به عقب روش نظامتی برای کشف همه راه حل های ممکن.
  2. استفاده می کند عمق اول جستجو وت توابع هرس برای از بین بردن مسیرهای نامعتبر.
  3. برای حل مفید است مشکلات NP-HARD مانند معماها ، مشکلات رضایت محدودیت و بهینه سازی ترکیبی.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا