Trying to update this optimization program that worked fine with julia 1.6.2, but now
returns the following error using julia 1.7.2.
The error occurs in line 24.
#constraint(m, sum(pitchers_lineup[i], i=1:num_pitchers) == 1)
using DataFrames
using GLPK
using JuMP
using CSV
num_lineups = 25
num_overlap = 3
path_hitters = "Hitters.csv"
path_pitchers = "Pitchers.csv"
path_to_output = "output.csv"
# This is a function that creates one lineup using the Type 4 formulation from the paper
function one_lineup_Type_4(hitters, pitchers, lineups, num_overlap, num_hitters, num_pitchers, catcher, first_baseman, second_baseman, third_baseman, shortstop, outfielders, num_teams, hitters_teams, pitchers_opponents)
m = Model(GLPK.Optimizer)
# Variable for Hitters in lineup
#variable(m, hitters_lineup[i=1:num_hitters], Bin)
# Variable for Pitcher in lineup
#variable(m, pitchers_lineup[i=1:num_pitchers], Bin)
# One Pitcher constraint
#constraint(m, sum(pitchers_lineup[i], i=1:num_pitchers) == 1)
# Eight Hitters constraint
#constraint(m, sum(hitters_lineup[i], i=1:num_hitters) == 8)
# between 1 and 2 catchers + first baseman
#constraint(m, sum((catcher)[i]*hitters_lineup[i], i=1:num_hitters) <= 2)
#constraint(m, 1 <= sum(catcher[i]*hitters_lineup[i], i=1:num_hitters))
# between 1 and 2 second basemen
#constraint(m, sum(second_baseman[i]*hitters_lineup[i], i=1:num_hitters) <= 2)
#constraint(m, 1 <= sum(second_baseman[i]*hitters_lineup[i], i=1:num_hitters))
# between 1 and 2 third basemen
#constraint(m, sum(third_baseman[i]*hitters_lineup[i], i=1:num_hitters) <= 2)
#constraint(m, 1 <= sum(third_baseman[i]*hitters_lineup[i], i=1:num_hitters))
# between 1 and 2 shortstops
#constraint(m, sum(shortstop[i]*hitters_lineup[i], i=1:num_hitters) <= 2)
#constraint(m, 1 <= sum(shortstop[i]*hitters_lineup[i], i=1:num_hitters))
# between 3 and 4 outfielders
#constraint(m, 3 <= sum(outfielders[i]*hitters_lineup[i], i=1:num_hitters))
#constraint(m, sum(outfielders[i]*hitters_lineup[i], i=1:num_hitters) <= 4)
# Financial Constraint
#constraint(m, sum(hitters[i,:Salary]*hitters_lineup[i], i=1:num_hitters) + sum(pitchers[i,:Salary]*pitchers_lineup[i], i=1:num_pitchers) <= 35000)
# exactly x different teams for the 8 hitters constraint
#variable(m, used_team[i=1:num_teams], Bin)
constr = #constraint(m, [i=1:num_teams], used_team[i] <= sum(hitters_teams[t, i]*hitters_lineup[t], t=1:num_hitters))
constr = #constraint(m, [i=1:num_teams], sum(hitters_teams[t, i]*hitters_lineup[t], t=1:num_hitters) == 4*used_team[i])
#constraint(m, sum(used_team[i], i=1:num_teams) == 2)
# No pitchers going against hitters
constr = #constraint(m, [i=1:num_pitchers], 6*pitchers_lineup[i] + sum(pitchers_opponents[k, i]*hitters_lineup[k], k=1:num_hitters)<=6)
# Overlap Constraint
constr = #constraint(m, [i=1:size(lineups)[2]], sum(lineups[j,i]*hitters_lineup[j], j=1:num_hitters) + sum(lineups[num_hitters+j,i]*pitchers_lineup[j], j=1:num_pitchers) <= num_overlap)
# Objective
#objective(m, Max, sum(hitters[i,:FPPG]*hitters_lineup[i], i=1:num_hitters) + sum(pitchers[i,:FPPG]*pitchers_lineup[i], i=1:num_pitchers) )
# Solve the integer programming problem
println("Solving Problem...")
print("\n")
status = solve(m);
# Puts the output of one lineup into a format that will be used later
if status==:Optimal
hitters_lineup_copy = Array(Int64)(0)
for i=1:num_hitters
if getvalue(hitters_lineup[i]) >= 0.9 && getvalue(hitters_lineup[i]) <= 1.1
hitters_lineup_copy = vcat(hitters_lineup_copy, fill(1,1))
else
hitters_lineup_copy = vcat(hitters_lineup_copy, fill(0,1))
end
end
for i=1:num_pitchers
if getvalue(pitchers_lineup[i]) >= 0.9 && getvalue(pitchers_lineup[i]) <= 1.1
hitters_lineup_copy = vcat(hitters_lineup_copy, fill(1,1))
else
hitters_lineup_copy = vcat(hitters_lineup_copy, fill(0,1))
end
end
return(hitters_lineup_copy)
end
end
#=
formulation is the type of formulation that you would like to use. Feel free to customize the formulations. In our paper we considered
the Type 4 formulation in great detail, but we have included the code for all of the formulations dicussed in the paper here. For instance,
if you would like to create lineups without stacking, change one_lineup_Type_4 below to one_lineup_no_stacking
=#
formulation = one_lineup_Type_4
function create_lineups(num_lineups, num_overlap, path_hitters, path_pitchers, formulation, path_to_output)
#=
num_lineups is an integer that is the number of lineups
num_overlap is an integer that gives the overlap between each lineup
path_hitters is a string that gives the path to the hitters csv file
path_pitchers is a string that gives the path to the pitchers csv file
formulation is the type of formulation you would like to use (for instance one_lineup_Type_1, one_lineup_Type_2, etc.)
path_to_output is a string where the final csv file with your lineups will be
=#
# Load information for hitters table
hitters = CSV.read(path_hitters, DataFrames.DataFrame)
# Load information for pitchers table
pitchers = CSV.read(path_pitchers, DataFrames.DataFrame)
# Number of hitters
num_hitters = size(hitters)[1]
# Number of pitchers
num_pitchers = size(pitchers)[1]
# catchers stores the information on which players are catchers
catcher = Int64[]
# first baseman stores the information on which players are first baseman
first_baseman = Int64[]
# second baseman stores the information on which players are second baseman
second_baseman = Int64[]
# third baseman stores the information on which players are third baseman
third_baseman = Int64[]
# shortstop stores the information on which players are shortsops
shortstop = Int64[]
# outfielders stores the information on which players are outfielders
outfielders = Int64[]
#=
Process the position information in the hitters file to populate C, 1B, 2B, 3B, SS & OF's with the
corresponding correct information
=#
for i =1:num_hitters
if hitters[i,:Position] == "C"
catcher=vcat(catcher,fill(1,1))
first_baseman=vcat(first_baseman,fill(0,1))
second_baseman=vcat(second_baseman,fill(0,1))
third_baseman=vcat(third_baseman,fill(0,1))
shortstop=vcat(shortstop,fill(0,1))
outfielders=vcat(outfielders,fill(0,1))
elseif hitters[i,:Position] == "1B"
catcher=vcat(catcher,fill(1,1))
first_baseman=vcat(first_baseman,fill(0,1))
second_baseman=vcat(second_baseman,fill(0,1))
third_baseman=vcat(third_baseman,fill(0,1))
shortstop=vcat(shortstop,fill(0,1))
outfielders=vcat(outfielders,fill(0,1))
elseif hitters[i,:Position] == "2B"
catcher=vcat(catcher,fill(0,1))
first_baseman=vcat(first_baseman,fill(0,1))
second_baseman=vcat(second_baseman,fill(1,1))
third_baseman=vcat(third_baseman,fill(0,1))
shortstop=vcat(shortstop,fill(0,1))
outfielders=vcat(outfielders,fill(0,1))
elseif hitters[i,:Position] == "3B"
catcher=vcat(catcher,fill(0,1))
first_baseman=vcat(first_baseman,fill(0,1))
second_baseman=vcat(second_baseman,fill(0,1))
third_baseman=vcat(third_baseman,fill(1,1))
shortstop=vcat(shortstop,fill(0,1))
outfielders=vcat(outfielders,fill(0,1))
elseif hitters[i,:Position] == "SS"
catcher=vcat(catcher,fill(0,1))
first_baseman=vcat(first_baseman,fill(0,1))
second_baseman=vcat(second_baseman,fill(0,1))
third_baseman=vcat(third_baseman,fill(0,1))
shortstop=vcat(shortstop,fill(1,1))
outfielders=vcat(outfielders,fill(0,1))
else
catcher=vcat(catcher,fill(0,1))
first_baseman=vcat(first_baseman,fill(0,1))
second_baseman=vcat(second_baseman,fill(0,1))
third_baseman=vcat(third_baseman,fill(0,1))
shortstop=vcat(shortstop,fill(0,1))
outfielders=vcat(outfielders,fill(1,1))
end
end
catcher = catcher+first_baseman
# Create team indicators from the information in the hitters file
teams = unique(hitters[!, :Team])
# Total number of teams
num_teams = size(teams)[1]
# player_info stores information on which team each player is on
player_info = zeros(Int, size(teams)[1])
# Populate player_info with the corresponding information
for j=1:size(teams)[1]
if hitters[1, :Team] == teams[j]
player_info[j] =1
end
end
hitters_teams = player_info'
for i=2:num_hitters
player_info = zeros(Int, size(teams)[1])
for j=1:size(teams)[1]
if hitters[i, :Team] == teams[j]
player_info[j] =1
end
end
hitters_teams = vcat(hitters_teams, player_info')
end
# Create pitcher identifiers so you know who they are playing
opponents = pitchers[!, :Opponent]
pitchers_teams = pitchers[!, :Team]
pitchers_opponents=[]
for num = 1:size(teams)[1]
if opponents[1] == teams[num]
pitchers_opponents = hitters_teams[:, num]
end
end
for num = 2:size(opponents)[1]
for num_2 = 1:size(teams)[1]
if opponents[num] == teams[num_2]
pitchers_opponents = hcat(pitchers_opponents, hitters_teams[:,num_2])
end
end
end
# Lineups using formulation as the stacking type
the_lineup= formulation(hitters, pitchers, hcat(zeros(Int, num_hitters + num_pitchers), zeros(Int, num_hitters + num_pitchers)), num_overlap, num_hitters, num_pitchers, catcher, first_baseman, second_baseman, third_baseman, shortstop, outfielders, num_teams, hitters_teams, pitchers_opponents)
the_lineup2 = formulation(hitters, pitchers, hcat(the_lineup, zeros(Int, num_hitters + num_pitchers)), num_overlap, num_hitters, num_pitchers, catcher, first_baseman, second_baseman, third_baseman, shortstop, outfielders, num_teams, hitters_teams, pitchers_opponents)
tracer = hcat(the_lineup, the_lineup2)
for i=1:(num_lineups-2)
try
thelineup=formulation(hitters, pitchers, tracer, num_overlap, num_hitters, num_pitchers, catcher, first_baseman, second_baseman, third_baseman, shortstop, outfielders, num_teams, hitters_teams, pitchers_opponents)
tracer = hcat(tracer,thelineup)
catch
break
end
end
# Create the output csv file
lineup2 = ""
for j = 1:size(tracer)[2]
lineup = ["" "" "" "" "" "" "" "" ""]
for i =1:num_hitters
if tracer[i,j] == 1
if catcher[i]==1
if lineup[2]==""
lineup[2] = string(hitters[i,1])
elseif lineup[9] ==""
lineup[9] = string(hitters[i,1])
end
elseif first_baseman[i] == 1
if lineup[2] == ""
lineup[2] = string(hitters[i,1])
elseif lineup[9] == ""
lineup[9] = string(hitters[i,1])
end
elseif second_baseman[i] == 1
if lineup[3] == ""
lineup[3] = string(hitters[i,1])
elseif lineup[9] == ""
lineup[9] = string(hitters[i,1])
end
elseif third_baseman[i] == 1
if lineup[4] == ""
lineup[4] = string(hitters[i,1])
elseif lineup[9] == ""
lineup[9] = string(hitters[i,1])
end
elseif shortstop[i] == 1
if lineup[5] == ""
lineup[5] = string(hitters[i,1])
elseif lineup[9] == ""
lineup[9] = string(hitters[i,1])
end
elseif outfielders[i] == 1
if lineup[6] == ""
lineup[6] = string(hitters[i,1])
elseif lineup[7] == ""
lineup[7] = string(hitters[i,1])
elseif lineup[8] == ""
lineup[8] = string(hitters[i,1])
elseif lineup[9] == ""
lineup[9] = string(hitters[i,1])
end
end
end
end
for i =1:num_pitchers
if tracer[num_hitters+i,j] == 1
lineup[1] = string(pitchers[i,1])
end
end
for name in lineup
lineup2 = string(lineup2, name, ",")
end
lineup2 = chop(lineup2)
lineup2 = string(lineup2, """
""")
end
outfile = open(path_to_output, "w")
write(outfile, lineup2)
close(outfile)
end
# Running the code
create_lineups(num_lineups, num_overlap, path_hitters, path_pitchers, formulation, path_to_output)
UndefVarError: i not defined
Stacktrace:
[1] macro expansion
# ~/.julia/packages/MutableArithmetics/0Y9ZS/src/rewrite.jl:279 [inlined]
[2] macro expansion
# ~/.julia/packages/JuMP/klrjG/src/macros.jl:676 [inlined]
[3] one_lineup_Type_4(hitters::DataFrame, pitchers::DataFrame, lineups::Matrix{Int64}, num_overlap::Int64, num_hitters::Int64, num_pitchers::Int64, catcher::Vector{Int64}, first_baseman::Vector{Int64}, second_baseman::Vector{Int64}, third_baseman::Vector{Int64}, shortstop::Vector{Int64}, outfielders::Vector{Int64}, num_teams::Int64, hitters_teams::Matrix{Int64}, pitchers_opponents::Matrix{Int64})
# Main ./In[30]:24
[4] create_lineups(num_lineups::Int64, num_overlap::Int64, path_hitters::String, path_pitchers::String, formulation::typeof(one_lineup_Type_4), path_to_output::String)
# Main ./In[30]:265
[5] top-level scope
# In[30]:348
[6] eval
# ./boot.jl:373 [inlined]
[7] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
# Base ./loading.jl:1196
The correct syntax is
sum(pitchers_lineup[i] for i=1:num_pitchers)
Note the for, not a comma.
I'm trying to use Julia to solve the common tile game 15 Puzzle using Julia using A* algorithm. I am quite new to the language and my style may seem very C like. When I try the following code, I run out of memory. I'm not sure if its related to the use of a pointer style in my structs or just bad design.
struct Node
parent
f::Int64
board::Array{Int64,1}
end
function findblank(A::Array{Int64,1})
x = size(A,1)
for i = 1:x
if A[i] == x
return i
end
end
return -1
end
function up(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
blank = findblank(A)
B = copy(A)
if blank / Nsq <= 1
return nothing
end
B[blank-Nsq],B[blank] = B[blank],B[blank-Nsq]
return B
end
function down(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
blank = findblank(A)
B = copy(A)
if (blank / Nsq) > (Nsq -1)
return nothing
end
B[blank+Nsq],B[blank] = B[blank],B[blank+Nsq]
return B
end
function left(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
blank = findblank(A)
B = copy(A)
if (blank % Nsq) == 1
return nothing
end
B[blank-1],B[blank] = B[blank],B[blank-1]
return B
end
function right(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
blank = findblank(A)
B = copy(A)
if (blank % Nsq) == 0
return nothing
end
B[blank+1],B[blank] = B[blank],B[blank+1]
return B
end
function manhattan(A::Array{Int64,1})
N = size(A,1)
Nsq = isqrt(N)
r = 0
for i in 1:N
if (A[i]==i || A[i]==N)
continue
end
row1 = floor((A[i]-1) / Nsq)
col1 = (A[i]-1) % Nsq
row2 = floor((i-1) / Nsq)
col2 = (i-1) % Nsq
r+= abs(row1 - row2) + abs(col1 - col2)
end
return r
end
# start = [1,2,3,4,5,6,7,9,8]
# start = [6,5,4,1,7,3,9,8,2] #26 moves
start = [7,8,4,11,12,14,10,15,16,5,3,13,2,1,9,6] # 50 moves
goal = [x for x in 1:length(start)]
# println("The manhattan distance of $start is $(manhattan(start))")
g = 0
f = g + manhattan(start)
pq = PriorityQueue()
actions = [up,down,left,right]
dd = Dict{Array{Int64,1},Int64}()
snode = Node(C_NULL,f,start)
enqueue!(pq,snode,f)
pos_seen = 0
moves = 0
while (!isempty(pq))
current = dequeue!(pq)
if haskey(dd,current.board)
continue
else
push!(dd, current.board =>current.f)
end
if (current.board == goal)
while(current.board != start)
println(current.board)
global moves +=1
current = current.parent[]
end
println(start)
println("$start solved in $moves moves after looking at $pos_seen positions")
break
end
global pos_seen+=1
global g+=1
for i in 1:4
nextmove = actions[i](current.board)
if (nextmove === nothing || nextmove == current.board || haskey(dd,nextmove))
continue
else
global f = g+manhattan(nextmove)
n = Node(Ref(current),f,nextmove)
enqueue!(pq,n,f)
end
end
end
println("END")
I am working on a project for my Visual Basic class, which is to create a digital check. The assignment requires us to input a check amount, which translates into words. In example, $1,200.00 needs to output "One thousand two hundred dollars"
For the most part, my code works. I'm using a switch statement. The original assignment was to have our check go up to a 9,999 value, but as we continue to build, we need to be able to convert up to 99,999.
As I said, I've been using a series of case statements, but realize that this is a very "hard code" way of doing this and would like create a method that can check these type of things for me, however I'm still new to Visual Basic and don't really have a good idea where to start or what is applicable in this scenario (we don't really have an example to go by.)
Here is my WriteCheck method that does the assigning/converting for the most part.
'Convert check value from a text field to a double'
Try
checkValue = checkInput.Text
Catch ex As InvalidCastException
MessageBox.Show("You must enter a numbers to write a check.")
End Try
'Operation to convert number to String'
thousands = checkValue \ 1000
hundreds = checkValue Mod 1000
hundreds = hundreds \ 100
tens = checkValue Mod 100
tens = tens \ 10
ones = checkValue Mod 10
ones = ones \ 1
'Case for thousands'
Select Case thousands & hundreds & tens
Case 1
tempStringT = "One"
Case 2
tempStringT = "Two"
Case 3
tempStringT = "Three"
Case 4
tempStringT = "Four"
Case 5
tempStringT = "Five"
Case 6
tempStringT = "Six"
Case 7
tempStringT = "Seven"
Case 8
tempStringT = "Eight"
Case 9
tempStringT = "Nine"
End Select
'Case for hundreds'
Select Case hundreds
Case 1
tempStringH = "one"
Case 2
tempStringH = "two"
Case 3
tempStringH = "three"
Case 4
tempStringH = "four"
Case 5
tempStringH = "five"
Case 6
tempStringH = "six"
Case 7
tempStringH = "seven"
Case 8
tempStringH = "eight"
Case 9
tempStringH = "nine"
End Select
'Case for tens'
Select Case tens Or ones
Case 1
tempStringTens = "one"
Case 2
tempStringTens = "twenty"
Case 3
tempStringTens = "thirty"
Case 4
tempStringTens = "fourty"
Case 5
tempStringTens = "fifty"
Case 6
tempStringTens = "sixty"
Case 7
tempStringTens = "seventy"
Case 8
tempStringTens = "eighty"
Case 9
tempStringTens = "ninety"
End Select
If tempStringTens <> "one" Then
'Case for ones'
Select Case ones
Case 1
tempStringO = "one"
Case 2
tempStringO = "two"
Case 3
tempStringO = "three"
Case 4
tempStringO = "four"
Case 5
tempStringO = "five"
Case 6
tempStringO = "six"
Case 7
tempStringO = "seven"
Case 8
tempStringO = "eight"
Case 9
tempStringO = "nine"
End Select
lblConverted.Text = tempStringT & " thousand " & tempStringH & " hundred " & tempStringTens & " " & tempStringO & " dollars " & change & "/100"
End If
If tempStringTens = "one" Then
Select Case ones
Case 1
tempStringO = "eleven"
Case 2
tempStringO = "twelve"
Case 3
tempStringO = "thirteen"
Case 4
tempStringO = "fourteen"
Case 5
tempStringO = "fifteen"
Case 6
tempStringO = "sixteen"
Case 7
tempStringO = "seventeen"
Case 8
tempStringO = "eighteen"
Case 9
tempStringO = "nineteen"
End Select
lblConverted.Text = tempStringT & " thousand " & tempStringH & " hundred " & tempStringO & " dollars"
End If
End Sub
This is my approach to the problem. The solution can be easily scaled up or down by adding or removing items in BigNumbers and upping the scope of num beyond Long if necessary. (As written, it will work for numbers up to 999,999,999,999,999.)
Public Function NumberToText(ByVal num As Long) As String
Dim BigNumbers() As String = {"", " Thousand", " Million", " Billion", " Trillion"}
Dim TextParts() As String = {}
If num < 0 Then
Return "Checks cannot be written for negative amounts."
ElseIf num >= 10 ^ ((BigNumbers.Length) * 3) Then
Return "This number exceeds the current maximum value of " & NumberToText(10 ^ ((BigNumbers.Length) * 3) - 1) & "."
End If
Dim LoopCount As Integer = 0
While num >= 1000
ReDim Preserve TextParts(TextParts.Length)
If num Mod 1000 > 0 Then
TextParts(TextParts.GetUpperBound(0)) = ThreeDigitText(num Mod 1000) & BigNumbers(LoopCount)
End If
num = num \ 1000
LoopCount += 1
End While
ReDim Preserve TextParts(TextParts.Length)
TextParts(TextParts.GetUpperBound(0)) = ThreeDigitText(num) & BigNumbers(LoopCount)
If Array.IndexOf(TextParts, "Error") > -1 Then
Return "An unknown error occurred while converting this number to text."
Else
Array.Reverse(TextParts)
Return Join(TextParts)
End If
End Function
Private Function ThreeDigitText(ByVal num As Integer) As String
If num > 999 Or num < 0 Then
Return "Error"
Else
Dim h As Integer = num \ 100 'Hundreds place
Dim tempText As String = ""
If h > 0 Then
tempText = OneDigitText(h) & " Hundred"
End If
num -= h * 100
If num > 0 And Not tempText = "" Then
tempText &= " "
End If
If num > 9 And num < 20 Then
Dim DoubleDigits() As String = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}
Return tempText & DoubleDigits(num - 10)
Else
Dim TensPlace() As String = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}
Dim t As Integer = num \ 10 'Tens place
num -= t * 10
If t > 1 Then
tempText &= TensPlace(t - 2)
If num > 0 Then
tempText &= " "
End If
End If
If num > 0 Then
tempText &= OneDigitText(num)
End If
Return tempText
End If
End If
End Function
Private Function OneDigitText(ByVal num As Integer) As String
If num > 9 Or Num < 0 Then
Return "Error"
Else
Dim SingleDigits() As String = {"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"}
Return SingleDigits(num)
End If
End Function
Since this is for school, you will probably want to adapt parts of my code to your own rather than copy the whole thing. (Teachers can usually tell when you get code off the internet, especially if you can't explain every line.) If you have any questions about it, send them to the email listed in my profile.