Electric Vehicle Routing Path Simulation Giving Wrong Output - python-3.x

My electric vehicle charging algorithm aims at returning the shortest path length by a charging drone. The drone will meet the electric vehicle at a rendezvous point and charge the vehicle. The vehicle selection is done based on the charging urgency of the vehicles. The total path length is calculated when all vehicles are charged based on their urgency. The pseudocode is:
EDF(List_Req)
SunchrgEV = List_Req
Pathlen = 0
Nchgreq = 0
while(SunchrgEV = 0):
U obtains the updated location of all ei element of SunchrgEV via message exchange
S'gcs = set of GCS element of Sgcs
Gr = min {Eucleadian distance between Loc(ei) and Loc(Gj)} //The closest GCS
ex = min [{Eucleadian distance between Loc(ei) and Loc(Gr)}/ResidDist(ei)] // most urgent EV
if SoC(U)<RqB2D(ex) // then U(the drone) itself needs charge and it reports its termination to the server
// the server dispatches another U(drone) to charge the remaining EVs (ei)
Gr = min {Eucleadian distance between Loc(U) and Loc(Gj)} //The closest GCS to U where U goes to full charge
end if
t = tcurrent
// Finding rendezvous point where ex and U meets
RdvLoc = FindRdvLoc(ex, Loc(ex), Loc(U),t)
if RdvLoc is out of service area of U then
Report2server(ex,'Outofservicearea')
continue
end if
Pathlen += Dist2(Loc(U),RdvLoc)
U sends RdvLoc to ex and flies to RdvLoc
if U reaches ex in ChgRng(U) then
{Pathlen += Charge(ex, RdvLoc)
Nchgreq ++
}
else
Report2server(ex, 'Outofservicearea')
endif
SunchrgEV -= ex
do
Update (Loc(U))
Gr = min {Eucleadian distance between Loc(U) and Loc(Gj)} //U returns to Gr
Pathlen += Dist2(Loc(U), Loc(Gr))
return Pathlen and Nchgreq
//Compute the expected location where U meets e on Map(e)
def FindRdvLoc(e,Le,Lu,t):
Compute X = (x,y) on Rte(e,t) so that {Dist(e,X)/Speed(e,t)} = {Dist(U, X-ChgRng(U))/Speed(U)}
return X
def Charge(ei, RdvLoc):
U starts to charge ei and follows Rte(ei,t)
eLoc = FindLoc(Map(ei), Loc(ei), ChgTime(ei), Speed(ei,t))
return DistM(Map(ei), RdvLoc, eLoc)
The code that I have written so far gives the same output regardless of the input. The code is:
import math
import sys
from typing import List, Any
class Location:
x = 0
y = 0
def __init__(self, x, y):
self.x = x
self.y = y
class Result:
path_len: int = 0
n_charge_request: int = 0
def __init__(self, path_len, n_charge_request):
self.path_len = path_len
self.n_charge_request = n_charge_request
def to_string(self):
return "path len : " + str(self.path_len) + ", n_charge_request : " + str(self.n_charge_request)
def print(self):
print(self.to_string())
#SGCs
class ChargingStation:
def __init__(self, location: Location, fuel):
self.location = location
self.fuel = fuel
#EVs(ex)
class Vehicle:
location = Location(0, 0)
fuel = 1
isNeedEmergencyFuel = False
per_fuel_distance_travel = 2
def __init__(self, id, location, fuel):
self.id = id
self.location = location
self.fuel = fuel
# Resid (U)
def residual_distance(self):
return self.fuel * self.per_fuel_distance_travel # assuming each watt or kw fuel will yield to 2 killos or milies
# RqB2D
def requested_amount_of_charge(self, nearest_charge_station_location: Location) -> int:
distance = get_distance(self.location, nearest_charge_station_location)
cover = self.fuel * self.per_fuel_distance_travel
diff = math.fabs(distance - cover)
if diff > 0:
needed_fuel = diff / self.per_fuel_distance_travel + 2
return needed_fuel
return 0
# U(i)
class Drone:
location = Location(0, 0)
fuel = 0
isFlying = False
isSendForEvCharge = False
per_fuel_distance_travel = 20
serving_radius = 15
G = [
ChargingStation(Location(20, 10), 50),
ChargingStation(Location(50, 80), 40),
ChargingStation(Location(30, 30), 60)
]
def __init__(self, location, fuel):
self.location = location
self.fuel = fuel
# Resid (U)
def residual_distance(self):
return self.fuel * self.per_fuel_distance_travel # assuming each unit of fuel will yield to 2 kilos or miles
def is_out_of_service_zone(self, vehicle_location: Location): # ----->
distance = get_distance(self.location, vehicle_location)
return distance > self.serving_radius
#staticmethod
def get_distance(from_location, to_location):
x_dis = to_location.x - from_location.x
y_dis = to_location.y - from_location.y
x_dis_sqr = math.pow(x_dis, 2)
y_dis_sqr = math.pow(y_dis, 2)
final_dis_sum = x_dis_sqr + y_dis_sqr
final = math.sqrt(final_dis_sum)
return final
class EDFGenerator:
min_fuel = 50
charging_stations_for_drones = [ChargingStation(Location(2, 10), 80), ChargingStation(Location(2, 10), 50),
ChargingStation(Location(2, 10), 100)]
list_waiting_drones = [Drone(Location(5, 10), 50), Drone(Location(2, 10), 50), Drone(Location(2, 10), 50)]
list_sent_drones = []
list_charging_drones = []
def __init__(self):
pass
def rdv_loc(self, ei: Vehicle, drone_location: Location, t: int) -> Location | None:
needed_fuel = ei.requested_amount_of_charge(drone_location)
nearest_charge_station = self.get_nearest_charge_station(ei.location, self.charging_stations_for_drones)
needed_fuel_at_nearest_station = needed_fuel / ei.per_fuel_distance_travel
if nearest_charge_station.fuel < needed_fuel_at_nearest_station:
return None
else:
return nearest_charge_station.location
#staticmethod
def get_nearest_charge_station(from_location: Location, list_of_stations: List[ChargingStation]) -> ChargingStation:
nearest = list_of_stations[0]
min_distance = get_distance(from_location, nearest.location)
for station in list_of_stations:
dis = get_distance(from_location, station.location)
if min_distance > dis:
min_distance = dis
nearest = station
return nearest
def NChgReq(self) -> int:
charging_requesters = 0
for drone in self.list_waiting_drones:
if drone.isNeedEmergencyFuel:
charging_requesters += 1
return charging_requesters
def send_drone_to_charge(self, drone: Drone): # ----->
if drone.fuel < self.min_fuel:
nearest_station = self.get_nearest_charge_station(
drone.location,
self.charging_stations_for_drones)
self.list_sent_drones.append(drone)
self.list_waiting_drones.remove(drone)
drone.isSendForEvCharge = True
# send the drone to the charging station here
print(f"Drone {drone} sent to charging station at {nearest_station}")
def check_fuel_and_send_to_charge(self): # ----->
for drone in self.list_waiting_drones:
self.send_drone_to_charge(drone)
def get_drone(self, max_try=4) -> Drone:
if max_try <= 0:
print("max try failed for get_drone")
return None
# take one time from list_waiting_drones ------->
# add to list_sent_drones
# send or return the taken item
if len(self.list_waiting_drones) == 0:
return None
else:
# lastOne = self.list_waiting_drones.pop()
self.last_one = self.list_waiting_drones.pop()
if self.last_one.fuel < self.min_fuel:
print("low fuel failed to get_drone, retry")
self.list_waiting_drones.insert(0, self.last_one)
return max_try - 1
self.list_sent_drones.append(self.last_one)
return self.last_one
def get_closest_location_from_sending_server_to_e_vehicle(self, current_vechicle_location):
min_distance = sys.maxsize
for current_server in self.charging_stations_for_drones:
distance = get_distance(current_vechicle_location, current_server.location)
if min_distance > distance:
min_distance = distance
return min_distance
def get_most_urgent_electric_vehicle(self, closest_distance_between_server_ev: int,
all_uncharged_electric_vehicles: List[Vehicle]) -> Vehicle:
final_ev = None
min_distance = sys.maxsize
for ev in all_uncharged_electric_vehicles:
g_r = self.get_closest_location_from_sending_server_to_e_vehicle(ev.location)
residual_distance = ev.residual_distance()
eq = g_r / residual_distance
if min_distance > eq:
min_distance = eq
final_ev = ev
return final_ev
def reports_termination_to_server(self, drone: Drone):
self.list_charging_drones.append(drone)
self.charge_all_waiting_drones()
def charge_all_waiting_drones(self):
# assuming the environment is not async but synchronous
for drone in self.list_charging_drones:
drone.fuel = 100
self.list_waiting_drones.insert(0, drone)
self.list_charging_drones.clear()
#staticmethod
def report_to_server(ev: Vehicle, message):
print(ev.id + " - " + message)
def get_edf(self, list_req: List[Vehicle]) -> Result:
s_uncharged_electric_vehicles = list_req
path_len = 0
n_charge_req = 0
while len(s_uncharged_electric_vehicles) > 0:
print("uncharged_ev : " + str(len(s_uncharged_electric_vehicles)))
current_uncharged_ev = s_uncharged_electric_vehicles[0]
u = self.get_drone()
if u is None:
print("no drones from any station or with min charge")
return Result(path_len, n_charge_req)
# current_uncharged_ev.location aka e----->
e = current_uncharged_ev.location
# confusion SGCS what would be the SET
g_r: int = self.get_closest_location_from_sending_server_to_e_vehicle(
e) # closest vehicle from sending location
# confusion regarding dis (loc(e), g_r) , g_r already contains the distance
e_x = self.get_most_urgent_electric_vehicle(g_r, s_uncharged_electric_vehicles)
drone_residual_distance = u.residual_distance() # Resid (U)
ev_requested_amount_of_charge = e_x.requested_amount_of_charge(u.location) # RqB2D
if drone_residual_distance < ev_requested_amount_of_charge:
self.reports_termination_to_server(u)
u = self.get_drone()
g_r_2 = self.get_closest_location_from_sending_server_to_e_vehicle(
u.location) # closest vehicle from sending location
self.reports_termination_to_server(u) # sends back the drone for charging
# ?? t is something confusing, how to include t into the equation??
rdv_loc = self.rdv_loc(e_x, u.location, 0) # t should be random
if rdv_loc is None:
self.report_to_server(e_x, "rdv location generate failed")
continue
if u.is_out_of_service_zone(rdv_loc):
self.report_to_server(e_x, "Out of Service")
continue
path_len += get_distance(u.location, rdv_loc)
u.location = rdv_loc
e_x.location = rdv_loc
# list_1 = filter(lambda x: x[3] <= 0.3 and x[2] < 5, list_1)
s_uncharged_electric_vehicles.remove(e_x)
n_charge_req = n_charge_req + 1
return Result(path_len, n_charge_req)
if __name__ == '__main__':
edf_runner = EDFGenerator()
un_charged_vehicles = [
Vehicle(1, Location(1, 1), 2),
Vehicle(2, Location(5, 10), 16),
Vehicle(3, Location(6, 10), 13),
Vehicle(4, Location(8, 11), 22),
Vehicle(5, Location(5, 6), 35),
]
edf_result = edf_runner.get_edf(un_charged_vehicles)
print("first_path_len - edf : ")
edf_result.print()
Where am I wrong? What needs fix?

