Browse Source

explore_eval_gtr

master
김선중 1 year ago
parent
commit
6dd78c453f
8 changed files with 604 additions and 0 deletions
  1. +11
    -0
      0110_pyc_test/0110_pyc_test.py
  2. +24
    -0
      0110_pyc_test/0110_pyc_test_decompiled.py
  3. BIN
      0110_pyc_test/__pycache__/0110_pyc_test.cpython-38.pyc
  4. BIN
      0110_pyc_test/__pycache__/env.cpython-38.pyc
  5. +189
    -0
      0110_pyc_test/env.py
  6. +171
    -0
      0110_pyc_test/env_decompiled.py
  7. +122
    -0
      0217_explore_eval_gtr/0217_explore_eval_gtr.ipynb
  8. +87
    -0
      0217_explore_eval_gtr/0217_explore_eval_gtr.md

+ 11
- 0
0110_pyc_test/0110_pyc_test.py View File

@ -0,0 +1,11 @@
import numpy as np
# A, B로 나뉘어진 현시시간을 (4현시) 세부현시시간(5현시)로 바꾸는 코드
durs_A = np.array([37, 55, 45, 23])
durs_B = np.array([37, 55, 28, 40])
cums_A = durs_A.cumsum()
cums_B = durs_B.cumsum()
cycle = durs_A.sum()
detailed_cums = []
combined_row = np.unique(np.concatenate((cums_A, cums_B)))
detailed_durations = np.concatenate(([combined_row[0]], np.diff(combined_row)))
print(detailed_durations)

+ 24
- 0
0110_pyc_test/0110_pyc_test_decompiled.py View File

@ -0,0 +1,24 @@
import numpy as np
# 두 개의 배열 생성
durs_A = np.array([37, 55, 45, 23])
durs_B = np.array([37, 55, 28, 40])
# 두 배열의 누적합 계산
cums_A = durs_A.cumsum()
cums_B = durs_B.cumsum()
# durs_A의 합계를 cycle에 저장
cycle = durs_A.sum()
# 빈 리스트 생성
detailed_cums = []
# cums_A와 cums_B의 고유한 요소들을 결합
combined_row = np.unique(np.concatenate((cums_A, cums_B)))
# combined_row의 각 요소 간 차이 계산
detailed_durations = np.concatenate(([combined_row[0]], np.diff(combined_row)))
# 결과 출력
print(detailed_durations)

BIN
0110_pyc_test/__pycache__/0110_pyc_test.cpython-38.pyc View File


BIN
0110_pyc_test/__pycache__/env.cpython-38.pyc View File


+ 189
- 0
0110_pyc_test/env.py View File

