Я пытаюсь выучить Юлию в образовательных целях.Специально я пытался использовать Джулию и пакет JuMP для решения проблем оперативных исследований.
Я смотрел это замечательное видео с YouTube.Парень по имени Филип Томас показывает диатический пример.Однако это видео было создано в 2014 году. С тех пор Юлия эволюционировала.
Он использовал этот код:
#=
We are going to the thrift store and need 99 cents. What is the least amount of
weight we need to carry?
i.e. a knapsack problem
We specify that you need at least 99 cents - does the answer change if you need exact change?
=#
using JuMP
using Cbc # Open source solver. Must support integer programming.
m = Model(solver=CbcSolver())
# Variables represent how many of each coin we want to carry
@defVar(m, pennies >= 0, Int)
@defVar(m, nickels >= 0, Int)
@defVar(m, dimes >= 0, Int)
@defVar(m, quarters >= 0, Int)
# We need at least 99 cents
@addConstraint(m, 1 * pennies + 5 * nickels + 10 * dimes + 25 * quarters >= 99)
# Minimize mass (Grams)
# (source: US Mint)
@setObjective(m, Min, 2.5 * pennies + 5 * nickels + 2.268 * dimes + 5.670 * quarters)
# Solve
status = solve(m)
println("Minimum weight: ", getObjectiveValue(m), " grams")
println("using:")
println(round(getValue(pennies)), " pennies") # "round" to cast as integer
println(round(getValue(nickels)), " nickels")
println(round(getValue(dimes)), " dimes")
println(round(getValue(quarters)), " quarters")
Его код возвращает этот результат:
Minimum weight: 22.68 grams
using:
0.0 pennies
0.0 nickels
0.0 dimes
4.0 quarters
Я использую текущую версию Julia (1.0).Более того, я использую текущую версию JUMP.Есть синтаксические различия между текущей версией Julia и кодом выше.После некоторых проб и ошибок я смог правильно перевести код для запуска в Julia 1.0:
#=
We are going to the thrift store and need 99 cents. What is the least amount of
weight we need to carry?
i.e. a knapsack problem
We specify that you need at least 99 cents - does the answer change if you need exact change?
=#
using JuMP
using GLPK
using Cbc # Open source solver. Must support integer programming.
model = Model(with_optimizer(GLPK.Optimizer))
# Variables represent how many of each coin we want to carry
@variable(model, pennies >= 0, Int)
@variable(model, nickels >= 0, Int)
@variable(model, dimes >= 0, Int)
@variable(model, quarters >= 0, Int)
# We need at least 99 cents
@constraint(model, 1 * pennies + 5 * nickels + 10 * dimes + 25 * quarters >= 99)
# Minimize mass (Grams)
# (source: US Mint)
@objective(model, Min, 2.5 * pennies + 5 * nickels + 2.268 * dimes + 5.670 * quarters)
# Solve
optimize!(model)
println("Minimum weight: ", objective_value(model), " grams")
println("using:")
println(round(value(pennies)), " pennies") # "round" to cast as integer
println(round(value(nickels)), " nickels")
println(round(value(dimes)), " dimes")
println(round(value(quarters)), " quarters")
Интересно то, что терминал вернул результат:
Minimum weight: 22.68 grams
using:
0.0 pennies
0.0 nickels
0.0 dimes
4.0 quarters
Как видите, окончательный результат относительно минимального веса остается прежним.Однако решение о том, какую монету получить, меняется с 10 центов до 4 кварталов.
Помимо синтаксических изменений, я модифицировал солвер, потому что изначально у меня не было возможности запустить Cbc.
После этого я снова изменил на Cbc с этой простой модификацией:
model = Model(with_optimizer(Cbc.Optimizer))
После вышеупомянутой модификации "перевод кода" был ближе к оригиналу с Cbc в качестве выбранного решателя.Любопытно, что программа возвращает ожидаемый результат:
Minimum weight: 22.68 grams
using:
0.0 pennies
0.0 nickels
10.0 dimes
0.0 quarters
Однако я все еще в замешательстве.Согласно документации оба решателя могут решать MILP (смешанные целочисленные линейные задачи).
Почему это происходит?Почему разные решатели возвращают разные результаты, если оба имеют одинаковый профиль?Я пропустил некоторые детали во время перевода кода?
Заранее спасибо.