Related

How to pass values from one thread to another thread Python?

I begin to code the python and I am not have more experience in syntax of python
I want to send a value from the RFID reader. If it saves successfully, the PIR Motion Sensor will be disabled in a moment. and reworking within the specified time.
If the temperature is measured And send the value to the function RFID Reader to record the temperature and the PIR Motion Sensor stops working as well.
class Security:
global dbHost
global dbUser
global dbPass
global dbNameEmp
global dbNameSecure
dbHost = 'localhost'
dbUser = 'root'
dbPass = 'iTdev#2020'
dbNameEmp = 'empinfo'
dbNameSecure = 'secureinfo'
def __init__(self):
self.msg=""
def Temperature(self):
while True:
GPIO.output(TRIG, False)
time.sleep(0.5)
GPIO.output(TRIG, True)
time.sleep(0.01)
GPIO.output(TRIG, False)
while GPIO.input(ECHO) == 0 :
pulse_start = time.time()
while GPIO.input(ECHO) == 1 :
pulse_end = time.time()
pulse_duration = pulse_end - pulse_start
distance = pulse_duration * 11150
distance = round(distance,2)
if distance > 0 and distance < 3 :
buzzer.on()
time.sleep(0.1)
buzzer.off()
print ("Distance: %scm" % (distance))
#print "Ambient Temperature :", sensor.get_ambient()
print ("Temperature: %.1fc" % (sensor.get_object_1()))
msgTemp = ("%.1f" % (sensor.get_object_1()))
w, h = textsize(msgTemp, font=proportional(CP437_FONT))
if w <= device.width:
x = round((device.width - w) / 2)
with canvas(device) as draw:
text(draw, (x, 0), msgTemp, fill="white", font=proportional(CP437_FONT))
else:
show_message(device, msgTemp, fill="white", font=proportional(CP437_FONT),scroll_delay=0.04)
time.sleep(1)
device.clear()
def rfid_callback(self, state, dev):
rfid_presented = ""
keys = "X^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXX"
while True:
r,w,x = select([dev], [], [])
for event in dev.read():
if event.type==1 and event.value==1:
if event.code==28:
rfid_presented = rfid_presented.replace("X", "")
travel = state.replace("Thread-", "")
dbConnEmp = mysql.connect(host=dbHost, user=dbUser, passwd=dbPass, db=dbNameEmp)
curEmp = dbConnEmp.cursor()
curEmp.execute("Select RFidEmp FROM RFidMaster WHERE (RFidStatus = 1) AND RFidNumber = '%s'" % (rfid_presented))
resultRFid = curEmp.fetchone()
if curEmp.rowcount != 1:
# print("Access Denied." + travel)
with canvas(device) as draw:
text(draw, (0, 0), "None", fill="white", font=proportional(CP437_FONT))
time.sleep(0.5)
device.clear()
else:
# print("Unlocking Door." + travel)
dbConnSecure = mysql.connect(host=dbHost, user=dbUser, passwd=dbPass, db=dbNameSecure)
curSecure = dbConnSecure.cursor()
curSecure.execute("SELECT EntraId,DATE_FORMAT(CreateDate, '%Y%m%d') AS CreateDate FROM entranlog ORDER BY EntraId DESC, CreateDate DESC LIMIT 1")
resultKey = curSecure.fetchone()
KeyDate = time.strftime("%Y%m%d")
if curSecure.rowcount != 1:
KeyId = KeyDate+"0001"
else:
if resultKey[1] == KeyDate:
iSum = int(resultKey[0])
def sum(x, y):
return x + y
KeyId = ('%d' % sum(iSum, 1))
else:
KeyId = KeyDate+"0001"
create_date = time.strftime('%Y-%m-%d %H:%M:%S')
insertSecure = "INSERT INTO entranlog (EntraId,EntraAction,EntraStatus,CreateBy,CreateDate) VALUES (%s,%s,%s,%s,%s)"
valSecure = (KeyId,travel,1,resultRFid[0],create_date)
curSecure.execute(insertSecure, valSecure)
dbConnSecure.commit()
# print("Welcome: " + resultRFid[0])
with canvas(device) as draw:
text(draw, (0, 0), "Hello", fill="white", font=proportional(CP437_FONT))
print(curSecure.rowcount, "record inserted.")
time.sleep(0.8)
device.clear()
rfid_presented = ""
else:
rfid_presented += keys[ event.code ]
def PirSensor(self):
while True:
led_blue.on()
time.sleep(0.1)
current_state = GPIO.input(pir_sensor)
if current_state == 1:
print("GPIO pin %s is %s" % (pir_sensor, current_state))
GPIO.output(relay_alarm,True)
led_blue.off()
led_red.blink(0.1, 0.2)
# buzzer.beep(0.5, 0.5, 3)
time.sleep(5)
GPIO.output(relay_alarm,False)
led_red.off()
led_yellow.blink(0.5, 0.5)
time.sleep(5)
led_yellow.off()
def main(self):
devIn = threading.Thread(target=self.rfid_callback, args=['1', InputDevice('/dev/input/event0')])
devIn.start()
devOut = threading.Thread(target=self.rfid_callback, args=['2', InputDevice('/dev/input/event1')])
devOut.start()
Pir = threading.Thread(target=self.PirSensor)
Pir.start()
Temp = threading.Thread(target=self.Temperature)
Temp.start()
if __name__ == "__main__":
g=Security()
g.main()