@ -0,0 +1,189 @@
import os
import sys
import numpy as np
from sumolib import checkBinary
from args import Args
class Env:
'''This class is responsible for handling the traffic light optimization environment.'''
def __init__(self, infos, path_config, name=0):
'''
Initializes the environment with given information,
configuration path and initial state path.
'''
self.path_config = path_config
self.infos = infos
self.node_ids = Args.node_ids
assert list(self.node_ids) == list(self.infos)
self.path_init_state = f'data/init_state_{name}'
assert not os.path.exists(self.path_init_state)
self.gui = Args.gui
self.e2_length = Args.e2_length
self.yellow_length = Args.yellow_length
self.step_length = Args.step_length
self.rest_length = self.step_length - self.yellow_length
self.episode_length = Args.episode_length
self.episode_step = Args.episode_step
self.name = name
def _start(self):
'''
Starts the simulation.
https://sumo.dlr.de/docs/TraCI/Interfacing_TraCI_from_Python.html#importing_traci_in_a_script
'''
import traci
if 'SUMO_HOME' in os.environ:
tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
sys.path.append(tools)
else:
sys.exit("please declare environment variable 'SUMO_HOME'")
sumo_binary = checkBinary('sumo-gui' if self.gui else 'sumo')
cmd = [sumo_binary, '-c', self.path_config]
traci.start(cmd, label=self.name)
self.conn = traci.getConnection(self.name)
def close(self):
'''Closes the simulation.'''
self.conn.close()
if os.path.exists(self.path_init_state):
os.remove(self.path_init_state)
def _save(self):
'''
Saves the current state of the simulation.
https://sumo.dlr.de/docs/TraCI/Change_Simulation_State.html
'''
self.conn.simulation.saveState(self.path_init_state)
def _load(self):
'''
Loads the saved state of the simulation.
https://sumo.dlr.de/docs/TraCI/Change_Simulation_State.html
'''
self.conn.simulation.loadState(self.path_init_state)
def _step(self, step_length):
'''Advances the simulation by a given number of steps.'''
for _ in range(step_length):
self.conn.simulationStep()
def _get_occupancy(self, detector_id):
'''
Returns the occupancy of a given detector.
https://sumo.dlr.de/docs/TraCI/Lane_Area_Detector_Value_Retrieval.html
'''
return self.conn.lanearea.getLastStepOccupancy(detector_id) / 100
def _get_queue(self, detector_id):
'''
Returns the queue length at a given detector.
https://sumo.dlr.de/docs/TraCI/Lane_Area_Detector_Value_Retrieval.html
'''
return self.conn.lanearea.getJamLengthMeters(detector_id) / self.e2_length
def _get_values(self):
'''Retrieves the occupancy, queue and phase for each node.'''
node2values = {}
for node_id, info in self.infos.items():
values = {}
values['occupancy'] = [self._get_occupancy(d) for d in info['detectors']]
values['queue'] = [self._get_queue(d) for d in info['detectors']]
values['phase'] = [self.prev_phase_indexes[node_id]]
node2values[node_id] = values
states, rewards = [], []
global_reward = 0
for node_id, info in self.infos.items():
occupancy = [node2values[node_id]['occupancy']]
queue = [node2values[node_id]['queue']]
phase = [node2values[node_id]['phase']]
reward = -np.sum(node2values[node_id]['queue'])
global_reward -= np.sum(node2values[node_id]['queue'])
for nnode_id in info['neighbors']:
occupancy.append(node2values[nnode_id]['occupancy'])
queue.append(node2values[nnode_id]['queue'])
phase.append(node2values[nnode_id]['phase'])
reward -= np.sum(node2values[nnode_id]['queue']) * 0.5
states.append(np.concatenate(occupancy + queue + phase, dtype=np.float32))
rewards.append(reward)
return states, rewards, global_reward
def _set_yellows(self, actions):
'''Sets the yellow phase for nodes based on the given actions.'''
for node_id, action in zip(self.node_ids, actions):
if action == 0:
continue
info = self.infos[node_id]
prev_idx = self.prev_phase_indexes[node_id]
idx = (prev_idx + 1) % len(info['phases']['green'])
self.prev_phase_indexes[node_id] = idx
y = info['phases']['yellow'][prev_idx]
self._set_phase(node_id, y)
def _set_greens(self):
'''Sets the green phase for each node.'''
for node_id, info in self.infos.items():
idx = self.prev_phase_indexes[node_id]
g = info['phases']['green'][idx]
self._set_phase(node_id, g)
def _set_phase(self, node_id, phase):
'''Sets the phase for a specific node.'''
if self.prev_phases.get(node_id) != phase:
self.conn.trafficlight.setRedYellowGreenState(node_id, phase)
self.prev_phases[node_id] = phase
def step(self, actions):
'''Performs a step in the simulation based on the given actions.'''
self._set_yellows(actions)
self._step(self.yellow_length)
self._set_greens()
self._step(self.rest_length)
self.curr_step += 1
states, rewards, global_reward = self._get_values()
done = self.curr_step >= self.episode_step
return states, rewards, done, global_reward
def reset(self):
'''Resets the simulation to its initial state.'''
# Initialize simulation
if not os.path.exists(self.path_init_state):
self._start()
self._save()
self._load()
self.curr_step = 0
self.prev_phases = {n:'none' for n in self.node_ids}
self.prev_phase_indexes = {n:0 for n in self.node_ids}
self._set_greens()
self._step(1)
states, _, _ = self._get_values()
return states

+ 171
- 0
0110_pyc_test/env_decompiled.py View File

