Related
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 have the following test module (MyMod.jl) to store some test functions in Julia. Some of the core functions are written in serial. Other functions call the core functions in parallel.
module MyMod
export Dummy,distribute_data,getfrom,recombine_data,regular_test,parallel_test
function Dummy(icol,model,data,A,B) # Generate data from a model
nz,nx,nh = size(model) # = size(A) = size(B)
for ih = 1:nh
for ix = 1:nx
for iz = 1:nz
data[iz,icol] += A[iz,ix,ih]*B[iz,ix,ih]*model[iz,ix,ih]
end
end
end
end
function distribute_data(X, obj_name_on_worker::Symbol, dim) # Distributes X over workers
size_per_worker = floor(Int,size(X,1) / nworkers())
StartIdx = 1
EndIdx = size_per_worker
for (idx, pid) in enumerate(workers())
if idx == nworkers()
EndIdx = size(X,1)
end
println(StartIdx:EndIdx)
if dim == 3
#spawnat(pid, eval(Main, Expr(:(=), obj_name_on_worker, X[StartIdx:EndIdx,:,:])))
elseif dim == 2
#spawnat(pid, eval(Main, Expr(:(=), obj_name_on_worker, X[StartIdx:EndIdx,:])))
end
StartIdx = EndIdx + 1
EndIdx = EndIdx + size_per_worker - 1
end
end
getfrom(p::Int, nm::Symbol; mod=Main) = fetch(#spawnat(p, getfield(mod, nm)))
function recombine_data(Data::Symbol) # gather data from workers
Results = cell(nworkers())
for (idx, pid) in enumerate(workers())
Results[idx] = getfrom(pid, Data)
end
return vcat(Results...)
end
function regular_test(model,data,A,B)
ncol=size(data,2)
map((arg)->Dummy(arg,model,data,A,B),[icol for icol = 1:ncol])
end
function parallel_test(model,data,A,B)
distribute_data(model, :model, 3)
distribute_data(A, :A, 3)
distribute_data(B, :B, 3)
distribute_data(data, :data, 2)
#everywhere ncol=size(data,2)
#everywhere begin
if myid() != 1
map((arg)->Dummy(arg,model,data,A,B),[icol for icol = 1:ncol])
end
end
P_Data = recombine_data(:data)
return P_Data
end
end
I then open a Julia session and run:
addprocs(3)
using MyMod
nx = 250;
nz = 350;
nh = 150;
ncol = 125;
model = rand(nz,nx,nh);
data = SharedArray(Float64,nz,ncol);
A = rand(nz,nx,nh);
B = rand(nz,nx,nh);
#time P_Data = parallel_test(model,data,A,B);
#time regular_test(model,data,A,B);
P_Data == data
The regular_test runs as expected, but parallel_test produces the following error:
ERROR: On worker 2:
UndefVarError: Dummy not defined
in anonymous at /home/username/Desktop/MyMod.jl:58
in map at ./essentials.jl:153
in anonymous at /home/username/Desktop/MyMod.jl:58
in eval at ./sysimg.jl:14
in anonymous at multi.jl:1378
in anonymous at multi.jl:907
in run_work_thunk at multi.jl:645
[inlined code] from multi.jl:907
in anonymous at task.jl:63
in remotecall_fetch at multi.jl:731
in remotecall_fetch at multi.jl:734
in anonymous at multi.jl:1380
...and 2 other exceptions.
in sync_end at ./task.jl:413
[inlined code] from multi.jl:1389
in parallel_test at /home/username/Desktop/MyMod.jl:51
What adjustment do I need to make to parallel_test to prevent this issue?
Here, you just need to use:
addprocs(3) ## or, starting with julia -p 3 does the same
#everywhere using MyMod
I'm trying to plot a function of two variables with pyplot in Julia. The working starting-point is the following (found here at StackOverflow):
function f(z,t)
return z*t
end
z = linspace(0,5,11)
t = linspace(0,40,4)
for tval in t
plot(z, f(z, tval))
end
show()
This works right for me and is giving me exactly what I wanted:
a field of lines.
My own functions are as follows:
## needed functions ##
const gamma_0 = 6
const Ksch = 1.2
const Kver = 1.5
function Kvc(vc)
if vc <= 0
return 0
elseif vc < 20
return (100/vc)^0.1
elseif vc < 100
return 2.023/(vc^0.153)
elseif vc == 100
return 1
elseif vc > 100
return 1.380/(vc^0.07)
else
return 0
end
end
function Kgamma(gamma_t)
return 1-((gamma_t-gamma_0)/100)
end
function K(gamma_t, vc)
return Kvc(vc)*Kgamma(gamma_t)*Ksch*Kver
end
I've tried to plot them as follows:
i = linspace(0,45,10)
j = linspace(0,200,10)
for i_val in i
plot(i,K(i,j))
end
This gives me the following Error:
isless has no method matching isless(::Int64, ::Array{Float64,1})
while loading In[51], in expression starting on line 3
in Kvc at In[17]:2 in anonymous at no file:4
Obviously, my function cant deal with an array.
Next try:
i = linspace(0,200,11)
j = linspace(0,45,11)
for i_val in i
plot(i_val,map(K,i_val,j))
end
gives me a empty plot only with axes
Can anybody please give me a hint...
EDIT
A simpler example:
using PyPlot
function P(n,M)
return (M*n^3)/9550
end
M = linspace(1,5,5)
n = linspace(0,3000,3001)
for M_val in M
plot(n,P(n,M_val))
end
show()
Solution
OK, with your help I found this solution for the shortened example which works for me as intended:
function P(n,M)
result = Array(Float64, length(n))
for (idx, val) in enumerate(n)
result[idx] = (M*val^3)/9550
end
return result
end
n = linspace(0,3000,3001)
for M_val = 1:5
plot(n,P(n,M_val))
end
show()
This gives me what I wanted for this shortened example. The remainig question is: could it be done in a simpler more elegant way?
I'll try to apply it to the original example and post it when I'll succed.
I don't completely follow all the details of what you're trying to accomplish, but here are examples on how you can modify a couple of your functions so that they accept and return arrays:
function Kvc(vc)
result = Array(Float64, length(vc))
for (idx, val) in enumerate(vc)
if val <= 0
result[idx] = 0
elseif val < 20
result[idx] = (100/val)^0.1
elseif val < 100
result[idx] = 2.023/(val^0.153)
elseif val == 100
result[idx] = 1
elseif val > 100
result[idx] = 1.380/(val^0.07)
else
result[idx] = 0
end
end
return result
end
function Kgamma(gamma_t)
return ones(length(gamma_t))-((gamma_t - gamma_0)/100)
end
Also, for your loop, I think you probably want something like:
for i_val in i
plot(i_val,K(i_val,j))
end
rather than plot(i, K(i,j), as that would just print the same thing over and over.
< is defined for scalars. I think you need to broadcast it for arrays, i.e. use .<. Example:
julia> x = 2
2
julia> x < 3
true
julia> x < [3 4]
ERROR: MethodError: no method matching isless(::Int64, ::Array{Int64,2})
Closest candidates are:
isless(::Real, ::AbstractFloat)
isless(::Real, ::Real)
isless(::Integer, ::Char)
in <(::Int64, ::Array{Int64,2}) at .\operators.jl:54
in eval(::Module, ::Any) at .\boot.jl:234
in macro expansion at .\REPL.jl:92 [inlined]
in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at .\event.jl:46
julia> x .< [3 4]
1x2 BitArray{2}:
true true
Inherited a VB website and am new to vb programming, so steep learning curve.
I have a site that searches and list all currently available cars in the UK for a leasing company.
the vehicle data is provided by an external comapany and links all the tech specs etc and images to a keyID. However...
If the vehicle has not been assigned an image it is not counted or displayed. I want to add an IF statement so that if the ImageId is Null then it will display a default 'awaiting image' jpg and would therefore still be listed to the public.
the page is http://www.carmyke.co.uk/search_prices.aspx with the 'Vans' dropping the most from the list.
I have included the code I think I need to update.
I think I need an IF statement for the .ImageId that if the SQL returns NULL then it uses a default image located in the same folder as defined by the appsettings
Hope this makes sense!?
<--- THE CODE --->
#Region "Methods"
Private Function GetVehicle(ByVal SearchBy As SearchBy, _
ByVal SearchText As String) As Data.LeasingPrices.Vehicle
Dim _Vehicle As New Data.LeasingPrices.Vehicle
Try
Dim _SQL As New Net.SQL
_SQL.AppendSQL("SELECT TOP 1 * ")
_SQL.AppendSQL("FROM vw_carmyke_Rates_Business ")
_SQL.AppendSQL("LEFT OUTER JOIN carmyke_SpecialOffers ON vw_carmyke_Rates_Business.CVehicleId = carmyke_SpecialOffers.CVehicleId ")
Select Case SearchBy
Case Hydrate.SearchBy.Make
_SQL.AppendSQL("WHERE Make = #SearchText ")
Case Hydrate.SearchBy.Model
_SQL.AppendSQL("WHERE MakeModel = #SearchText ")
Case Hydrate.SearchBy.Derivative
_SQL.AppendSQL("WHERE MakeModelDerivative = #SearchText ")
End Select
_SQL.AppendSQL("ORDER BY Rental_48_40;")
_SQL.AddParameter("#SearchText", SearchText, SqlDbType.VarChar)
_SQL.ConnectReader()
If _SQL.Validation.NoErrors Then
If _SQL.Reader.Read() Then
With _Vehicle
.CVehicleId = _SQL.Reader.SQLString("CVehicleId").ToInteger()
.Van = _SQL.Reader.SQLString("BodyStyle").Contains("Van")
.Make = _SQL.Reader.SQLString("Make")
.Model = _SQL.Reader.SQLString("Model")
.Derivative = _SQL.Reader.SQLString("Derivative")
.ImageId = _SQL.Reader.SQLString("ImageId") & ".jpg"
.Co2 = _SQL.Reader.SQLString("Co2").ToInteger()
.P11d = _SQL.Reader.SQLString("P11d").ToDouble()
.Business = _SQL.Reader.SQLString("Business").ToBoolean()
.Personal = _SQL.Reader.SQLString("Personal").ToBoolean()
.Details = _SQL.Reader.SQLString("Details")
.OfferPrice = _SQL.Reader.SQLString("OfferPrice").ToDouble()
If .OfferPrice = 0 Then _
.OfferPrice = _SQL.Reader.SQLString("Offer_48_40").ToDouble()
If .OfferPrice = 0 Then _
.OfferPrice = _SQL.Reader.SQLString("Rental_48_40").ToDouble()
.Commercial = _SQL.Reader.SQLString("Commercial").ToBoolean()
.Offer_24_20 = _SQL.Reader.SQLString("Offer_24_20").ToDouble()
.Offer_24_40 = _SQL.Reader.SQLString("Offer_24_40").ToDouble()
.Offer_24_60 = _SQL.Reader.SQLString("Offer_24_60").ToDouble()
.Offer_36_30 = _SQL.Reader.SQLString("Offer_36_30").ToDouble()
.Offer_36_60 = _SQL.Reader.SQLString("Offer_36_60").ToDouble()
.Offer_36_90 = _SQL.Reader.SQLString("Offer_36_90").ToDouble()
.Offer_48_40 = _SQL.Reader.SQLString("Offer_48_40").ToDouble()
.Offer_48_80 = _SQL.Reader.SQLString("Offer_48_80").ToDouble()
.Offer_48_120 = _SQL.Reader.SQLString("Offer_48_120").ToDouble()
If .Offer_24_20 = -1 Then
.Rental_24_20 = 0
ElseIf .Offer_24_20 > 0 Then
.Rental_24_20 = .Offer_24_20
Else
.Rental_24_20 = _SQL.Reader.SQLString("Rental_24_20").ToDouble()
End If
If .Offer_24_40 = -1 Then
.Rental_24_40 = 0
ElseIf .Offer_24_40 > 0 Then
.Rental_24_40 = .Offer_24_40
Else
.Rental_24_40 = _SQL.Reader.SQLString("Rental_24_40").ToDouble()
End If
If .Offer_24_60 = -1 Then
.Rental_24_60 = 0
ElseIf .Offer_24_60 > 0 Then
.Rental_24_60 = .Offer_24_60
Else
.Rental_24_60 = _SQL.Reader.SQLString("Rental_24_60").ToDouble()
End If
If .Offer_36_30 = -1 Then
.Rental_36_30 = 0
ElseIf .Offer_36_30 > 0 Then
.Rental_36_30 = .Offer_36_30
Else
.Rental_36_30 = _SQL.Reader.SQLString("Rental_36_30").ToDouble()
End If
If .Offer_36_60 = -1 Then
.Rental_36_60 = 0
ElseIf .Offer_36_60 > 0 Then
.Rental_36_60 = .Offer_36_60
Else
.Rental_36_60 = _SQL.Reader.SQLString("Rental_36_60").ToDouble()
End If
If .Offer_36_90 = -1 Then
.Rental_36_90 = 0
ElseIf .Offer_36_90 > 0 Then
.Rental_36_90 = .Offer_36_90
Else
.Rental_36_90 = _SQL.Reader.SQLString("Rental_36_90").ToDouble()
End If
If .Offer_48_40 = -1 Then
.Rental_48_40 = 0
ElseIf .Offer_48_40 > 0 Then
.Rental_48_40 = .Offer_48_40
Else
.Rental_48_40 = _SQL.Reader.SQLString("Rental_48_40").ToDouble()
End If
If .Offer_48_80 = -1 Then
.Rental_48_80 = 0
ElseIf .Offer_48_80 > 0 Then
.Rental_48_80 = .Offer_48_80
Else
.Rental_48_80 = _SQL.Reader.SQLString("Rental_48_80").ToDouble()
End If
If .Offer_48_120 = -1 Then
.Rental_48_120 = 0
ElseIf .Offer_48_120 > 0 Then
.Rental_48_120 = .Offer_48_120
Else
.Rental_48_120 = _SQL.Reader.SQLString("Rental_48_120").ToDouble()
End If
End With
Else
_Vehicle = Nothing
End If
Else
_Vehicle = Nothing
End If
_SQL.DisconnectReader()
Catch
_Vehicle = Nothing
End Try
Return _Vehicle
End Function
Public Function Vehicle(ByVal SearchText As String) As Data.LeasingPrices.Vehicle
Dim _Vehicle As New Data.LeasingPrices.Vehicle
_Vehicle = GetVehicle(Hydrate.SearchBy.Derivative, SearchText)
If _Vehicle Is Nothing Then
_Vehicle = GetVehicle(Hydrate.SearchBy.Model, SearchText)
End If
If _Vehicle Is Nothing Then
_Vehicle = GetVehicle(Hydrate.SearchBy.Make, SearchText)
End If
Return _Vehicle
End Function
Private Function GetSearchOption(ByVal SearchOption As String) As String
Dim _GetSearchOption As String = ""
Try
If Not HttpContext.Current.Session(SearchOption) Is Nothing Then _
_GetSearchOption = HttpContext.Current.Session(SearchOption)
Catch
_GetSearchOption = ""
End Try
Return _GetSearchOption
End Function
Public Function SearchOptions() As Data.LeasingPrices.SearchOptions
Dim _SearchOptions As New Data.LeasingPrices.SearchOptions
Try
With _SearchOptions
.FourByFour = GetSearchOption("FourByFour").ToBoolean()
.CityCar = GetSearchOption("CityCar").ToBoolean()
.Coupe = GetSearchOption("Coupe").ToBoolean()
.Estate = GetSearchOption("Estate").ToBoolean()
.Hatchback = GetSearchOption("Hatchback").ToBoolean()
.MPV = GetSearchOption("MPV").ToBoolean()
.Saloon = GetSearchOption("Saloon").ToBoolean()
.Sports = GetSearchOption("Sports").ToBoolean()
.Van = GetSearchOption("Van").ToBoolean()
.RentalFrom = GetSearchOption("RentalFrom").ToInteger()
.RentalTo = GetSearchOption("RentalTo").ToInteger()
If .RentalFrom = 0 And .RentalTo = 0 Then
.RentalFrom = Data.LeasingPrices.SearchOptions.DefaultRentalFrom
.RentalTo = Data.LeasingPrices.SearchOptions.DefaultRentalTo
End If
End With
Catch
_SearchOptions = Nothing
End Try
Return _SearchOptions
End Function
#End Region
#Region "Constructors"
Public Sub New()
End Sub
#End Region
End Class
End Namespace
I'm not familiar with the Net.SQL entity you're using, but it is usual to use something like the Convert.IsDBNull Method to check for a NULL database value.
An alternative is to use COALESCE in the query, like
SELECT TOP 1 [CVehicleId], ..more columns.., COALESCE([ImageId], 'AwaitingImage'), ..remaining columns..
You should really explicitly specify the columns, and put the column names in square brackets so that if you accidentally have a column name which happens to be an SQL keyword then it doesn't mistake it for a keyword.
This question already has answers here:
method for serializing lua tables
(5 answers)
Closed 8 years ago.
I would like to serialize a table so that I can insert it into a database and retrieve it later on. How would I do this?
maybe like this https://gist.github.com/rangercyh/5814003
local szStr = ""
function print_lua_table (lua_table, indent)
indent = indent or 0
for k, v in pairs(lua_table) do
if type(k) == "string" then
k = string.format("%q", k)
end
local szSuffix = ""
if type(v) == "table" then
szSuffix = "{"
end
local szPrefix = string.rep(" ", indent)
formatting = szPrefix.."["..k.."]".." = "..szSuffix
if type(v) == "table" then
szStr = szStr..formatting
print_lua_table(v, indent + 1)
szStr = szStr..szPrefix.."},"
else
local szValue = ""
if type(v) == "string" then
szValue = string.format("%q", v)
else
szValue = tostring(v)
end
szStr = szStr..formatting..szValue..","
end
end
end
How to serialize Lua value nicely?
local serialize
do
local num_fmt = '%.17g'
local NaN_serialized = { -- This idea was stolen from lua-nucleo
[num_fmt:format(1/0)] = '1/0',
[num_fmt:format(-1/0)] = '-1/0',
[num_fmt:format(0/0)] = '0/0'
}
local function serialize_table(t, indent)
indent = indent or ''
local new_indent = indent..'\t'
if next(t) == nil then
return '{}'
else
local lines = {}
local function add_line(key)
local ser_key = key
if type(key) ~= 'string' or not key:find'^[%a_][%w_]*$' then
ser_key = '['..serialize(key, new_indent)..']'
end
table.insert(lines,
ser_key..' = '..serialize(t[key], new_indent))
end
local other_keys = {}
local keys = setmetatable({number = {}, string = {}},
{__index = function() return other_keys end})
for k in pairs(t) do
table.insert(keys[type(k)], k)
end
table.sort(keys.number)
table.sort(keys.string)
for _, k in ipairs(keys.number) do
add_line(k)
end
for _, k in ipairs(keys.string) do
add_line(k)
end
for _, k in ipairs(other_keys) do
add_line(k)
end
return '{\n'..new_indent..table.concat(lines, ',\n'..new_indent)
..'\n'..indent..'}'
end
end
function serialize(v, indent)
if type(v) == 'string' then
return ('%q'):format(v)
elseif type(v) == 'boolean' then
return tostring(v)
elseif type(v) == 'nil' then
return tostring(v)
elseif type(v) == 'number' then
return (num_fmt:format(v):gsub('^.*', NaN_serialized))
elseif type(v) == 'table' then
return serialize_table(v, indent)
else
error('Can not serialize '..type(v))
end
end
end
-- What it can:
print(serialize(math.huge))
print(serialize'"What\'s up?"\n\t123')
print(serialize{{}, {{}}})
-- And what it can not:
local t = {}
local tt = {[t] = t}
print(serialize(tt)) -- tt is not a tree, so it was serialized incorrectly