558 lines
22 KiB
Typst
558 lines
22 KiB
Typst
#import "template.typ": *
|
|
|
|
|
|
// ==================================================
|
|
// Config Variables
|
|
// ==================================================
|
|
|
|
#show: base.with(
|
|
cur_domain: 1,
|
|
total_domain: 5,
|
|
domain_name: "Research",
|
|
domain_detail: "본질을 향한 여정",
|
|
date: "2026",
|
|
author: "Seungjun Lee",
|
|
main-hue: 60deg,
|
|
)
|
|
|
|
|
|
// ==================================================
|
|
// Main content
|
|
// ==================================================
|
|
|
|
#cover()
|
|
|
|
#counter(page).update(1)
|
|
|
|
#table_of_contents()
|
|
|
|
#domain_frame(
|
|
bg_img_path: "assets/research/bg.png",
|
|
font_color: color.oklch(95%, 0.01, 250deg),
|
|
chrome_color: color.oklch(80%, 0.01, 250deg),
|
|
title: [본질을 향한 여정],
|
|
)[
|
|
나는 세상을 하나의 질문으로 이해하고 싶었다. \
|
|
답을 알수록 새로운 질문이 늘어난다는 것도, \
|
|
그 질문들이 결국 하나로 이어지지 않는다는 것도 나중에 알았다.
|
|
|
|
생명 수업에서 인체를 배울 때 이 사실을 가장 선명하게 느꼈다. \
|
|
나는 인간이면서도 내 몸 안에서 무슨 일이 일어나는지 인지하지 못한다. \
|
|
신경계가, 세포가 어떻게 상호작용하는지 하나의 그림으로 설명하려 할수록 \
|
|
설명은 흐려졌다.
|
|
|
|
전체를 통째로 이해하려는 시도는 매번 그렇게 무너졌다. \
|
|
대신 남은 방법은 하나였다 — 쪼개서 이해하고, 그 이해들을 다시 쌓아 올리는 것. \
|
|
전체가 아니라 부분에서, 이론이 아니라 실제 관찰에서 다시 시작하는 것.
|
|
|
|
이후의 모든 연구는 이 하나의 발견에서 출발한다. \
|
|
그래프 알고리즘의 이론적 시간복잡도가 실제 실행 시간과 어긋나는 지점에서, \
|
|
사회 현상을 하나의 법칙이 아니라 여러 변수의 상호작용으로 다시 볼 때, \
|
|
그리고 인간의 선택이 이론적 모형을 벗어나는 순간에서 — \
|
|
나는 같은 방법을 반복했다. 쪼개고, 어긋난 지점을 찾고, 다시 쌓아 올렸다.
|
|
]
|
|
|
|
#activity_cover(
|
|
name: [Dijkstra Runtime Analysis],
|
|
hook: [
|
|
`Big-O` 시간 복잡도의 한계를 넘어, \
|
|
알고리즘의 세부 작업 실행 횟수와 단위 실행 시간을 고려한 \
|
|
가장 정확한 `Dijkstra` 알고리즘 런타임 예측 모델
|
|
],
|
|
)[]
|
|
|
|
#activity_intro(
|
|
title: "Big-O가 답하지 못하는 것",
|
|
)[
|
|
네비게이션, 자율주행, 우주항공 등 많은 현대 기술들에게 최적 경로를 탐색하는 것은 중요한 일이며,
|
|
Dijkstra 알고리즘은 최적 경로를 도출하는 가장 효율적인 알고리즘이다. \
|
|
그러나 자율주행과 같이 실시간성과 속도가 중요한 문제가 많아지자, 휴리스틱 기반의 A\* 알고리즘들이 적용되었다. 이들은 속도는 빠르지만, 항상 최적해를 보장하지는 않한다는 트레이드오프가 존재한다. \
|
|
상황에 따라 적절한 알고리즘을 선택하면 될 듯 하지만, Big-O 시간복잡도는 노드·간선 수 등 입력 크기에 따른 점근적 증가율만 나타낼 뿐, 상수항이나 그래프의 특성, 기기 성능 같은 요인은 반영하지 않기 때문에 Dijkstra의 실제 실행시간이 충분한지 알기 어렵다. \
|
|
그래서 *"이 트레이드오프를 감이 아닌 숫자로 계산해서 상황에 따른 정확한 알고리즘을 선택할 수는 없을까?"*라는 질문에서 출발하여 입력 그래프와 기기 성능만으로 Dijkstra의 실제 실행시간을 예측하는 모델을 연구했다.
|
|
|
|
IB 소논문 활동에서 시작해 계속 발전시켜 현재는 외부 학술지에도 기제된 연구로, 목표는 그래프의 노드 수, 간선 수, 가중치의 분산, 기기 성능만으로 이집 힙이 적용된 Dijkstra의 실행시간을 예측하는 것이다.
|
|
]
|
|
|
|
#let RS = math.italic("RS")
|
|
#let RSR = math.italic("RSR")
|
|
|
|
#activity_process(
|
|
title: "통제된 환경",
|
|
)[
|
|
#problem()[
|
|
실행 시간 측정의 신뢰도와 타당도를 높이기 위해서는 일정한 환경을 유지하는 것이 중요하다.
|
|
그러나 일반적인 데스크탑이나 노트북 환경에서는 통제된 환경을 구현하기 어렵다.
|
|
]
|
|
|
|
#hl[]
|
|
|
|
#solution()[
|
|
운영중인 홈서버의 Proxmox VE에 특정한 스펙의 Debian CT를 만들어 환경을 통제한다.
|
|
]
|
|
|
|
#figure(
|
|
image("assets/research/dijkstra/pve.png"),
|
|
caption: [CPU: AMD Ryzen 7 7700 8-Core Processor (4cores, Host) \/ RAM: 8GB \/ \
|
|
OS: Debian GNU/Linux 13 (trixie) \/ Kernal: Linux 6.8.12-17-pve \/
|
|
Python: Python 3.12],
|
|
)
|
|
]
|
|
|
|
#activity_process(
|
|
title: "Big-O의 한계를 넘어서다",
|
|
)[
|
|
#problem()[
|
|
`Big-O` 시간복잡도는 최고차항을 제외한 모든 항들을 무시하고, 계수마자 없앤다. \
|
|
그렇기 때문에 시간복잡도가 $O(n^2)$인 알고리즘에 $n$을 넣는다고 실행시간을 구할 수 없다.
|
|
]
|
|
|
|
#hl[]
|
|
|
|
#solution()[
|
|
Dijkstra 알고리즘을 의사코드를 기반으로 세부 작업들로 쪼개어 실행시간 식을 도출한다.
|
|
]
|
|
|
|
#block_equation(description: [
|
|
$V$ : 노드 수, $E$ : 간선 수, $RS$ : 키 감소 실행 횟수
|
|
])[
|
|
$
|
|
"Runtime" & = "Heap build" + "Min-node find" + "Vertex Iterate" + "Decrease key" \
|
|
& = "V" dot k_1 log(V) + V dot k_2 log(V) + E dot k_3 + RS dot k_4 log(V) \
|
|
& = V dot k_12 log(V) + E dot k_3 + RS dot k_4 log(V)
|
|
$
|
|
]
|
|
|
|
이진 힙이 적용된 Dijkstra 알고리즘은 크게 위의 4개의 동작으로 나눌 수 있다. \
|
|
각각의 시간 복잡도와 계수 그리고 실행 횟수의 곱을 모두 더하면 전체 실행 시간이 나온다. \
|
|
이때, 첫 두 항의 문자 부분이 같기 때문에 인수분해를 통해 두 식을 합친다.
|
|
이때 개별 항의 계수를 구하는 것이 목적이 아니기 때문에 두 계수를 합쳐 $k_12$라고 한다.
|
|
|
|
이 식을 통해 $V, E, RS, k_12, k_3, k_4$만 알면 Dijkstra의 실행시간을 구할 수 있게 된다.
|
|
]
|
|
|
|
#activity_process(
|
|
title: "존재하지 않는 데이터를 만들다",
|
|
)[
|
|
#problem()[
|
|
식을 학습시키려면 방대한 양의 실제 경로 데이터가 필요했다.
|
|
그러나 현실에서는 학습에 필요한 만큼의 실제 경로 데이터를 구할 수 없다.
|
|
]
|
|
|
|
#hl[]
|
|
|
|
#solution()[
|
|
실제 경로 데이터의 특성들(크기, 밀도, 가중치 분포 등)을 분석하여, 이를 토대로 가상의 경로 데이터를 제작한다.
|
|
]
|
|
|
|
#figure(image("assets/research/dijkstra/hist_original.png", width: 100%), caption: [원데이터 분포])
|
|
|
|
#grid(
|
|
columns: (auto, auto),
|
|
figure(
|
|
image("assets/research/dijkstra/hist_log.png"),
|
|
caption: [$log$ 데이터 Q-Q 플롯],
|
|
),
|
|
figure(
|
|
image("assets/research/dijkstra/Q-Q_log.png"),
|
|
caption: [$log$ 데이터 Q-Q 플롯],
|
|
),
|
|
)
|
|
|
|
원데이터의 분포와 Q-Q 플롯을 통해 데이터가 양의 왜도를 지닌 것을 파악하여, 가중치에 $log$를 취한 후 다시 Q-Q 플롯을 그리니 정규성을 보였다.
|
|
|
|
#figure(
|
|
table(
|
|
columns: (auto, auto),
|
|
[*그래프 밀도*], [$tilde.eq 1.02 dot 10^(-07)$],
|
|
[*가중치 평균*], [$tilde.eq 2950$],
|
|
[*표준편차 평균*], [$tilde.eq 4070$],
|
|
),
|
|
caption: [실제 경로 데이터 분석 값],
|
|
)
|
|
|
|
이를 바탕으로 그래프의 밀도와 가중치에 대한 추가적인 특성들을 분석하였다.
|
|
|
|
#figure(
|
|
table(
|
|
columns: (auto, auto),
|
|
[*노드 수*], [${2000 dot 2^k | k = 0, 1, 2, 3}$],
|
|
[*그래프 밀도*], [${10^k, 3 dot 10^k | k = -7, -6, ..., -1}$],
|
|
[*표준편차*], [${1000, 1500, 2000, 3000, 4000, 6000, 8000, 12000, 16000}$],
|
|
[*개수*], [$10$],
|
|
[*가중치 평균*], [$3000$],
|
|
[*시작 노드*], [$0$],
|
|
[*랜덤 시드*], [$42$],
|
|
),
|
|
caption: [데이터 생성 매개변수 조합],
|
|
)
|
|
|
|
분석 값들을 바탕으로 적절한 노드 수, 그래프 밀도, 가중치 분산 3개 변수의 쌍으로 로그 정규분포를 띄는 가상 그래프를 864,000개 생성했다.
|
|
|
|
#figure(
|
|
image("assets/research/dijkstra/synthetic_data_code.png"),
|
|
caption: u_link(
|
|
"https://gitea.seung6lee.com/seung6lee/dijkstra-runtime-analysis/src/branch/main/codes/experiments/synthetic_data/graph_generators/outdegree_graph_generator.py",
|
|
)[outdegree 기반 랜덤 경로 데이터 생성 프로그램],
|
|
)
|
|
|
|
#figure(
|
|
image("assets/research/dijkstra/synthetic_data.png"),
|
|
caption: u_link(
|
|
"https://gitea.seung6lee.com/seung6lee/dijkstra-runtime-analysis/src/branch/main/codes/results/real_data/raw/dimacs_s42.csv",
|
|
)[가상 경로 데이터 864,000개],
|
|
)
|
|
]
|
|
|
|
#activity_process(
|
|
title: "실행해야만 알 수 있는 값",
|
|
)[
|
|
#problem()[
|
|
모델을 학습시켜 가중치 $k$들을 알아낼 수 있다.
|
|
그리고 $V$와 $E$는 그래프에서 쉽계 계산할 수 있다.
|
|
그러나 $RS$는 Dijkstra를 실행하지 않으면 알 수 없다.
|
|
예측을 위해 실행이 선행되어야 하는 모순이 발생하는 것이다.
|
|
]
|
|
|
|
#hl[]
|
|
|
|
#solution()[
|
|
그래프의 특성만으로 Dijkstra 실행 없이 $RS$를 예측하는 방법을 찾는다.
|
|
]
|
|
|
|
#stack(
|
|
(
|
|
[$bold(RS)$ 재정의],
|
|
[
|
|
$RS$를 그 자체가 아니라, 다른 변수들로 쪼개어서 정의한다.
|
|
|
|
#block_equation()[
|
|
$ RS = "Relax Attemps" times "Relax Success Ratio" = E times RSR $
|
|
]
|
|
|
|
시도 횟수는 $E$라는 것을 알기에, $RSR$만 예측하면 된다. \
|
|
$RSR$은 비율이기에 절대량이 아닌 밀도나 분산 등에 영향을 받을 것이라고 판단한다.
|
|
#fill_break()
|
|
],
|
|
),
|
|
(
|
|
[$bold(RSR) thin \& thin bold(sigma)$],
|
|
[
|
|
#figure(
|
|
image("assets/research/dijkstra/sigma_rsr_01.png", width: 60%),
|
|
caption: [$V = 2000, thin D = 0.01$ 에서의 $sigma "vs" RSR$],
|
|
)
|
|
각 $(V, D)$ 쌍에 대해 $(sigma, RSR)$ 그래프를 그린 결과,
|
|
대부분의 경우 완벽한 로그 함수 관계를 보인다.
|
|
|
|
#grid(
|
|
columns: (1fr, 1fr),
|
|
gutter: 1em,
|
|
figure(
|
|
image("assets/research/dijkstra/sigma_rsr_02.png", width: 100%),
|
|
caption: [$V = 2000, thin D = 3 dot 10^(-5)$ 에서의 $sigma "vs" RSR$],
|
|
),
|
|
figure(
|
|
image("assets/research/dijkstra/sigma_rsr_03.png", width: 100%),
|
|
caption: [$V = 2000, thin D = 0.0003$ 에서의 $sigma "vs" RSR$],
|
|
),
|
|
)
|
|
그러나 $sigma$값에 관계없이 항상 $RSR=1$이거나, 경향성이 전혀 없는 경우도 나타난다.
|
|
|
|
#block_equation(description: [
|
|
$a, b$는 상수
|
|
])[
|
|
$ RSR = a dot log(sigma) + b $
|
|
]
|
|
|
|
$log$ 관계를 가정하고 위와 같이 $RSR$과 $sigma$의 관계를 식으로 나타내었다.
|
|
|
|
#fill_break()
|
|
],
|
|
),
|
|
(
|
|
[$bold(RSR) thin \& thin bold(D)$],
|
|
[
|
|
#figure(
|
|
image("assets/research/dijkstra/density_rsr.png", width: 60%),
|
|
caption: [$V = 10000, thin sigma = 0.3246$ 에서의 $D "vs" RSR$],
|
|
)
|
|
각 $(V, sigma)$ 쌍에 대해 $(D, RSR)$ 그래프를 그린 결과,
|
|
초반에 급격하게 감소하다 완만해지고 꼬리가 길게 남는 개형을 보인다. \
|
|
이는 멱법칙의 특성과 부합하여, $(log(D), log(RSR))$ 그래프를 그려본다.
|
|
|
|
#figure(
|
|
image("assets/research/dijkstra/density_rsr_loglog.png", width: 60%),
|
|
caption: [$V = 10000, thin sigma = 0.3246$ 에서의 $log(D) "vs" log(RSR)$],
|
|
)
|
|
특정 임계점을 기준으로 왼쪽은 항상 $RSR = 1$인 구간이고, 오른쪽은 두 변수가 완벽하게 멱법칙을 만족하는 구간이 나온다. \
|
|
이 임계점의 위치와 의미를 설명하려 했으나, 해당 지점의 $D$나 $log(D)$의 유의미한 특징을 발견하지 못하였다.
|
|
#fill_break()
|
|
],
|
|
),
|
|
(
|
|
[$bold(D)$ 분석],
|
|
[
|
|
$D$를 다른 변수로 대체해보았다. \
|
|
방향 그래프에서 $D = E / V(V - 1)$로 나타낼 수 있고,
|
|
평균 차수는 $macron(k) = E \/ V = (V - 1) D$로 나타낼 수 있다.
|
|
$D$대신 $macron(k)$를 대입해 그래프를 그려보았으며,
|
|
이때 $V$는 통제 변인으로 각 그래프에서 상수로 취급된다.
|
|
|
|
#grid(
|
|
columns: (1fr, 1fr),
|
|
figure(
|
|
image("assets/research/dijkstra/avgdeg_rsr_loglog.png"),
|
|
caption: [$V = 10000, thin sigma = 0.3246$ 에서의 $log(macron(k)) "vs" log(RSR)$],
|
|
),
|
|
figure(
|
|
image("assets/research/dijkstra/phase_histogram.png"),
|
|
caption: [$macron(k)$에 따른 경로 그래프 양상 분포],
|
|
),
|
|
)
|
|
|
|
그 결과, 임계점이 항상 $macron(k) = 1$인 구간에서 발생한다.
|
|
이 지점은 각 노드에서 출발하는 간선이 최소 1개씩 있는 경우이다.
|
|
|
|
이 현상은 Erdős-Rényi 모델의 3가지 상과 연결된다는 것을 파악했다.
|
|
해당 모델은 $G(n,p)$ 그래프를 $n p$의 값에 따라 아임계, 임계, 초임계 구간으로 분류한다.\
|
|
$sigma$ 분석에서의 예외 상황들도 아임계 구간과 임계 구간으로 설명이 가능해졌다.
|
|
|
|
#block_equation(description: [
|
|
$c, d$는 상수
|
|
])[
|
|
$ RSR = c dot macron(k)^d quad (macron(k) > 1) $
|
|
]
|
|
|
|
$macron(k) > 1$인 조건에서 위와 같이 $RSR$과 $d$의 관계를 식으로 나타내었다.
|
|
#fill_break()
|
|
],
|
|
),
|
|
(
|
|
[최종 식 도출],
|
|
[
|
|
$sigma$ 분석 과정에서 발견한 Erdős-Rényi 모델과의 연결성을 통해 $d$ 분석 과정에서의 한계를 극복하여, $sigma$와 $d$ 각각과 $RSR$간의 식을 확정하였다.
|
|
|
|
이때 $sigma$와 $d$는 그래프에서 서로 독립적이기 때문에 두 관계식을 곱하면 두 변수의 영향을 모두 반영하는 식을 도출할 수 있다.
|
|
|
|
#block_equation(description: [
|
|
$alpha, beta, gamma$는 상수
|
|
])[
|
|
$
|
|
RSR & = {a dot log(sigma) + b} times {c dot macron(k)^d} quad (macron(k) > 1) \
|
|
& = macron(k)^d times {a c dot log(sigma) + b c} \
|
|
& = macron(k)^alpha times {beta dot log(sigma) + gamma}
|
|
$
|
|
]
|
|
],
|
|
),
|
|
(
|
|
[회귀 분석],
|
|
[
|
|
#figure(
|
|
image("assets/research/dijkstra/rsr_regression.png", width: 50%),
|
|
caption: [비선형 회귀 결과 (
|
|
$alpha = 0.0612 plus.minus 0.000202, thin
|
|
beta = 0.928 plus.minus 0.000171, thin
|
|
gamma = -0.711 plus.minus 0.000183$)],
|
|
)
|
|
|
|
제작한 864,000개의 데이터에 대해 비선형 회귀를 진행하였더니 $RSR$에 대해 $R^2 = 0.9947$에 달하는 적합에 성공하였다.
|
|
|
|
이를 통해 Dijkstra 실행 없이도 $99%$의 정확도로 $RS$를 예측할 수 있게 되었다.
|
|
],
|
|
),
|
|
)
|
|
]
|
|
|
|
#activity_process(title: "다중공선성")[
|
|
#problem()[
|
|
#block_equation(description: [
|
|
$V$ : 노드 수, $E$ : 간선 수, $RS$ : 키 감소 실행 횟수
|
|
])[
|
|
$
|
|
"Runtime" = V dot k_12 log(V) + E dot k_3 + RS dot k_4 log(V)
|
|
$
|
|
]
|
|
|
|
이제 회귀 분석을 통해 $k_12, k_3, k_4$만 구하면 된다.
|
|
|
|
그러나 $k_12$와 $k_4$가 포함된 두 항이 유사하다.
|
|
공통적으로 $log(V)$가 있으며, $V$와 $RS$도 양의 상관관계를 가진다.
|
|
따라서 회귀분석 시행하면 다중공선성이 발생할 가능성이 높다.
|
|
]
|
|
|
|
#hl[]
|
|
|
|
#solution()[
|
|
모든 데이터를 한번에 회귀하는 것이 아니라, 고유한 $V$별로 부분 회귀를 하고 결과를 종합하는 방법을 고안했다.
|
|
|
|
#block_equation()[
|
|
$
|
|
"UC"_1(V) & = k_12 log(V) \
|
|
"UC"_2(V) & = k_4 log(V) \
|
|
"Runtime" & = V dot "UC"_1(V) + E dot k_3 + RS dot "UC"_2(V)
|
|
$
|
|
]
|
|
|
|
$V = V_i$인 데이터로 회귀를 하면 $"UC"_1(V_i), "UC"_2(V_i), k_3$가 도출된다. \
|
|
이때 $"UC"_1(V)$과 $"UC"_2(V)$는 $V$에 대해 $log$ 관계를 가져야하고, $k_3$는 상수여야한다.
|
|
]
|
|
]
|
|
|
|
#activity_process(title: "이론과 결과의 괴리")[
|
|
#callout(title: [$bold("UC"_1(V_i)), bold("UC"_2(V_i)), bold(k_3)$ 적합 결과])[
|
|
#grid(
|
|
columns: (1fr, 1fr),
|
|
gutter: 1em,
|
|
figure(
|
|
image("assets/research/dijkstra/node_uc1.png", width: 100%),
|
|
caption: [$"UC"_1(V)$],
|
|
),
|
|
figure(
|
|
image("assets/research/dijkstra/node_uc2.png", width: 100%),
|
|
caption: [$"UC"_2(V)$],
|
|
),
|
|
)
|
|
#figure(
|
|
image("assets/research/dijkstra/node_k3.png", width: 60%),
|
|
caption: [$"k"_3(V)$],
|
|
)
|
|
]
|
|
|
|
|
|
#problem()[
|
|
$"UC"_2(V)$는 $V$와 정확한 $log$ 관계를 보였다.\
|
|
그러나 $"UC"_1(V)$는 어떠한 경향성도 보이지 않았으며, \
|
|
$k_3$는 고정되지 않고 우하향의 추세를 보였다.
|
|
]
|
|
|
|
#hl[]
|
|
|
|
#solution()[
|
|
#figure(
|
|
image("assets/research/dijkstra/contribution_vs_N.png", width: 100%),
|
|
caption: [세부 작업별 전체 실행시간 차지 비율],
|
|
)
|
|
|
|
$"UC"_1(V)$의 경향성은 파악이 불가능했으나,
|
|
전체 런타임에서 $V dot "UC"_1(V)$항이 차지하는 비율이 $V lt.eq.slant 20000$ 인 지점에서 평균 $4.2 %$ 이하라는 것을 고려해 평균을 대푯값으로 사용하기로 하였다.
|
|
|
|
$k_3$의 우하향 추세는 파이썬의 캐싱 효과로 인한 것이라고 추정하였다. \
|
|
실행시간은 양수여야한다는 점을 고려하여 지수 포화 함수로 모델링하였다.
|
|
|
|
$"UC"_2(V)$는 $log$ 함수 적합을 통해 성공적으로 $k_4$를 구했다.
|
|
]
|
|
]
|
|
|
|
#activity_result(title: "예측할 수 있게 된 것")[
|
|
#block_equation(
|
|
title: [키 감소 횟수],
|
|
description: [$V$ : 노드 수, $E$ : 간선 수, $sigma$ : 가중치 표준편차],
|
|
)[
|
|
$
|
|
RSR(macron(k), sigma) & = macron(k)^0.0612 (0.928 log sigma - 0.711), quad
|
|
macron(k)(V, E) & = E \/ V \
|
|
RS(V, E, sigma) & = E dot RSR(macron(k)(V, E), sigma)
|
|
$
|
|
]
|
|
|
|
실행해야만 알 수 있던 $RS$를 세 변수만으로 계산할 수 있게 되었다.
|
|
|
|
#block_equation(
|
|
title: [단위 실행시간],
|
|
description: [단위 : 초],
|
|
)[
|
|
$
|
|
"UC"_1 & = 2.15 times 10^(-7) \
|
|
k_3(V) & = 1.59 times 10^(-7) e^(-5.67 times 10^(-5) V) + 4.37 times 10^(-8) \
|
|
"UC"_2(V) & = 1.06 times 10^(-6) log_2 V - 1.09 times 10^(-5)
|
|
$
|
|
]
|
|
|
|
세 값은 모두 $V$의 함수이거나 상수가 되어 식에 남아 있던 미지수가 전부 사라진다.
|
|
|
|
#block_equation(
|
|
title: [최종 모델],
|
|
description: [입력 : $V$, $E$, $sigma$],
|
|
)[
|
|
$
|
|
"Runtime"(V, E, sigma) = V dot "UC"_1 + E dot k_3(V) + RS(V, E, sigma) dot "UC"_2(V)
|
|
$
|
|
]
|
|
|
|
최종 식의 세 변수 모두 실행 전에 그래프에서 직접 추출할 수 있는 값이기에, \
|
|
*Dijkstra를 한 번도 실행하지 않고 실행시간을 예측할 수 있다.*
|
|
]
|
|
|
|
#activity_result(title: "남은 오차")[
|
|
#figure(
|
|
image("assets/research/dijkstra/comparison_plot.png"),
|
|
caption: [실제 경로 데이터에 대한 실행시간 예측과 $RS$ 예측],
|
|
)
|
|
|
|
#figure(
|
|
image("assets/research/dijkstra/predicted_vs_real.png", width: 60%),
|
|
caption: [생성 그래프에 대한 예측값과 실측값],
|
|
)
|
|
|
|
내삽에 대해 실행 시간 예측에 대해서 $96.9%$를 설명에 성공했다. \
|
|
게다가 실제 경로 데이터(외삽)에서도 $RS$예측에 대해 일관된 정확도를 보였다. \
|
|
그러나 실전 상황에서 그래프가 커질수록 실행시간 예측은 과대평가하는 경항이 보였다.\
|
|
|
|
이 결과들에서 내 연구의 의의와 한계가 뚜렷하게 드러난다. \
|
|
$RS$는 그래프의 구조만으로 결정되므로, 그래프의 근본적인 특성까지 쪼개었더니 정확하게 설명이 가능해졌으나, 실행시간은 파이썬 아래의 캐싱이나 하드웨어적 특성까지 쪼개지 못해 예측과 실측값 차이가 벌어졌다.
|
|
|
|
#table(
|
|
columns: (auto, 1fr),
|
|
table.header([*문제 상황*], [*극복 방법*]),
|
|
[학습 데이터의 부재], [분포를 분석해 864,000개를 직접 생성],
|
|
[실행해야 알 수 있는 값], [$E times RSR$로 쪼개 미지수를 하나로 축소],
|
|
[다중공선성], [$V$별 개별 회귀 후 기여도 기준으로 정밀도 배분],
|
|
)
|
|
|
|
모든 문제 상황에서는 직면한 큰 문제를 작은 단위들로 쪼개고, 작은 문제들의 해결책들을 종합하여 전체 문제를 해결해나갔다.
|
|
실행시간 측정을 위한 통제된 환경은 직접 구축한 홈서버의 가상화 환경(PVE)를 통해 구현했다.
|
|
|
|
이제 남은 오차는 파이썬이라는 언어 아래의 저차원에 위치해 있다. \
|
|
카이스트에서 언어와 하드웨어 수준의 저차원 요소를 배워 이 모델의 정확도를 끌어올리고, 완성한 모델을 실제 임베디드 시스템에서 알고리즘 선택의 지표로 적용하려 한다.
|
|
|
|
#context ref_evidence()
|
|
]
|
|
|
|
#add_evidence(
|
|
activity_ref: ref(label("Dijkstra Runtime Analysis")),
|
|
(
|
|
[소스 코드 및 자료],
|
|
u_link(
|
|
"https://gitea.seung6lee.com/seung6lee/dijkstra-runtime-analysis",
|
|
)[https://gitea.seung6lee.com/seung6lee/dijkstra-runtime-analysis],
|
|
),
|
|
(
|
|
[International Journal of STEAM 기재],
|
|
[
|
|
#image("assets/research/dijkstra/short_paper_01.png", height: 70%)
|
|
#image("assets/research/dijkstra/short_paper_02.png")
|
|
],
|
|
),
|
|
(
|
|
[정리 노트],
|
|
{
|
|
for i in range(1, 15) {
|
|
let path = "assets/research/dijkstra/notes/note_" + pad_zeros(i, 2) + ".jpg"
|
|
image(path)
|
|
}
|
|
},
|
|
),
|
|
(
|
|
[논문 본문],
|
|
{
|
|
for i in range(1, 17) {
|
|
let path = "assets/research/dijkstra/paper/paper_" + pad_zeros(i, 2) + ".png"
|
|
image(path)
|
|
}
|
|
},
|
|
),
|
|
)
|
|
|
|
#evidence()
|