@ -0,0 +1,171 @@
# uncompyle6 version 3.9.0
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)]
# Embedded file name: .\env.py
# Compiled at: 2024-01-10 13:34:11
# Size of source mod 2**32: 6588 bytes
import os, sys, numpy as np
from sumolib import checkBinary
from args import Args
class Env:
__doc__ = 'This class is responsible for handling the traffic light optimization environment.'
def __init__(self, infos, path_config, name=0):
"""
Initializes the environment with given information,
configuration path and initial state path.
"""
self.path_config = path_config
self.infos = infos
self.node_ids = Args.node_ids
assert list(self.node_ids) == list(self.infos)
self.path_init_state = f"data/init_state_{name}"
assert not os.path.exists(self.path_init_state)
self.gui = Args.gui
self.e2_length = Args.e2_length
self.yellow_length = Args.yellow_length
self.step_length = Args.step_length
self.rest_length = self.step_length - self.yellow_length
self.episode_length = Args.episode_length
self.episode_step = Args.episode_step
self.name = name
def _start(self):
"""
Starts the simulation.
https://sumo.dlr.de/docs/TraCI/Interfacing_TraCI_from_Python.html#importing_traci_in_a_script
"""
import traci
if 'SUMO_HOME' in os.environ:
tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
sys.path.append(tools)
else:
sys.exit("please declare environment variable 'SUMO_HOME'")
sumo_binary = checkBinary('sumo-gui' if self.gui else 'sumo')
cmd = [sumo_binary, '-c', self.path_config]
traci.start(cmd, label=(self.name))
self.conn = traci.getConnection(self.name)
def close(self):
"""Closes the simulation."""
self.conn.close()
if os.path.exists(self.path_init_state):
os.remove(self.path_init_state)
def _save(self):
"""
Saves the current state of the simulation.
https://sumo.dlr.de/docs/TraCI/Change_Simulation_State.html
"""
self.conn.simulation.saveState(self.path_init_state)
def _load(self):
"""
Loads the saved state of the simulation.
https://sumo.dlr.de/docs/TraCI/Change_Simulation_State.html
"""
self.conn.simulation.loadState(self.path_init_state)
def _step(self, step_length):
"""Advances the simulation by a given number of steps."""
for _ in range(step_length):
self.conn.simulationStep()
def _get_occupancy(self, detector_id):
"""
Returns the occupancy of a given detector.
https://sumo.dlr.de/docs/TraCI/Lane_Area_Detector_Value_Retrieval.html
"""
return self.conn.lanearea.getLastStepOccupancy(detector_id) / 100
def _get_queue(self, detector_id):
"""
Returns the queue length at a given detector.
https://sumo.dlr.de/docs/TraCI/Lane_Area_Detector_Value_Retrieval.html
"""
return self.conn.lanearea.getJamLengthMeters(detector_id) / self.e2_length
def _get_values(self):
"""Retrieves the occupancy, queue and phase for each node."""
node2values = {}
for node_id, info in self.infos.items():
values = {}
values['occupancy'] = [self._get_occupancy(d) for d in info['detectors']]
values['queue'] = [self._get_queue(d) for d in info['detectors']]
values['phase'] = [self.prev_phase_indexes[node_id]]
node2values[node_id] = values
else:
states, rewards = [], []
global_reward = 0
for node_id, info in self.infos.items():
occupancy = [
node2values[node_id]['occupancy']]
queue = [node2values[node_id]['queue']]
phase = [node2values[node_id]['phase']]
reward = -np.sum(node2values[node_id]['queue'])
global_reward -= np.sum(node2values[node_id]['queue'])
for nnode_id in info['neighbors']:
occupancy.append(node2values[nnode_id]['occupancy'])
queue.append(node2values[nnode_id]['queue'])
phase.append(node2values[nnode_id]['phase'])
reward -= np.sum(node2values[nnode_id]['queue']) * 0.5
else:
states.append(np.concatenate((occupancy + queue + phase), dtype=(np.float32)))
rewards.append(reward)
else:
return (
states, rewards, global_reward)
def _set_yellows(self, actions):
"""Sets the yellow phase for nodes based on the given actions."""
for node_id, action in zip(self.node_ids, actions):
if action == 0:
pass
else:
info = self.infos[node_id]
prev_idx = self.prev_phase_indexes[node_id]
idx = (prev_idx + 1) % len(info['phases']['green'])
self.prev_phase_indexes[node_id] = idx
y = info['phases']['yellow'][prev_idx]
self._set_phase(node_id, y)
def _set_greens(self):
"""Sets the green phase for each node."""
for node_id, info in self.infos.items():
idx = self.prev_phase_indexes[node_id]
g = info['phases']['green'][idx]
self._set_phase(node_id, g)
def _set_phase(self, node_id, phase):
"""Sets the phase for a specific node."""
if self.prev_phases.get(node_id) != phase:
self.conn.trafficlight.setRedYellowGreenState(node_id, phase)
self.prev_phases[node_id] = phase
def step(self, actions):
"""Performs a step in the simulation based on the given actions."""
self._set_yellows(actions)
self._step(self.yellow_length)
self._set_greens()
self._step(self.rest_length)
self.curr_step += 1
states, rewards, global_reward = self._get_values()
done = self.curr_step >= self.episode_step
return (states, rewards, done, global_reward)
def reset(self):
"""Resets the simulation to its initial state."""
if not os.path.exists(self.path_init_state):
self._start()
self._save()
self._load()
self.curr_step = 0
self.prev_phases = {n: 'none' for n in self.node_ids}
self.prev_phase_indexes = {n: 0 for n in self.node_ids}
self._set_greens()
self._step(1)
states, _, _ = self._get_values()
return states
# okay decompiling .\env.cpython-38.pyc

