Как найти оптимальные продукты с наименьшей ценой и наибольшим количеством?

Я попробовал написать функцию для себя, но она как-то некорректно выводит конечный результат:

function findOptimalProducts(products, budget) {
    const getPrice = (priceString) => parseFloat(priceString.replace(/,/g, ""));
    const getQuantity = (quantityString) => parseFloat(quantityString.slice(1).replace(/K/g, "")) * (quantityString.endsWith("K") ? 1000 : 1);

    // Sort products by price per unit (price / quantity) in ascending order
    products.sort((a, b) => {
        const quantityA = getQuantity(a.quantity);
        const quantityB = getQuantity(b.quantity);
        const priceA = getPrice(a.price);
        const priceB = getPrice(b.price);
        return (priceA / quantityA) - (priceB / quantityB);
    });

    let selectedProducts = [];
    let totalQuantity = 0;
    let totalPrice = 0;

    // Loop through sorted products
    for (const product of products) {
        const pricePerUnit = getPrice(product.price) / getQuantity(product.quantity);
        const quantity = getQuantity(product.quantity);
        const productCost = pricePerUnit * quantity;

        // Check if adding the product would exceed the budget
        if (totalPrice + productCost <= budget) {
            selectedProducts.push(product);
            totalQuantity += quantity;
            totalPrice += productCost;
        } else {
            // Budget reached or almost reached (within a small tolerance), continue iterating
            if (totalPrice + productCost > budget + 100) { // Adjust tolerance as needed
                continue;
            }
        }
    }

    return {
        selectedProducts,
        totalQuantity,
        totalPrice,
    };
}

const products = [
    {
        "title": "Apple",
        "quantity": "+2.14K",
        "price": "800,000"
    },
    {
        "title": "Orange",
        "quantity": "+1.44K",
        "price": "200,000"
    },
    {
        "title": "Banana",
        "quantity": "+900",
        "price": "70,000"
    },
    {
        "title": "Grape",
        "quantity": "+96",
        "price": "90,000"
    },
    {
        "title": "Strawberry",
        "quantity": "+800",
        "price": "130,000"
    },
];



findOptimalProducts(products, 1000000); // Banana, Orange, Strawberry and Grape
findOptimalProducts(products, 800000); // Banana, Orange, Strawberry and Grape
findOptimalProducts(products, 300000); // Banana and Orange
findOptimalProducts(products, 20000); // Nothing

Как я могу правильно найти продукты, сумма цен которых является самой низкой, при самом большом количестве?

Пример правильных результатов:

Budget: $1M
Result: "Apple", "Banana" and "Strawberry"

Budget: $800K
Result: "Orange", "Banana", "Grape" and "Strawberry"

Budget: $300K
Result: "Orange" and "Banana"

Budget: $200K
Result: "Banana" and "Strawberry"

просто проверьте динамическое программирование

Alexander Nenashev 10.06.2024 12:29

«как-то неправильно выводит конечный результат» Создайте небольшой неудачный пример и начните отладку.

MrSmith42 10.06.2024 13:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Описание:

Функция findOptimalProductsDP призвана эффективно определить оптимальную комбинацию продуктов для покупки в рамках заданного бюджета. Он использует динамическое программирование для решения проблемы экономичным способом.

Как это работает:

  1. Инициализация массива динамического программирования: инициализирует двумерный массив. dp для хранения максимального общего количества, достижимого для каждого сочетание продуктов и бюджетов.
  2. Базовый вариант. Устанавливает базовый вариант, при котором продукты не используются ни с одним из них. бюджет.
  3. Итерация по продуктам и бюджетам. Функция выполняет итерацию. по каждому продукту и каждому возможному бюджету, рассчитывая максимальное количество, достижимое для каждой комбинации, учитывая включать или исключать текущий продукт.
  4. Возврат: после расчета максимального количества для каждого бюджета функция возвращается назад, чтобы определить, какие продукты были выбраны в пределах заданного бюджета.
  5. Вывод: Наконец, он возвращает объект, содержащий выбранный продукции и общее количество, достигнутое в рамках данного бюджета.

Код:

