-
Ruben Haag authoredRuben Haag authored
script_fmax.jl 5.30 KiB
#Julia 1.6.2
#RidePooling 0.8.2
using RidePooling
using DelimitedFiles
#error function (to be minimized)
function f(x,N,target,t0,specs)
if x < 0
return 1.0
end
model=get_model(;N_bus=N,ν=x/t0,specs...);
#now comes the initial phase that will be skipped for the statistics
run!(model,dropped=10*max(N,100),time=2*t0) #on average, every bus has dropped off >10 users + simulation time 4 times bigger than avrg. direct distance.
startindex=length(model.requests)
run!(model,requested=startindex+20*max(N,100))
res=served_percentage(model,startindex=startindex)-target
if abs(res)>0.5
return res
else
run!(model,requested=startindex+50*max(N,100))
res=served_percentage(model,startindex=startindex)-target
if abs(res)>0.15
return res
else
run!(model,requested=startindex+100*max(N,100))
res=served_percentage(model,startindex=startindex)-target
if abs(res)>0.05
return res
else
run!(model,requested=startindex+200*max(N,100))
return served_percentage(model,startindex=startindex)-target
end
end
end
end
function prnt(x)
println(x)
flush(stdout)
end
percentage=eval(Meta.parse(ARGS[1]))
index=eval(Meta.parse(ARGS[2]))
Ns=unique(Integer.(round.(exp.(range(log(1),log(1000);length=61)))))
N=Ns[index]
target=percentage/100
filepath=pwd()*"/../evaluation/f$(percentage)_$(N).txt"
guesspath=pwd()*"/../evaluation/guess_f$(percentage)_$(N).txt"
map_folder=pwd()*"/../../map/"
include(map_folder*"map.jl")
include(pwd()*"/../dispatcher.jl")
#initiate model
specs=(;
map=map,
route_matrix=RM,
subspaces=:all_edges,
routing=:lookup,
speed_dict=speed_dict,
seed=1
)
specs=merge(specs,dispatcher)
TEST=false
init=1.6*N^1.14
occursin("32",pwd()) ? prnt("map with a 32. init prefactor = 1.6") : nothing
occursin("64",pwd()) ? (init*=2.6/1.6;prnt("map with a 64. init prefactor = 2.6")) : nothing
occursin("128",pwd()) ? (init*=5.5/1.6;prnt("map with a 128. init prefactor = 5.5")) : nothing
while TEST==false
A=init*(0.95+0.1*rand())
prnt("################")
prnt("N = $(N)")
prnt("initial guess A = $(round(A;digits=4))")
prnt("################\n")
fA=f(A,N,target,t0,specs)
prnt("fA=$(round(fA;digits=4))")
if fA>0
prnt("A=$(round(A;digits=4)) too small, B must be larger.")
best_positive=A
best_negative=false
B=A
while best_negative==false
B*=1.1
prnt("Trying B=$(B)")
fB=f(B,N,target,t0,specs)
prnt("fB=$(fB)")
best_negative= fB<0 ? B : false
fB>0 ? ((A,fA)=(B,fB)) : nothing
end
else
prnt("A too large, B must be smaller.")
B,fB=(A,fA)
prnt("Setting B=$(round(A;digits=4)) to maintain the convention that A<B")
best_negative=B
best_positive=false
while best_positive==false
A/=1.1
prnt("Trying A=$(round(A;digits=4))")
fA=f(A,N,target,t0,specs)
prnt("fA=$(round(fA;digits=4))")
best_positive= fA>0 ? A : false
fA<0 ? ((B,fB)=(A,fA)) : nothing
if A<1e-3
prnt("This many buses don't seem to be able to serve $(percentage) percent of any demand. Exiting.")
exit()
end
end
end
iteration=0
while true
if (fA<0.02 && fB>-0.02)
prnt("")
prnt("breaking free after $(iteration) iterations with")
prnt("A=$(round(A;digits=4)), fA=$(round(fA;digits=4))")
prnt("B=$(round(B;digits=4)), fB=$(round(fB;digits=4))")
break
end
iteration+=1
C_mean=(A+B)/2
C_secante=B-fB*(B-A)/(fB-fA)
writedlm(guesspath,C_secante);prnt("\n ..writing $(round(C_secante;digits=4)) (current secante root) to guess_path.")
if fA<0.01
C=(2*C_secante+B)/3
elseif fB>0.01
C=(2*C_secante+A)/3
else
C=(2*C_secante+C_mean)/3
end
fC=f(C,N,target,t0,specs)
prnt("iteration $(iteration)")
prnt("A=$(round(A;digits=4)), fA=$(round(fA;digits=4))")
prnt("B=$(round(B;digits=4)), fB=$(round(fB;digits=4))")
prnt("C=$(round(C;digits=4)), fC=$(round(fC;digits=4))")
if fC>0
A,fA=(C,fC)
else
B,fB=(C,fC)
end
end
C=B-fB*(B-A)/(fB-fA)
writedlm(guesspath,C);prnt(" ..writing $(round(C;digits=4)) (final secante root) to guess_path.")
#find root of parabola
fC=f(C,N,target,t0,specs)
mat=[A^2 A 1;B^2 B 1;C^2 C 1]
a,b,c=inv(mat)*[fA,fB,fC]
p,q=(b/a,c/a)
x1=-p/2-sqrt((p/2)^2-q)
x2=-p/2+sqrt((p/2)^2-q)
C= abs(x1-C)<abs(x2-C) ? x1 : x2
writedlm(guesspath,C);prnt(" ..writing $(round(C;digits=4)) (root of parabola) to guess_path.")
prnt("\nFINAL: $(round(C;digits=4))")
#test served percentage
fFINAL=f(C,N,target,t0,specs)
global TEST=abs(fFINAL)<0.02
prnt("TEST: served percentage = $(round(100*(fFINAL+target);digits=2))%\n\n\n")
if TEST
prnt("test worked.")
writedlm(filepath,C)
else
global init=C
prnt("test failed.")
end
end