Алгоритм: найти два натуральных числа, разница которых сведена к минимуму и произведение которых известно - PullRequest
0 голосов
/ 26 октября 2018

Немного предыстории ...

В настоящее время я создаю макрос, который будет оценивать стоимость инструмента для литья под давлением.Эти инструменты имеют полости, которые заполнены пластиком.Количество полостей, которое имеет инструмент, равно количеству деталей, которые будут сформированы.

До сих пор моя программа определяла минимальное количество полостей, которое может иметь инструмент, исходя из потребностей клиента.Это число всегда четное.Инструмент должен иметь четное количество полостей.Учитывая ограничивающую длину и ширину полости и установление предела того, сколько пространства могут занимать полости внутри инструмента, мне нужна моя программа для расчета комбинации числа полостей по длине и ширине, разница которых сведена к минимуму и чье произведениеравно общему количеству минимальных полостей, которые должен иметь инструмент.

Я программирую, мой макрос - SolidWorks VBA.Сначала я построил эту проблему в Excel и использовал инструмент решателя.Но я не могу найти способ ссылки на Excel Solver Tool в SolidWorks, чтобы автоматизировать эту проблему оптимизации.Я надеюсь найти умный набор уравнений, который может решить эту конкретную проблему для меня.Но если у кого-то есть лучшее представление о том, что использовать, это было бы замечательно.

Перефразирование в формате оптимизации ...

Переменные

  • x =количество полостей по ширине инструмента
  • y = количество полостей по длине инструмента
  • z = рекомендуемое количество полостей

Целевая функция

Свернуть x - y

Так, чтобы

  • x * y = z
  • x> = 1
  • y> = 1
  • x <= y </li>
  • x является целым числом
  • y является целым числом

Пример

Мой макрос говорит, что по порядкучтобы удовлетворить спрос, наш инструмент должен иметь как минимум 48 полостей.Найдите число полостей по длине и ширине инструмента, чтобы разница была минимальной, а произведение было равно 48. В идеале в этом случае макрос мог бы вернуть x = 6 и y = 8.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

Я думаю, вы можете просто проверить несколько примеров.Не требуется никакого сложного алгоритма.

Если вы уменьшите условие до 2 чисел, x и y, произведение которых равно z и с минимальной разницей, тогда ответ будет SQRT(z).

Это не целое число, которое соответствует вашим потребностям (в целом).Однако вы можете попробовать целые числа вокруг квадратного корня, чтобы увидеть, делят ли они z.Первое, которое вы нажали (т.е. минимальное отличие от SQRT(z)), должно иметь минимальное различие.

Если вы уменьшите условие до |z - x * y|, оно будет минимизировано, тогда я бы порекомендовал проверить числа в районе sqrt(z),Вам нужно проверить два случая - пол и потолок квадратного корня (и соответствующий другой номер).

0 голосов
/ 26 октября 2018

На всякий случай, если кому-то понадобится что-то похожее в будущем, но он не сможет понять псевдокод, который я написал, записал его. Я не был уверен, как вывести его как два значения, поэтому я просто скомбинировал их в виде строки, чтобы пользователь мог их увидеть.

Option Explicit
Function Factors(ByVal Test As Long) As String
    Dim Val As Long
    Dim i As Long
    Val = Test

    i = Int(Sqr(Val))
    While Val / i >= 2
        If Int(Val / i) * i = Val Then
            Factors = i & " & " & Val / i
            Exit Function
        End If
    i = i - 1
    Wend
End Function
0 голосов
/ 26 октября 2018

Просто чтобы уточнить, в вопросе вы действительно имели в виду Min y-x вместо Min x-y? В противном случае есть наивное решение, принимающее x = 1 и y = z. Min x - y = 1-z.

Я не программирую на VBA, но вот идея.

Так как x и y являются положительными целыми числами, и произведение равно z, с x <= y. Вы можете начать с x = floor(sqrt(z)) и уменьшать до x = 1.

Для каждого x проверьте, существует ли целое число y такое, что x * y = z. Если есть, разорвать петлю, и это пара, которую вы ищете. В противном случае продолжайте до x = 1

Если вам нужен псевдокод, чтобы вы могли перевести его на VBA. Вот оно

int x, y;
for (x = floor(sqrt(z)); x >= 1; --x)
{
    y = z / x;
    if (x * y == z)
        break;
}
...