3

Я создал модель для решения линейных программ в Julia. Сначала я решил линейную программу, но тот же код не работает для модифицированной программы. Вы можете понять, что происходит? Спасибо! Код, который работает отлично:Тот же код не работает последовательно в Julia

m = Model() 
@variable(m, x[1:77] >= 0) 
for i in nutrients 
    @constraint(m, dot(data[:, i], x) >= lower[i]) 
end 
@objective(m, Min, sum(dot(c, x))) 
status = solve(m) 
for i in 1:77 
    if getvalue(x[i]) > 0 
     println("Take ", getvalue(x[i]), " dollars of ", foods[i], " every day.") 
    end 
end 
println("The total cost for each day is ", getobjectivevalue(m), " dollars.") 
println("The total cost for the whole year is ", getobjectivevalue(m) * 365, " dollars.") 

Это результат:

Take 0.02951906167648827 dollars of Wheat Flour (Enriched) every day. 
Take 0.0018925572907052643 dollars of Liver (Beef) every day. 
Take 0.011214435246144865 dollars of Cabbage every day. 
Take 0.005007660466725203 dollars of Spinach every day. 
Take 0.061028563526693246 dollars of Navy Beans, Dried every day. 
The total cost for each day is 0.10866227820675685 dollars. 
The total cost for the whole year is 39.66173154546625 dollars. 

Это код, который не работает:

m1 = Model() 
for i in 1:77 
    if i == a 
     @variable(m1, x[i] == 0) 
    elseif i == b 
     @variable(m1, x[i] == 0) 
    else 
     @variable(m1, x[i] >= 0) 
    end 
end 
for i in nutrients 
    @constraint(m1, dot(data[:, i], x) >= lower[i]) 
end 
@objective(m1, Min, sum(dot(c, x))) 
status = solve(m1) 
for i in 1:77 
    if getvalue(x[i]) > 0 
     println("Take ", getvalue(x[i]), " dollars of ", foods[i], " every day.") 
    end 
end 
println("The total cost for each day is ", getobjectivevalue(m1), " dollars.") 
println("The total cost for the whole year is ", getobjectivevalue(m1) * 365, " dollars.") 

Вот сообщение об ошибке:

MethodError: no method matching dot(::NamedArrays.NamedArray{Any,1,Array{Any,1},Tuple{DataStructures.OrderedDict{Any,Int64}}}, ::JuMP.JuMPArray{JuMP.Variable,1,Tuple{Int64}}) 
Closest candidates are: 
    dot(::AbstractArray{T,1}, ::AbstractArray{T,1}) at linalg/generic.jl:302 
    dot{T,S,N}(::Array{T,N}, ::JuMP.JuMPArray{S,N,NT<:Tuple{Vararg{T,N}}}) at /Users/yiboliu/.julia/v0.5/JuMP/src/operators.jl:299 
    dot{T,S,N}(::JuMP.JuMPArray{T,N,NT<:Tuple{Vararg{T,N}}}, ::JuMP.JuMPArray{S,N,NT<:Tuple{Vararg{T,N}}}) at /Users/yiboliu/.julia/v0.5/JuMP/src/operators.jl:301 

in macro expansion; at /Users/yiboliu/.julia/v0.5/JuMP/src/macros.jl:400 [inlined] 
in macro expansion; at ./In[23]:13 [inlined] 
in anonymous at ./<missing>:? 

Я знаю, что проблема связана с ограничениями, но эта часть кода идентична и не работает. Можете ли вы дать мне представление о том, что происходит?

ответ

2

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

Сначала проверьте вывод ошибки, чтобы увидеть, какой именно вызов функции точки отвечает (у вас, кажется, два), а затем вставьте строку непосредственно перед вызовом, чтобы выводить информацию о входах, которые будут использоваться. Вы можете использовать функцию typeof(). Затем сравните то, что вы отправляете, что действительно хочет dot().

0

У вас не может быть двух вызовов @variable в той же модели, так как они будут определять разные переменные каждый раз. Таким образом, весь первый for ... end цикл в m1 должен быть заменен

@variable(m1, x[1:77] >= 0) 
@constraint(m1, x[a] == 0) 
@constraint(m1, x[b] == 0) 

(я полагаю a и b были определены в другом месте)