+ 122
- 0
0217_explore_eval_gtr/0217_explore_eval_gtr.ipynb View File

@ -0,0 +1,122 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`node_id = '11053'`는 총 4현시로 구성되어 있고, 1현시와 2현시에서 오버랩이 일어난다.\n",
"\n",
"#### single ring\n",
"\n",
"3현시는 오버랩현시에 포함되지 않으므로\n",
"$a_3=b_3$\n",
"이어야 한다. (단, $a_3$은 A링 3현시의 현시시간.)\n",
"그런데\n",
"\\begin{align*}\n",
"a_3&=ag_3+ar_3+ay_3\\\\\n",
"b_3&=bg_3+br_3+by_3\n",
"\\end{align*}\n",
"에서\n",
"\\begin{align*}\n",
"ag_3+ar_3+ay_3 &= bg_3+br_3+by_3\\\\\n",
"ag_3 - bg_3 &= -ar_3+br_3 -ay_3+by_3\\\\\n",
"\\begin{bmatrix}0\\\\0\\\\1\\\\0\\\\0\\\\0\\\\-1\\\\0\\end{bmatrix}^T\n",
"\\begin{bmatrix}ag_1\\\\ag_2\\\\ag_3\\\\ag_4\\\\bg_1\\\\bg_2\\\\bg_3\\\\bg_4\\end{bmatrix}\n",
"&= (-1)((ar_3+ay_3)-(br_3+by_3))\\tag{$*$}\n",
"\\end{align*}\n",
"이어야 한다.\n",
"한편\n",
"\\begin{align*}\n",
"\\texttt{loss\\_lst}\n",
"&= \\texttt{r\\_lst} + \\texttt{y\\_loss\\_lst} + \\texttt{y\\_lst}\\\\\n",
"&=\\begin{bmatrix}ar_1\\\\ar_2\\\\ar_3\\\\ar_4\\\\br_1\\\\br_2\\\\br_3\\\\br_4\\end{bmatrix}\n",
"+\\begin{bmatrix}0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\end{bmatrix}\n",
"+\\begin{bmatrix}ay_1\\\\ay_2\\\\ay_3\\\\ay_4\\\\by_1\\\\by_2\\\\by_3\\\\by_4\\end{bmatrix}\n",
"\\end{align*}\n",
"이다. ($\\texttt{y\\_loss\\_lst}$는 편의상 0.3으로 이루어진 벡터로 표현함.)\n",
"따라서 식 $(*)$의 우변은\n",
"$$\n",
"(-1)((ar_3+ay_3)-(br_3+by_3))\n",
"=(-1)\\begin{bmatrix}0\\\\0\\\\1\\\\0\\\\0\\\\0\\\\-1\\\\0\\end{bmatrix}^T\\texttt{loss\\_lst}\n",
"$$\n",
"으로 쓸 수 있고, 따라서 식 $(*)$은 \n",
"\n",
"$$\n",
"\\begin{bmatrix}0\\\\0\\\\1\\\\0\\\\0\\\\0\\\\-1\\\\0\\end{bmatrix}^T\n",
"\\begin{bmatrix}ag_1\\\\ag_2\\\\ag_3\\\\ag_4\\\\bg_1\\\\bg_2\\\\bg_3\\\\bg_4\\end{bmatrix}\n",
" = (-1)\\begin{bmatrix}0\\\\0\\\\1\\\\0\\\\0\\\\0\\\\-1\\\\0\\end{bmatrix}^T\\texttt{loss\\_lst}\n",
"$$\n",
"\n",
"이다.\n",
"A링과 B링의 황색/적색시간이 같으면 ($ar_i=br_i$, $ay_i=by_i$ ; 대부분의 경우에 이것이 성립한다.) 위 식의 우변은 0이다.\n",
"이것은 $ag_3=bg_3$이라는 의미이다.\n",
"\n",
"\n",
"이상이 `evaluation_green_time_ratio.py`의 368, 369번째 줄의 의미이다."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### dual ring\n",
"\n",
"1현시와 2현시는 오버랩되므로\n",
"$a_1+a_2=b_1+b_2$\n",
"이어야 한다.\n",
"그러면\n",
"\\begin{align*}\n",
"ag_1+ar_1+ay_1+ag_2+ar_2+ay_2 &= bg_1+br_1+by_1+bg_2+br_2+by_2\\\\\n",
"ag_1 + ag_2 - bg_1 - bg_2 &= -ar_1-ay_1-ar_2-ay_2+br_1+by_1+br_2+by_2\\\\\n",
"\\begin{bmatrix}1\\\\1\\\\0\\\\0\\\\-1\\\\-1\\\\0\\\\0\\end{bmatrix}^T\n",
"\\begin{bmatrix}ag_1\\\\ag_2\\\\ag_3\\\\ag_4\\\\bg_1\\\\bg_2\\\\bg_3\\\\bg_4\\end{bmatrix}\n",
"&= (-1)((ar_1+ay_1+ar_2+ay_2)-(br_1+by_1+br_2+by_2))\\tag{$**$}\n",
"\\end{align*}\n",
"이어야 한다.\n",
"한편\n",
"\\begin{align*}\n",
"\\texttt{loss\\_lst}\n",
"&= \\texttt{r\\_lst} + \\texttt{y\\_loss\\_lst} + \\texttt{y\\_lst}\\\\\n",
"&=\\begin{bmatrix}ar_1\\\\ar_2\\\\ar_3\\\\ar_4\\\\br_1\\\\br_2\\\\br_3\\\\br_4\\end{bmatrix}\n",
"+\\begin{bmatrix}0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\\\0.3 \\end{bmatrix}\n",
"+\\begin{bmatrix}ay_1\\\\ay_2\\\\ay_3\\\\ay_4\\\\by_1\\\\by_2\\\\by_3\\\\by_4\\end{bmatrix}\n",
"\\end{align*}\n",
"에서 식 $(**)$의 우변은\n",
"$$\n",
"(-1)((ar_1+ay_1+ar_2+ay_2)-(br_1+by_1+br_2+by_2))\n",
"=(-1)\\begin{bmatrix}1\\\\1\\\\0\\\\0\\\\-1\\\\-1\\\\0\\\\0\\end{bmatrix}^T\\texttt{loss\\_lst}\n",
"$$\n",
"으로 쓸 수 있고, 따라서 식 $(*)$은 \n",
"\n",
"$$\n",
"\\begin{bmatrix}1\\\\1\\\\0\\\\0\\\\-1\\\\-1\\\\0\\\\0\\end{bmatrix}^T\n",
"\\begin{bmatrix}ag_1\\\\ag_2\\\\ag_3\\\\ag_4\\\\bg_1\\\\bg_2\\\\bg_3\\\\bg_4\\end{bmatrix}\n",
" = (-1)\\begin{bmatrix}1\\\\1\\\\0\\\\0\\\\-1\\\\-1\\\\0\\\\0\\end{bmatrix}^T\\texttt{loss\\_lst}\n",
"$$\n",
"\n",
"이다. 이것이 `evaluation_green_time_ratio.py`의 380, 381번째 줄의 의미이다."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "sts",
"language": "python",
"name": "sts"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