Scipy optimize.minimize with multi- parameters

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import linalg, optimize
%matplotlib inline
Data load
data = pd.read_csv("D:/Stat/TimeSeries/KRW_month_0617_1.csv",index_col="Date") / 100
para = open("D:/Stat/TimeSeries/KRW_month_0617_1.txt").readlines()[0:2]
data.index = pd.to_datetime(data.index)
Parameters
cond = []
params = []
time = []
for i in para:
j = i.split()
for k in j:
cond.append(k)
cond = cond[1:]
for i in range(len(cond)):
cond[i] = round(float(cond[i]),4)
params = cond[0:23]
time = cond[23:]
maturity = np.array(time[1:])
timegap = 1/cond[23]
Functions We need
def Paramcheck(Params, checkStationary = 1):
result = 0
Kappa = np.array([[params[20],0,0], [0,params[21],0], [0,0,params[22]]])
Sigma = np.array([[params[1],0,0], [params[2],params[3],0], [params[4],params[5],params[6]]])
State = np.array([params[7], params[8], params[9]])
Lambda = params[0]
SigmaEps = np.identity(10)
for i in range(10):
SigmaEps[i][i] = params[i+10]
for i in range(len(Sigma)):
if Sigma[i][i] < 0:
result = 1
for j in SigmaEps:
if np.any(SigmaEps) < 0:
result = 1
if Lambda < 0.05 or Lambda > 2:
result = 1
elif State[0] < 0:
result = 1
elif Kappa[0][0] < 0:
result = 1
if result == 0 and checkStationary > 0:
if max(np.linalg.eigvals(-Kappa).real) > 0:
result = 2
return result
def CheckDet(x):
if x == np.inf or x == np.nan:
result = 1
elif x < 0:
result = 2
elif abs(x) < 10**-250:
result = 3
else:
result = 0
return result
def NS_factor(lambda_val, maturity):
col1 = np.ones(len(maturity))
col2 = (1 - np.exp(-lambda_val*maturity))/(lambda_val*maturity)
col3 = col2 - np.exp(-lambda_val*maturity)
factor = np.array([col1,col2,col3]).transpose()
return factor
def DNS_Kalman_filter(Params, *args):
N = Paramcheck(Params)
if N == 0:
Kappa = np.array([[params[20],0,0], [0,params[21],0], [0,0,params[22]]])
Sigma = np.array([[params[1],0,0], [params[2],params[3],0],
[params[4],params[5],params[6]]])
State = np.array([params[7], params[8], params[9]])
Lambda = params[0]
SigmaEps = np.identity(10)
for i in range(10):
SigmaEps[i][i] = params[i+10]
Obs_Yield = args[0]
Obs_Date = args[1]
Timegap = args[2]
Obs_Mty = args[3]
Finalstate = args[4]
Mty_length = len(Obs_Mty)
B = NS_factor(lambda_val = Lambda,maturity = Obs_Mty)
H_large = SigmaEps **2
N_obs = len(Obs_Date)
LLH_vec = np.zeros(N_obs)
phi1 = linalg.expm(-Kappa*Timegap)
phi0 = (np.identity(3)-phi1) # State
Eigenvalues = np.linalg.eig(Kappa)[0]
Eigen_vec = np.linalg.eig(Kappa)[1]
Eigen_vec_inv = np.linalg.inv(Eigen_vec)
S = Eigen_vec_inv # Sigma # Sigma.transpose() # Eigen_vec_inv.transpose()
Atilde = np.dot(Sigma[0], Sigma[0])
Btilde = np.dot(Sigma[1], Sigma[1])
Ctilde = np.dot(Sigma[2], Sigma[2])
Dtilde = np.dot(Sigma[0], Sigma[1])
Etilde = np.dot(Sigma[0], Sigma[2])
Ftilde = np.dot(Sigma[1], Sigma[2])
res1= Atilde* Obs_Mty* Obs_Mty/6
res2= Btilde*(1/(2*Lambda**2) - (1-np.exp(-Lambda*Obs_Mty))/(Lambda**3*Obs_Mty) + (1-
np.exp(-2*Lambda*Obs_Mty))/(4*Lambda**3*Obs_Mty))
res3= Ctilde*(1/(2*Lambda**2) + np.exp(-Lambda*Obs_Mty)/(Lambda**2)-
Obs_Mty*np.exp(-2*Lambda*Obs_Mty)/(4*Lambda) -
3*np.exp(-2*Lambda*Obs_Mty)/(4*Lambda**2) - 2*(1-np.exp(-
Lambda*Obs_Mty))/(Lambda**3*Obs_Mty) + 5*(1-
np.exp(-2*Lambda*Obs_Mty))/(8*Lambda**3*Obs_Mty))
res4= Dtilde*(Obs_Mty/(2*Lambda) + np.exp(-Lambda*Obs_Mty)/(Lambda**2) - (1-np.exp(-
Lambda*Obs_Mty))/(Lambda**3*Obs_Mty))
res5= Etilde*(3*np.exp(-Lambda*Obs_Mty)/(Lambda**2) + Obs_Mty/(2*Lambda)+Obs_Mty*np.exp(-
Lambda*Obs_Mty)/(Lambda) - 3*(1-np.exp(-Lambda*Obs_Mty))/(Lambda**3*Obs_Mty))
res6= Ftilde*(1/(Lambda**2) + np.exp(-Lambda*Obs_Mty)/(Lambda**2) -
np.exp(-2*Lambda*Obs_Mty)/(2*Lambda**2) - 3*(1-np.exp(-
Lambda*Obs_Mty))/(Lambda**3*Obs_Mty) + 3*(1-
np.exp(-2*Lambda*Obs_Mty))/(4*Lambda**3*Obs_Mty))
val = res1 + res2 + res3 + res4 + res5 + res6
V_mat = np.zeros([3,3])
V_lim = np.zeros([3,3])
for i in range(3):
for j in range(3):
V_mat[i][j] = S[i][j]*(1-np.exp(-(Eigenvalues[i] +
Eigenvalues[j])*Timegap))/(Eigenvalues[i] + Eigenvalues[j])
V_lim[i][j] = S[i][j]/(Eigenvalues[i] + Eigenvalues[j])
Q = (Eigen_vec # V_mat # Eigen_vec.transpose()).real
Sigma_lim = (Eigen_vec # V_lim # Eigen_vec.transpose()).real
for i in range(N_obs):
y = Obs_Yield[i]
xhat = phi0 + phi1 # State
y_implied = B # xhat
v = y - y_implied + val
Sigmahat = phi1 # Sigma_lim # phi1.transpose() + Q
F = B # Sigmahat # B.transpose() + H_large
detF = np.linalg.det(F)
if CheckDet(detF) > 0:
N = 3
break
Finv = np.linalg.inv(F)
State = xhat + Sigmahat # B.transpose() # Finv # v
Sigma_lim = Sigmahat - Sigmahat # B.transpose() # Finv # B # Sigmahat
LLH_vec[i] = np.log(detF) + v.transpose() # Finv # v
if N == 0:
if Finalstate:
yDate = Obs_Date[-1]
result = np.array([yDate,State])
else:
result = 0.5 * (sum(LLH_vec) + Mty_length*N_obs*np.log(2*np.pi))
else:
result = 7000000
return result
I made a code that does Arbitrage Free Nelson-Siegel model. Data is return rates of bond (1Y,1.5Y, ... ,20Y). I wanna optimize that function with scipy optimize.minimize function with fixed *args.
Suppose that Initial parmas are verified that it's close to optimized params from empirical experiments using Dynamic Nelson-Siegel Model.
LLC_new = 0
while True:
LLC_old = LLC_new
OPT = optimize.minimize(x0=params,fun=DNS_Kalman_filter, args=
(data.values,data.index,timegap,maturity,0))
params = OPT.x
LLC_new = round(OPT.fun,5)
print("Current LLC: %0.5f" %LLC_new)
if LLC_old == LLC_new:
OPT_para = params
FinalState = DNS_Kalman_filter(params,data.values,data.index,timegap,maturity,True)
break
Result is
Current LLC: -7613.70146
Current LLC: -7613.70146
LLC(log-likelihood value) isn't maximized. It's not a result I desire using Optimizer.
Is there any solution for that?
In R, there is optim() function works as similar as scipy.optimize.minimize() which works really well. I also have a R code for that very similar to this Python code.

Multivariate Natural Evolution Strategy

I've just started to play around with Reinforcement Learning these days and I found the Natural Evolution Strategy, I kind of understand how it works, but I'm very new with Python and I found this code which basically implements the NES algorithm
https://github.com/huseinzol05/Stock-Prediction-Models/blob/master/agent/updated-NES-google.ipynb
import numpy as np
import pandas as pd
import time
import matplotlib.pyplot as plt
import seaborn as sns
import random
sns.set()
# CSV containing the TSLA stock predictions in the form of
# [Date, Open, High, Low, Close, Adj Close, Volume] from
# Yahoo! Finance
df = pd.read_csv('TSLA.csv')
df.head()
def get_state(data, t, n):
d = t - n + 1
block = data[d : t + 1] if d >= 0 else -d * [data[0]] + data[0 : t + 1]
res = []
for i in range(n - 1):
res.append(block[i + 1] - block[i])
return np.array([res])
close = df.Close.values.tolist()
window_size = 30
skip = 1
l = len(close) - 1
class Deep_Evolution_Strategy:
inputs = None
def __init__(
self, weights, reward_function, population_size, sigma, learning_rate
):
self.weights = weights
self.reward_function = reward_function
self.population_size = population_size
self.sigma = sigma
self.learning_rate = learning_rate
def _get_weight_from_population(self, weights, population):
weights_population = []
for index, i in enumerate(population):
jittered = self.sigma * i
weights_population.append(weights[index] + jittered)
return weights_population
def get_weights(self):
return self.weights
def train(self, epoch = 100, print_every = 1):
lasttime = time.time()
for i in range(epoch):
population = []
rewards = np.zeros(self.population_size)
for k in range(self.population_size):
x = []
for w in self.weights:
x.append(np.random.randn(*w.shape))
population.append(x)
for k in range(self.population_size):
weights_population = self._get_weight_from_population(self.weights, population[k])
rewards[k] = self.reward_function(weights_population)
rewards = (rewards - np.mean(rewards)) / np.std(rewards)
for index, w in enumerate(self.weights):
A = np.array([p[index] for p in population])
self.weights[index] = (
w
+ self.learning_rate
/ (self.population_size * self.sigma)
* np.dot(A.T, rewards).T
)
class Model:
def __init__(self, input_size, layer_size, output_size):
self.weights = [
np.random.randn(input_size, layer_size),
np.random.randn(layer_size, output_size),
np.random.randn(layer_size, 1),
np.random.randn(1, layer_size),
]
def predict(self, inputs):
feed = np.dot(inputs, self.weights[0]) + self.weights[-1]
decision = np.dot(feed, self.weights[1])
buy = np.dot(feed, self.weights[2])
return decision, buy
def get_weights(self):
return self.weights
def set_weights(self, weights):
self.weights = weights
class Agent:
POPULATION_SIZE = 15
SIGMA = 0.1
LEARNING_RATE = 0.03
def __init__(self, model, money, max_buy, max_sell):
self.model = model
self.initial_money = money
self.max_buy = max_buy
self.max_sell = max_sell
self.es = Deep_Evolution_Strategy(
self.model.get_weights(),
self.get_reward,
self.POPULATION_SIZE,
self.SIGMA,
self.LEARNING_RATE,
)
def act(self, sequence):
decision, buy = self.model.predict(np.array(sequence))
return np.argmax(decision[0]), int(buy[0])
def get_reward(self, weights):
initial_money = self.initial_money
starting_money = initial_money
self.model.weights = weights
state = get_state(close, 0, window_size + 1)
inventory = []
quantity = 0
for t in range(0, l, skip):
action, buy = self.act(state)
next_state = get_state(close, t + 1, window_size + 1)
if action == 1 and initial_money >= close[t]:
if buy < 0:
buy = 1
if buy > self.max_buy:
buy_units = self.max_buy
else:
buy_units = buy
total_buy = buy_units * close[t]
initial_money -= total_buy
inventory.append(total_buy)
quantity += buy_units
elif action == 2 and len(inventory) > 0:
if quantity > self.max_sell:
sell_units = self.max_sell
else:
sell_units = quantity
quantity -= sell_units
total_sell = sell_units * close[t]
initial_money += total_sell
state = next_state
return ((initial_money - starting_money) / starting_money) * 100
def fit(self, iterations, checkpoint):
self.es.train(iterations, print_every = checkpoint)
def buy(self):
initial_money = self.initial_money
state = get_state(close, 0, window_size + 1)
starting_money = initial_money
states_sell = []
states_buy = []
inventory = []
quantity = 0
for t in range(0, l, skip):
action, buy = self.act(state)
next_state = get_state(close, t + 1, window_size + 1)
if action == 1 and initial_money >= close[t]:
if buy < 0:
buy = 1
if buy > self.max_buy:
buy_units = self.max_buy
else:
buy_units = buy
total_buy = buy_units * close[t]
initial_money -= total_buy
inventory.append(total_buy)
quantity += buy_units
states_buy.append(t)
elif action == 2 and len(inventory) > 0:
bought_price = inventory.pop(0)
if quantity > self.max_sell:
sell_units = self.max_sell
else:
sell_units = quantity
if sell_units < 1:
continue
quantity -= sell_units
total_sell = sell_units * close[t]
initial_money += total_sell
states_sell.append(t)
try:
invest = ((total_sell - bought_price) / bought_price) * 100
except:
invest = 0
state = next_state
invest = ((initial_money - starting_money) / starting_money) * 100
model = Model(window_size, 500, 3)
agent = Agent(model, 10000, 5, 5)
agent.fit(500, 10)
agent.buy()
As you can see, it is being used for stock prediction and it only uses the Close column, but I would like to try it with more parameters, let's say High and Low.
I'm struggling when I need to change it to use this 2 dimensional list. I've tried a simple change:
close = df.loc[:,['Close','Open']].values.tolist()
Which adds one more property at every row of the list. But when I run the code I start to see errors when I execute the agent.fit() call:
agent.fit(iterations = 500, checkpoint = 10)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-225-d97697984016> in <module>()
----> 1 agent.fit(iterations = 500, checkpoint = 10)
<ipython-input-223-35d9fbba5756> in fit(self, iterations, checkpoint)
66
67 def fit(self, iterations, checkpoint):
---> 68 self.es.train(iterations, print_every = checkpoint)
69
70 def buy(self):
<ipython-input-220-84ca345091f4> in train(self, epoch, print_every)
33 self.weights, population[k]
34 )
---> 35 rewards[k] = self.reward_function(weights_population)
36 rewards = (rewards - np.mean(rewards)) / np.std(rewards)
37
<ipython-input-223-35d9fbba5756> in get_reward(self, weights)
36
37 self.model.weights = weights
---> 38 state = get_state(self.close, 0, self.window_size + 1)
39 inventory = []
40 quantity = 0
<ipython-input-219-0df8d8be24a9> in get_state(data, t, n)
4 res = []
5 for i in range(n - 1):
----> 6 res.append(block[i + 1] - block[i])
7 return np.array([res])
TypeError: unsupported operand type(s) for -: 'list' and 'list'
I assume that the first step is that I need to update my Model class to use a different input_size parameter right?
Any help would be appreciated! Thanks

How to get different predation values every year for my simulation?

I am trying to run this model of seed predation and population dynamics but I am new to coding and I am only getting one predation value that gets repeated over different generations. How can I get different predation values for different year?
Also, Is there an issue with the normalizing method used?
import numpy as np
import matplotlib.pyplot as plt
def is_odd(year):
return ((year % 2) == 1)
def reproduction(p_iter, year, dead):
if is_odd(year):
predation = dead
seedsProd = p_iter*s_oddd
seedsPred = K*predation*200*(seedsProd/np.sum(seedsProd))
return (seedsProd - seedsPred) + np.array([0,0,p_iter[2]])
else:
predation = dead
seedsProd = p_iter*s_even
seedsPred = K*predation*200*(seedsProd/np.sum(seedsProd))
return (seedsProd - seedsPred) +np.array([0,p_iter[1],0])
def normalize(p_iter):
if is_odd(year):
x = np.copy(p_iter)
x[2] = 0
x = (K-p_iter[2]) * x / sum(x)
x[2] = p_iter[2]
return x
else:
x = np.copy(p_iter)
x[1] = 0
x = (K-p_iter[1]) * x / sum(x)
x[1] = p_iter[1]
return x
Predation is defined here:
def predation():
return (np.array(np.round(np.random.uniform(0.4,0.6),2)))
#max_years
Y = 100
#carrying capacity
K = 1000
#initial populaton
p_1, p_2, p_3 = 998., 1., 1.
#seed released per plant
s_1, s_2, s_3 = 200, 260, 260
p_init = np.array([p_1, p_2, p_3],dtype=float)
s_oddd = np.array([s_1, s_2, 0.0])
s_even = np.array([s_1, 0.0, s_3])
n = len(p_init)
m = np.append(p_init,s_oddd)
p_iter = p_init
dead = 0
norm = 0
for year in range(1,Y+1):
dead = predation()
seeds = reproduction(p_iter, year, dead)
p_iter = np.maximum(seeds,np.zeros(p_iter.shape))
p_iter = normalize(p_iter)
m = np.vstack((m, [*p_iter]+[*seeds] ))

How can I mount a video from multiple frames saved in a file?

I use a code that makes use of kalman filter to stabilize a video but I am not able to record a video to be saved. I thought about saving all the frames in a file and creating a video later.
If someone has a better idea, or how to modify the code to be possible to use cv2.videoWriter.
import cv2
import numpy as np
from matplotlib import pyplot as plt
ini = time.time()
class FrameInfo:
def __init__(self):
self.img = None
self.img_gray = None
self.features = []
self.number = 0
self.trajectory = Trajectory()
#property
def width(self):
return self.img_gray.shape[1]
#property
def height(self):
return self.img_gray.shape[0]
#property
def width_height(self):
return self.img_gray.shape[::-1]
videoInPath = "../data/MVI_5408.avi"
camera = cv2.VideoCapture(videoInPath)
videoOutPath = videoInPath +'sab.avi'
N_FRAMES = int(camera.get(cv2.CAP_PROP_FRAME_COUNT))
FPS = camera.get(cv2.CAP_PROP_FPS)
VID_WIDTH = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))
VID_HEIGHT = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))
print "N_FRAMES: " + str(N_FRAMES)
print "FPS: " + str(FPS)
frame = None
prev_frame = None
trajectory = Trajectory(0, 0, 0)
org_trajectories = []
stb_trajectories = []
crop = 40
crop_rate = crop / 20
filter = KalmanFilter(Trajectory(4e-2, 4e-2, 4e-2), Trajectory(crop_rate,
crop_rate, crop_rate), Trajectory(1, 1, 1))
#surf = cv2.SURF(4000)
prev_trans = None
frame_number = 0
frame_width = int(1336.0 / 2)
frame_height = int(768.0 / 2)
def resize(img):
return cv2.resize(img, (frame_width, frame_height),
interpolation=cv2.INTER_LANCZOS4)
lk_params = dict(winSize=(19, 19),
maxLevel=2,
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
feature_params = dict(maxCorners=100,
qualityLevel=0.01,
minDistance=8,
blockSize=19)
crop_rate = 0.9
limits = [int(frame_width * (1 - crop_rate)), int(frame_height * (1 -
crop_rate)), 0.05]
output_video = cv2.VideoWriter(videoOutPath,
cv2.VideoWriter_fourcc(*'XVID'), # -1, #
int(video.get(cv2.cv.CV_CAP_PROP_FOURCC)),
FPS,
(frame_width - 2*limits[0], frame_height - 2*limits[1])
)
feature_cont = 0
flow_cont = 0
ransac_cont = 0
kalman_cont = 0
features_quant = []
percent = 0
inliers_quant = []
ouliers_quant = []
compensate_count = 0
for k in range(N_FRAMES-1):
# Capture frame_img-by-frame_img
ret, frame_img = camera.read()
if frame_img is None:
break
if frame is not None:
prev_frame = frame
frame_number += 1
if frame_number < 220:
continue
frame = FrameInfo()
frame.number = frame_number
frame.img = frame_img
frame.img = cv2.resize(frame_img, (0, 0), fx=(1336.0 / frame_img.shape[1]) / 2.0,
fy=(768.0 / frame_img.shape[0]) / 2.0,
interpolation=cv2.INTER_LANCZOS4)
frame.img_gray = cv2.cvtColor(frame.img, cv2.COLOR_BGR2GRAY)
feature_time_ini = time.time()
frame.features = cv2.goodFeaturesToTrack(frame.img_gray, **feature_params)
#frame.features = sift.detect(frame.img_gray,None)
features_quant.append(len(frame.features))
if prev_frame is None:
continue
feature_time_fim = time.time()
feature_cont += feature_time_fim - feature_time_ini
feature_time_ini = 0
feature_time_fim = 0
flow_time_ini = time.time()
new_features, _, _ = cv2.calcOpticalFlowPyrLK(prev_frame.img, frame.img, prev_frame.features, None, **lk_params)
new_features_for_validation, _, _ = cv2.calcOpticalFlowPyrLK(frame.img, prev_frame.img, new_features, None,
**lk_params)
flow_time_fim = time.time()
flow_cont += flow_time_fim - flow_time_ini
flow_time_ini = 0
flow_time_fim = 0
d = abs(prev_frame.features - new_features_for_validation).reshape(-1, 2).max(-1)
good = d < 1
# Select good_features points
good_new = np.array([x for x, s in zip(new_features, good) if s], dtype=np.float32)
good_old = np.array([x for x, s in zip(prev_frame.features, good) if s], dtype=np.float32)
# trans = cv2.estimateRigidTransform(good_old, good_new, fullAffine=False)
ransac_time_ini = time.time()
trans, inliers_indices,outliers_indices = RansacMotionEstimator(40, 1.0).estimate(good_old, good_new)
ransac_time_fim = time.time()
ransac_cont += ransac_time_fim - ransac_time_ini
ransac_time_ini = 0
ransac_time_fim = 0
inliers_quant.append(len(inliers_indices))
ouliers_quant.append(len(outliers_indices))
if trans is None and prev_trans is None:
print ("wuf? trans is None and prev_trans is none too")
continue
if trans is None:
trans = prev_trans
print ("wut? trans is None")
delta = Trajectory(get_x(trans), get_y(trans), get_rad_angle(trans))
trajectory += delta
kalman_time_ini = time.time()
filter.put(trajectory)
diff = filter.get() - trajectory
new_delta = delta + diff
kalman_time_fim = time.time()
org_trajectories.append(trajectory)
stb_trajectories.append(filter.get())
kalman_cont += kalman_time_fim - kalman_time_ini
kalman_time_ini = 0
kalman_time_fim = 0
fill_mat(trans, new_delta.x, new_delta.y, new_delta.angle)
compensate_time_ini = time.time()
#out = cv2.warpAffine(frame.img, trans, frame.width_height, flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_CONSTANT)
#out = cv2.warpAffine(frame_img, trans, frame.width_height, flags=cv2.INTER_LANCZOS4, borderMode=cv2.BORDER_REFLECT)
#out = cv2.warpAffine(frame_img, trans, frame.width_height)
out = cv2.warpAffine(frame_img, trans, frame.width_height, flags=cv2.INTER_CUBIC,borderMode=cv2.BORDER_REPLICATE)
compensate_time_fim = time.time()
compensate_count += compensate_time_fim - compensate_time_ini
compensate_time_ini = 0
compensate_time_fim = 0
#out = cv2.warpAffine(frame_img, trans, frame.width_height, flags=cv2.INTER_LANCZOS4, borderMode=cv2.BORDER_REFLECT)
#out = frame.img.copy()
prev_trans = trans.copy()
output_video.write(out)
camera.release()
output_video.release()
cv2.destroyAllWindows()

Resources