diff --git a/assets/research/bg.png b/assets/research/bg.png new file mode 100644 index 0000000..61e8798 Binary files /dev/null and b/assets/research/bg.png differ diff --git a/assets/research/dijkstra/E_vs_relax_attempts.png b/assets/research/dijkstra/E_vs_relax_attempts.png new file mode 100644 index 0000000..eb5c474 Binary files /dev/null and b/assets/research/dijkstra/E_vs_relax_attempts.png differ diff --git a/assets/research/dijkstra/Q-Q_log.png b/assets/research/dijkstra/Q-Q_log.png new file mode 100644 index 0000000..b1aea0f Binary files /dev/null and b/assets/research/dijkstra/Q-Q_log.png differ diff --git a/assets/research/dijkstra/Q-Q_original.png b/assets/research/dijkstra/Q-Q_original.png new file mode 100644 index 0000000..54e4f86 Binary files /dev/null and b/assets/research/dijkstra/Q-Q_original.png differ diff --git a/assets/research/dijkstra/avgdeg_rsr_loglog.png b/assets/research/dijkstra/avgdeg_rsr_loglog.png new file mode 100644 index 0000000..472f263 Binary files /dev/null and b/assets/research/dijkstra/avgdeg_rsr_loglog.png differ diff --git a/assets/research/dijkstra/comparison_plot.png b/assets/research/dijkstra/comparison_plot.png new file mode 100644 index 0000000..633e363 Binary files /dev/null and b/assets/research/dijkstra/comparison_plot.png differ diff --git a/assets/research/dijkstra/contribution_vs_N.png b/assets/research/dijkstra/contribution_vs_N.png new file mode 100644 index 0000000..06fa6c4 Binary files /dev/null and b/assets/research/dijkstra/contribution_vs_N.png differ diff --git a/assets/research/dijkstra/density_rsr.png b/assets/research/dijkstra/density_rsr.png new file mode 100644 index 0000000..8735f9b Binary files /dev/null and b/assets/research/dijkstra/density_rsr.png differ diff --git a/assets/research/dijkstra/density_rsr_loglog.png b/assets/research/dijkstra/density_rsr_loglog.png new file mode 100644 index 0000000..01e3d57 Binary files /dev/null and b/assets/research/dijkstra/density_rsr_loglog.png differ diff --git a/assets/research/dijkstra/hist_log.png b/assets/research/dijkstra/hist_log.png new file mode 100644 index 0000000..0e40b48 Binary files /dev/null and b/assets/research/dijkstra/hist_log.png differ diff --git a/assets/research/dijkstra/hist_original.png b/assets/research/dijkstra/hist_original.png new file mode 100644 index 0000000..6d1fb99 Binary files /dev/null and b/assets/research/dijkstra/hist_original.png differ diff --git a/assets/research/dijkstra/node_k3.png b/assets/research/dijkstra/node_k3.png new file mode 100644 index 0000000..193c912 Binary files /dev/null and b/assets/research/dijkstra/node_k3.png differ diff --git a/assets/research/dijkstra/node_uc1.png b/assets/research/dijkstra/node_uc1.png new file mode 100644 index 0000000..890fca6 Binary files /dev/null and b/assets/research/dijkstra/node_uc1.png differ diff --git a/assets/research/dijkstra/node_uc2.png b/assets/research/dijkstra/node_uc2.png new file mode 100644 index 0000000..41b1bd4 Binary files /dev/null and b/assets/research/dijkstra/node_uc2.png differ diff --git a/assets/research/dijkstra/notes/note_01.jpg b/assets/research/dijkstra/notes/note_01.jpg new file mode 100644 index 0000000..c4fbe74 Binary files /dev/null and b/assets/research/dijkstra/notes/note_01.jpg differ diff --git a/assets/research/dijkstra/notes/note_02.jpg b/assets/research/dijkstra/notes/note_02.jpg new file mode 100644 index 0000000..f46967f Binary files /dev/null and b/assets/research/dijkstra/notes/note_02.jpg differ diff --git a/assets/research/dijkstra/notes/note_03.jpg b/assets/research/dijkstra/notes/note_03.jpg new file mode 100644 index 0000000..fced346 Binary files /dev/null and b/assets/research/dijkstra/notes/note_03.jpg differ diff --git a/assets/research/dijkstra/notes/note_04.jpg b/assets/research/dijkstra/notes/note_04.jpg new file mode 100644 index 0000000..438bbd9 Binary files /dev/null and b/assets/research/dijkstra/notes/note_04.jpg differ diff --git a/assets/research/dijkstra/notes/note_05.jpg b/assets/research/dijkstra/notes/note_05.jpg new file mode 100644 index 0000000..e4e1dc1 Binary files /dev/null and b/assets/research/dijkstra/notes/note_05.jpg differ diff --git a/assets/research/dijkstra/notes/note_06.jpg b/assets/research/dijkstra/notes/note_06.jpg new file mode 100644 index 0000000..85777c6 Binary files /dev/null and b/assets/research/dijkstra/notes/note_06.jpg differ diff --git a/assets/research/dijkstra/notes/note_07.jpg b/assets/research/dijkstra/notes/note_07.jpg new file mode 100644 index 0000000..eae45c0 Binary files /dev/null and b/assets/research/dijkstra/notes/note_07.jpg differ diff --git a/assets/research/dijkstra/notes/note_08.jpg b/assets/research/dijkstra/notes/note_08.jpg new file mode 100644 index 0000000..917ed16 Binary files /dev/null and b/assets/research/dijkstra/notes/note_08.jpg differ diff --git a/assets/research/dijkstra/notes/note_09.jpg b/assets/research/dijkstra/notes/note_09.jpg new file mode 100644 index 0000000..67e68a3 Binary files /dev/null and b/assets/research/dijkstra/notes/note_09.jpg differ diff --git a/assets/research/dijkstra/notes/note_10.jpg b/assets/research/dijkstra/notes/note_10.jpg new file mode 100644 index 0000000..844503c Binary files /dev/null and b/assets/research/dijkstra/notes/note_10.jpg differ diff --git a/assets/research/dijkstra/notes/note_11.jpg b/assets/research/dijkstra/notes/note_11.jpg new file mode 100644 index 0000000..f0e0051 Binary files /dev/null and b/assets/research/dijkstra/notes/note_11.jpg differ diff --git a/assets/research/dijkstra/notes/note_12.jpg b/assets/research/dijkstra/notes/note_12.jpg new file mode 100644 index 0000000..227a0e1 Binary files /dev/null and b/assets/research/dijkstra/notes/note_12.jpg differ diff --git a/assets/research/dijkstra/notes/note_13.jpg b/assets/research/dijkstra/notes/note_13.jpg new file mode 100644 index 0000000..9b30f6a Binary files /dev/null and b/assets/research/dijkstra/notes/note_13.jpg differ diff --git a/assets/research/dijkstra/notes/note_14.jpg b/assets/research/dijkstra/notes/note_14.jpg new file mode 100644 index 0000000..1c7319d Binary files /dev/null and b/assets/research/dijkstra/notes/note_14.jpg differ diff --git a/assets/research/dijkstra/paper/paper_01.png b/assets/research/dijkstra/paper/paper_01.png new file mode 100644 index 0000000..2fc3c28 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_01.png differ diff --git a/assets/research/dijkstra/paper/paper_02.png b/assets/research/dijkstra/paper/paper_02.png new file mode 100644 index 0000000..d9fafe5 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_02.png differ diff --git a/assets/research/dijkstra/paper/paper_03.png b/assets/research/dijkstra/paper/paper_03.png new file mode 100644 index 0000000..8d692a6 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_03.png differ diff --git a/assets/research/dijkstra/paper/paper_04.png b/assets/research/dijkstra/paper/paper_04.png new file mode 100644 index 0000000..a9f4dcf Binary files /dev/null and b/assets/research/dijkstra/paper/paper_04.png differ diff --git a/assets/research/dijkstra/paper/paper_05.png b/assets/research/dijkstra/paper/paper_05.png new file mode 100644 index 0000000..6490df2 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_05.png differ diff --git a/assets/research/dijkstra/paper/paper_06.png b/assets/research/dijkstra/paper/paper_06.png new file mode 100644 index 0000000..8bb13db Binary files /dev/null and b/assets/research/dijkstra/paper/paper_06.png differ diff --git a/assets/research/dijkstra/paper/paper_07.png b/assets/research/dijkstra/paper/paper_07.png new file mode 100644 index 0000000..900ecba Binary files /dev/null and b/assets/research/dijkstra/paper/paper_07.png differ diff --git a/assets/research/dijkstra/paper/paper_08.png b/assets/research/dijkstra/paper/paper_08.png new file mode 100644 index 0000000..8817945 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_08.png differ diff --git a/assets/research/dijkstra/paper/paper_09.png b/assets/research/dijkstra/paper/paper_09.png new file mode 100644 index 0000000..ee9cdef Binary files /dev/null and b/assets/research/dijkstra/paper/paper_09.png differ diff --git a/assets/research/dijkstra/paper/paper_10.png b/assets/research/dijkstra/paper/paper_10.png new file mode 100644 index 0000000..28b7565 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_10.png differ diff --git a/assets/research/dijkstra/paper/paper_11.png b/assets/research/dijkstra/paper/paper_11.png new file mode 100644 index 0000000..fb57430 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_11.png differ diff --git a/assets/research/dijkstra/paper/paper_12.png b/assets/research/dijkstra/paper/paper_12.png new file mode 100644 index 0000000..b714919 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_12.png differ diff --git a/assets/research/dijkstra/paper/paper_13.png b/assets/research/dijkstra/paper/paper_13.png new file mode 100644 index 0000000..11629a3 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_13.png differ diff --git a/assets/research/dijkstra/paper/paper_14.png b/assets/research/dijkstra/paper/paper_14.png new file mode 100644 index 0000000..ad95f08 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_14.png differ diff --git a/assets/research/dijkstra/paper/paper_15.png b/assets/research/dijkstra/paper/paper_15.png new file mode 100644 index 0000000..4016f8e Binary files /dev/null and b/assets/research/dijkstra/paper/paper_15.png differ diff --git a/assets/research/dijkstra/paper/paper_16.png b/assets/research/dijkstra/paper/paper_16.png new file mode 100644 index 0000000..c6337c2 Binary files /dev/null and b/assets/research/dijkstra/paper/paper_16.png differ diff --git a/assets/research/dijkstra/phase_histogram.png b/assets/research/dijkstra/phase_histogram.png new file mode 100644 index 0000000..6290035 Binary files /dev/null and b/assets/research/dijkstra/phase_histogram.png differ diff --git a/assets/research/dijkstra/predicted_vs_real.png b/assets/research/dijkstra/predicted_vs_real.png new file mode 100644 index 0000000..24fce30 Binary files /dev/null and b/assets/research/dijkstra/predicted_vs_real.png differ diff --git a/assets/research/dijkstra/pve.png b/assets/research/dijkstra/pve.png new file mode 100644 index 0000000..209cf5e Binary files /dev/null and b/assets/research/dijkstra/pve.png differ diff --git a/assets/research/dijkstra/rsr_regression.png b/assets/research/dijkstra/rsr_regression.png new file mode 100644 index 0000000..e179e2d Binary files /dev/null and b/assets/research/dijkstra/rsr_regression.png differ diff --git a/assets/research/dijkstra/short_paper_01.png b/assets/research/dijkstra/short_paper_01.png new file mode 100644 index 0000000..4fe28e4 Binary files /dev/null and b/assets/research/dijkstra/short_paper_01.png differ diff --git a/assets/research/dijkstra/short_paper_02.png b/assets/research/dijkstra/short_paper_02.png new file mode 100644 index 0000000..0d259e9 Binary files /dev/null and b/assets/research/dijkstra/short_paper_02.png differ diff --git a/assets/research/dijkstra/sigma_rsr_01.png b/assets/research/dijkstra/sigma_rsr_01.png new file mode 100644 index 0000000..d103005 Binary files /dev/null and b/assets/research/dijkstra/sigma_rsr_01.png differ diff --git a/assets/research/dijkstra/sigma_rsr_02.png b/assets/research/dijkstra/sigma_rsr_02.png new file mode 100644 index 0000000..4ae0892 Binary files /dev/null and b/assets/research/dijkstra/sigma_rsr_02.png differ diff --git a/assets/research/dijkstra/sigma_rsr_03.png b/assets/research/dijkstra/sigma_rsr_03.png new file mode 100644 index 0000000..9006575 Binary files /dev/null and b/assets/research/dijkstra/sigma_rsr_03.png differ diff --git a/assets/research/dijkstra/synthetic_data.png b/assets/research/dijkstra/synthetic_data.png new file mode 100644 index 0000000..76915f9 Binary files /dev/null and b/assets/research/dijkstra/synthetic_data.png differ diff --git a/assets/research/dijkstra/synthetic_data_code.png b/assets/research/dijkstra/synthetic_data_code.png new file mode 100644 index 0000000..c138557 Binary files /dev/null and b/assets/research/dijkstra/synthetic_data_code.png differ diff --git a/notes/activity_template.md b/notes/activity_template.md new file mode 100644 index 0000000..de20952 --- /dev/null +++ b/notes/activity_template.md @@ -0,0 +1,36 @@ +# 1. Hook + +**예시** +> Big-O 시간 복잡도의 한계를 넘어, +알고리즘의 세부 작업 실행 횟수와 단위 실행 시간을 고려한 +가장 정확한 Dijkstra 알고리즘 런타임 예측 모델 + +짧은 Hook + +# 2. 프로젝트 소개 + +**예시** +> 네비게이션, 자율주행, 우주항공 등 많은 현대 기술들에게 최적 경로를 탐색하는 것은 중요한 일이며, Dijkstra 알고리즘은 최적 경로를 도출하는 가장 효율적인 알고리즘이다. \ +그러나 자율주행과 같이 실시간성과 속도가 중요한 문제가 많아지자, 휴리스틱 기반의 A* 알고리즘들이 적용되었다. 이들은 속도는 빠르지만, 항상 최적해를 보장하지는 않한다는 트레이드오프가 존재한다. \ +상황에 따라 적절한 알고리즘을 선택하면 될 듯 하지만, Big-O 시간복잡도는 실행 상황이 아닌 알고리즘만을 고려하기 때문에 Dijkstra의 실행시간이 충분한지 알기 어렵다. \ +그래서 **"이 트레이드오프를 감이 아닌 숫자로 계산해서 상황에 따른 정확한 알고리즘을 선택할 수는 없을까?"**라는 질문에서 출발하여 입력 그래프와 기기 성능만으로 Dijkstra의 실제 실행시간을 예측하는 모델을 연구했다. + +IB 소논문 활동에서 시작해 계속 발전시켜 현재는 외부 학술지에도 기제된 연구로, 목표는 그래프의 노드 수, 간선 수, 가중치의 분산, 기기 성능만으로 이집 힙이 적용된 Dijkstra의 실행시간을 예측하는 것이다. + + +- 제목 +- 배경 +- 문제 제시 +- 개인적 연결 (내가 관심을 갖게 된 이유) +- 활동 부가 설명 (육하원칙으로) + +# 3. 시행착오 + +- 제목 +- 문제 +- 해결 + +# 4. 결과 + +- 결과 +- 연결 diff --git a/research.typ b/research.typ new file mode 100644 index 0000000..ede5de6 --- /dev/null +++ b/research.typ @@ -0,0 +1,557 @@ +#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() diff --git a/template.typ b/template.typ index 9f574eb..e12f5ac 100644 --- a/template.typ +++ b/template.typ @@ -7,7 +7,7 @@ #let font-display = ("Source Serif 4 Display", "Source Han Serif K") #let font-subhead = ("Source Serif 4 Subhead", "Source Han Serif K") #let font-caption = ("Source Serif 4 Caption", "Source Han Serif K") -// #let font-code = +#let font-code = ("Source Code Pro", "Pretendard") #let color-surface = white #let color-ink = color.oklch(22%, 0.01, 250deg) @@ -52,12 +52,14 @@ ), ) +#let evidence-data = state("evidence-data", none) + // ================================================== // Util functions // ================================================== -#let pad-zeros(num, width) = { +#let pad_zeros(num, width) = { let s = str(num) "0" * calc.max(0, width - s.len()) + s } @@ -77,17 +79,33 @@ } #let heading_text(it) = { - if it.has("text") { + if type(it) == str { + it + } else if it == linebreak() { + " " + } else if it.has("text") { it.text } else if it.has("children") { it.children.map(heading_text).join("") - } else if it == linebreak() { - " " } else { "" } } +// Must be called from inside a context block. +#let cur_activity() = { + let m = meta.get() + let level1s = query(heading.where(level: 1, outlined: true)) + let n = counter(heading).get().at(0) + let cur = level1s.at(n - 1) + let prefix = str(m.cur_domain) + "." + str(n) + ". " + + ( + prefix: prefix, + name: heading_text(cur.body), + location: cur.location(), + ) +} // ================================================== // Body components @@ -115,7 +133,8 @@ block( width: 100%, inset: (x: 12pt, y: 18pt), - radius: 4pt, + spacing: 1.6em, + // radius: 4pt, fill: bg_c, stroke: (paint: border_c), )[ @@ -149,7 +168,7 @@ stroke: ( paint: c, thickness: line-width, - cap: "round", + // cap: "round", ), angle: 90deg, length: body-size.height + 15pt, @@ -202,20 +221,43 @@ ) } -#let block_equation(content) = { +#let block_equation(title: "", description: "", content) = context { + let cp = color-palette.get() + callout()[ + #set par( + spacing: 1em, + ) + #if title != "" { + kicker(color: cp.accent)[#title] + } + #content + + #if description != "" { + set text( + size: 9pt, + fill: color-ink-helper, + ) + align(right)[#description] + } ] } -#let stack(layers) = context { +#let u_link(url, content) = link(url)[ + #underline( + content, + ) +] + +#let stack(..layers) = context { let cp = color-palette.get() let radius = 12pt let gutter = 12pt let gap = 24pt let indent = radius + gutter - for (idx, (title, body)) in layers.enumerate() { + for (idx, (title, body)) in layers.pos().enumerate() { let is_last = idx == layers.len() - 1 block( @@ -274,6 +316,38 @@ } } +#let ref_evidence() = { + let ca = cur_activity() + + set ref( + supplement: "증빙 자료.", + ) + + align(bottom)[ + #hl[] + *활동 증빙 자료:* + #underline[#ref(label("Evidence) " + ca.name))] + ] +} + +#let add_evidence(activity_ref: none, ..content) = context { + let name = str(activity_ref.target) + let data = ( + ( + name, + content.pos().flatten(), + ), + ).to-dict() + + evidence-data.update(old => { + if old == none { + data + } else { + old + data + } + }) +} + #let header_template(dark: false, font_color: none, show_activity: false) = place( top + left, dy: 1cm, @@ -293,13 +367,10 @@ link((page: 1, x: 0pt, y: 0pt))[#m.cur_domain. #m.domain_name] h(1fr) if show_activity { - let level1s = query(heading.where(level: 1, outlined: true)) - let n = counter(heading).get().at(0) - let cur = level1s.at(n - 1) - let prefix = str(m.cur_domain) + "." + str(n) + ". " + let ca = cur_activity() link( - cur.location(), - prefix + cur.body, + ca.location, + ca.prefix + ca.name, ) } } @@ -345,7 +416,7 @@ ) #text(font: font-caption)[ - #pad-zeros(m.cur_domain, 2) / #pad-zeros(m.total_domain, 2) + #pad_zeros(m.cur_domain, 2) / #pad_zeros(m.total_domain, 2) ] #v(12pt) @@ -410,6 +481,7 @@ #heading(level: 1)[ #name ] + #label(heading_text(name)) #block_quote()[ #hook @@ -451,7 +523,7 @@ header: header_template(show_activity: true), footer: footer_template(), )[ - #kicker("결론") + #kicker("결과") #heading(level: 2)[ #title @@ -460,6 +532,51 @@ #content ] +#let evidence() = context { + let cp = color-palette.get() + let ed = evidence-data.get() + + page( + header: header_template(), + footer: footer_template(), + )[ + #set heading(numbering: (..nums) => { + numbering("A", nums.at(1)) + }) + #show heading.where(level: 2): it => { + let num = counter(heading).display( + (..nums) => numbering("A", nums.at(1)), + ) + + block[ + #num. #it.body + ] + } + + #show table.cell.where(x: 0): set text( + weight: 700, + fill: cp.accent, + ) + + #heading(level: 1, numbering: none)[ + 증빙 자료 + ] + + #let cnt = ed.len() + #for (name, data) in ed [ + #heading(level: 2, supplement: "evidence")[#name] + #label("Evidence) " + name) + + #table( + columns: (10em, 1fr), + ..data, + ) + + #{ cnt -= 1 } + #if cnt > 0 { pagebreak() } + ] + ] +} // ================================================== // Style Settings @@ -515,11 +632,19 @@ set par( leading: 1.2em, - spacing: 2.4em, + spacing: 1.8em, ) + show raw: set text(font: font-code) + show strong: set text(fill: cp.accent) + // underline config + set underline( + offset: 2pt, + stroke: (paint: cp.accent, thickness: 1pt), + ) + // list config show list: set par(leading: 0.8em) set list( @@ -536,6 +661,31 @@ spacing: 0.8em, ) + // image config + show image: set align(center) + show image: set par( + spacing: 1.6em, + ) + + // figure config + show figure: set text( + fill: color-ink-helper, + size: 10pt, + ) + + show figure.caption: it => { + "[ " + it.body + " ]" + } + + // table config + show table: set text(size: 10pt) + + set table( + inset: 0.8em, + align: left + top, + stroke: (paint: cp.rule), + ) + // heading config show heading.where(level: 1): set heading(numbering: (..nums) => ( str(cur_domain) + "." + nums.pos().map(str).join(".") + "." @@ -595,9 +745,11 @@ fill: color-ink-secondary, ) - block(above: 20pt)[ - #it - ] + if it.element.supplement.text != "evidence" { + block(above: 20pt)[ + #it + ] + } } // render content