+ 87
- 0
0217_explore_eval_gtr/0217_explore_eval_gtr.md View File

@ -0,0 +1,87 @@
`node_id = '11053'`는 총 4현시로 구성되어 있고, 1현시와 2현시에서 오버랩이 일어난다.
#### single ring
3현시는 오버랩현시에 포함되지 않으므로
$a_3=b_3$
이어야 한다. (단, $a_3$은 A링 3현시의 현시시간.)
그런데
\begin{align*}
a_3&=ag_3+ar_3+ay_3\\
b_3&=bg_3+br_3+by_3
\end{align*}
에서
\begin{align*}
ag_3+ar_3+ay_3 &= bg_3+br_3+by_3\\
ag_3 - bg_3 &= -ar_3+br_3 -ay_3+by_3\\
\begin{bmatrix}0\\0\\1\\0\\0\\0\\-1\\0\end{bmatrix}^T
\begin{bmatrix}ag_1\\ag_2\\ag_3\\ag_4\\bg_1\\bg_2\\bg_3\\bg_4\end{bmatrix}
&= (-1)((ar_3+ay_3)-(br_3+by_3))\tag{$*$}
\end{align*}
이어야 한다.
한편
\begin{align*}
\texttt{loss\_lst}
&= \texttt{r\_lst} + \texttt{y\_loss\_lst} + \texttt{y\_lst}\\
&=\begin{bmatrix}ar_1\\ar_2\\ar_3\\ar_4\\br_1\\br_2\\br_3\\br_4\end{bmatrix}
+\begin{bmatrix}0.3 \\0.3 \\0.3 \\0.3 \\0.3 \\0.3 \\0.3 \\0.3 \end{bmatrix}
+\begin{bmatrix}ay_1\\ay_2\\ay_3\\ay_4\\by_1\\by_2\\by_3\\by_4\end{bmatrix}
\end{align*}
이다. ($\texttt{y\_loss\_lst}$는 편의상 0.3으로 이루어진 벡터로 표현함.)
따라서 식 $(*)$의 우변은
$$
(-1)((ar_3+ay_3)-(br_3+by_3))
=(-1)\begin{bmatrix}0\\0\\1\\0\\0\\0\\-1\\0\end{bmatrix}^T\texttt{loss\_lst}
$$
으로 쓸 수 있고, 따라서 식 $(*)$은
$$
\begin{bmatrix}0\\0\\1\\0\\0\\0\\-1\\0\end{bmatrix}^T
\begin{bmatrix}ag_1\\ag_2\\ag_3\\ag_4\\bg_1\\bg_2\\bg_3\\bg_4\end{bmatrix}
= (-1)\begin{bmatrix}0\\0\\1\\0\\0\\0\\-1\\0\end{bmatrix}^T\texttt{loss\_lst}
$$
이다.
A링과 B링의 황색/적색시간이 같으면 ($ar_i=br_i$, $ay_i=by_i$ ; 대부분의 경우에 이것이 성립한다.) 위 식의 우변은 0이다.
이것은 $ag_3=bg_3$이라는 의미이다.
이상이 `evaluation_green_time_ratio.py`의 368, 369번째 줄의 의미이다.
#### dual ring
1현시와 2현시는 오버랩되므로
$a_1+a_2=b_1+b_2$
이어야 한다.
그러면
\begin{align*}
ag_1+ar_1+ay_1+ag_2+ar_2+ay_2 &= bg_1+br_1+by_1+bg_2+br_2+by_2\\
ag_1 + ag_2 - bg_1 - bg_2 &= -ar_1-ay_1-ar_2-ay_2+br_1+by_1+br_2+by_2\\
\begin{bmatrix}1\\1\\0\\0\\-1\\-1\\0\\0\end{bmatrix}^T
\begin{bmatrix}ag_1\\ag_2\\ag_3\\ag_4\\bg_1\\bg_2\\bg_3\\bg_4\end{bmatrix}
&= (-1)((ar_1+ay_1+ar_2+ay_2)-(br_1+by_1+br_2+by_2))\tag{$**$}
\end{align*}
이어야 한다.
한편
\begin{align*}
\texttt{loss\_lst}
&= \texttt{r\_lst} + \texttt{y\_loss\_lst} + \texttt{y\_lst}\\
&=\begin{bmatrix}ar_1\\ar_2\\ar_3\\ar_4\\br_1\\br_2\\br_3\\br_4\end{bmatrix}
+\begin{bmatrix}0.3 \\0.3 \\0.3 \\0.3 \\0.3 \\0.3 \\0.3 \\0.3 \end{bmatrix}
+\begin{bmatrix}ay_1\\ay_2\\ay_3\\ay_4\\by_1\\by_2\\by_3\\by_4\end{bmatrix}
\end{align*}
에서 식 $(**)$의 우변은
$$
(-1)((ar_1+ay_1+ar_2+ay_2)-(br_1+by_1+br_2+by_2))
=(-1)\begin{bmatrix}1\\1\\0\\0\\-1\\-1\\0\\0\end{bmatrix}^T\texttt{loss\_lst}
$$
으로 쓸 수 있고, 따라서 식 $(*)$은
$$
\begin{bmatrix}1\\1\\0\\0\\-1\\-1\\0\\0\end{bmatrix}^T
\begin{bmatrix}ag_1\\ag_2\\ag_3\\ag_4\\bg_1\\bg_2\\bg_3\\bg_4\end{bmatrix}
= (-1)\begin{bmatrix}1\\1\\0\\0\\-1\\-1\\0\\0\end{bmatrix}^T\texttt{loss\_lst}
$$
이다. 이것이 `evaluation_green_time_ratio.py`의 380, 381번째 줄의 의미이다.

Loading…
Cancel
Save