function findOptimalProductsDP(products, budget) {
  // Utility functions to extract price and quantity
  const getPrice = (priceString) => parseFloat(priceString.replace(/,/g, ""));
  const getQuantity = (quantityString) => parseFloat(quantityString.slice(1).replace(/K/g, "")) * (quantityString.endsWith("K") ? 1000 : 1);

  const n = products.length;
  // Initialize DP array
  const dp = Array(n + 1).fill(0).map(() => Array(budget + 1).fill(0));

  // Base case: No products used with any budget
  for (let j = 0; j <= budget; j++) {
    dp[0][j] = 0;
  }

  // Iterate through products and budgets
  for (let i = 1; i <= n; i++) {
    const product = products[i - 1];
    const price = getPrice(product.price);

    for (let j = 0; j <= budget; j++) {
      if (price > j) {
        // If the price of the product exceeds the budget, exclude the product
        dp[i][j] = dp[i - 1][j]; // Exclude product
      } else {
        const remainingBudget = j - price;
        const maxQuantityWithRemaining = dp[i - 1][remainingBudget];
        const totalQuantity = maxQuantityWithRemaining + getQuantity(product.quantity);
        // Max of excluding or including the current product
        dp[i][j] = Math.max(dp[i - 1][j], totalQuantity);
      }
    }
  }

  // Backtrack to find selected products
  const selectedProducts = [];
  let remainingBudget = budget;
  for (let i = n; i > 0 && remainingBudget > 0; i--) {
    if (dp[i][remainingBudget] !== dp[i - 1][remainingBudget]) {
      selectedProducts.push(products[i - 1]);
      remainingBudget -= getPrice(products[i - 1].price);
    }
  }

  return {
    selectedProducts,
    totalQuantity: dp[n][budget],
  };
}


const products = [{
    "title": "Apple",
    "quantity": "+2.14K",
    "price": "800,000"
  },
  {
    "title": "Orange",
    "quantity": "+1.44K",
    "price": "200,000"
  },
  {
    "title": "Banana",
    "quantity": "+900",
    "price": "70,000"
  },
  {
    "title": "Grape",
    "quantity": "+96",
    "price": "90,000"
  },
  {
    "title": "Strawberry",
    "quantity": "+800",
    "price": "130,000"
  },
];

console.info(findOptimalProductsDP(products, 1000000));
console.info(findOptimalProductsDP(products, 800000));
console.info(findOptimalProductsDP(products, 300000));
console.info(findOptimalProductsDP(products, 200000));

Вот как в этом случае вы можете использовать возврат в свою пользу, рассматривая каждый фрукт как бинарный вопрос о том, добавляете вы его в корзину или нет (кроме случая, когда недостаточно средств, когда мы вынуждены их не добавлять). )

const products = [
    {
        "title": "Apple",
        "quantity": "+2140",
        "price": "800000"
    },
    {
        "title": "Orange",
        "quantity": "+1440",
        "price": "200000"
    },
    {
        "title": "Banana",
        "quantity": "900",
        "price": "70000"
    },
    {
        "title": "Grape",
        "quantity": "96",
        "price": "90000"
    },
    {
        "title": "Strawberry",
        "quantity": "800",
        "price": "130000"
    },
];

let bestSofar = [];

function findCombination(products, index, funds, combination = []) {
    if (index < products.length) {
        findCombination(products, index + 1, funds, combination);
        if (funds >= products[index].price) {
            findCombination(products, index + 1, funds - products[index].price, combination.concat(products[index]));
        }
    } else {
        if (combination.map(item => item.quantity * item.price).reduce((a, b) => a + b, 0) > bestSofar.map(item => item.quantity * item.price).reduce((a, b) => a + b, 0)) {
            bestSofar = combination;
        }
    }
}



bestSofar = [];
findCombination(products, 0, 1000000); // Banana, Orange, Strawberry and Grape
console.info(bestSofar.map(item => item.title));
bestSofar = [];
findCombination(products, 0, 800000); // Banana, Orange, Strawberry and Grape
console.info(bestSofar.map(item => item.title));
bestSofar = [];
findCombination(products, 0, 300000); // Banana and Orange
console.info(bestSofar.map(item => item.title));
bestSofar = [];
findCombination(products, 0, 20000); // Nothing
console.info(bestSofar.map(item => item.title));

Другие вопросы по теме