From 9045520b570661d9755dacb8ba643952475b41ef Mon Sep 17 00:00:00 2001 From: seung6lee Date: Sat, 5 Sep 2026 09:44:49 +0900 Subject: [PATCH] change table of contents design, add activity outline --- research.typ | 149 +++++++++++++++++++----------------- template.typ | 211 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 212 insertions(+), 148 deletions(-) diff --git a/research.typ b/research.typ index c679707..c8183f1 100644 --- a/research.typ +++ b/research.typ @@ -55,15 +55,7 @@ #activity_cover( name: [Dijkstra Runtime Analysis], - hook: [ - `Big-O` 시간 복잡도의 한계를 넘어, \ - 알고리즘의 세부 작업 실행 횟수와 단위 실행 시간을 고려한 \ - 가장 정확한 `Dijkstra` 알고리즘 런타임 예측 모델 - ], -)[] - -#activity_intro( - title: "Big-O가 답하지 못하는 것", + hook: [Big-O가 버린 세부 실행비용을 다시 세우고, 실행해야만 알 수 있던 키 감소 횟수를 그래프 특성만으로 구해, 이진 힙 Dijkstra의 런타임 변동 96.9%를 실행 전에 설명한 모델.], )[ 네비게이션, 자율주행, 우주항공 등 많은 현대 기술들에게 최적 경로를 탐색하는 것은 중요한 일이며, Dijkstra 알고리즘은 최적 경로를 도출하는 가장 효율적인 알고리즘이다. \ @@ -74,11 +66,26 @@ IB 소논문 활동에서 시작해 계속 발전시켜 현재는 외부 학술지에도 기제된 연구로, 목표는 그래프의 노드 수, 간선 수, 가중치의 분산, 기기 성능만으로 이집 힙이 적용된 Dijkstra의 실행시간을 예측하는 것이다. ] +// #activity_intro( +// title: "Big-O가 답하지 못하는 것", +// )[ +// 네비게이션, 자율주행, 우주항공 등 많은 현대 기술들에게 최적 경로를 탐색하는 것은 중요한 일이며, +// Dijkstra 알고리즘은 최적 경로를 도출하는 가장 효율적인 알고리즘이다. \ +// 그러나 자율주행과 같이 실시간성과 속도가 중요한 문제가 많아지자, 휴리스틱 기반의 A\* 알고리즘들이 적용되었다. 이들은 속도는 빠르지만, 항상 최적해를 보장하지는 않한다는 트레이드오프가 존재한다. \ +// 상황에 따라 적절한 알고리즘을 선택하면 될 듯 하지만, Big-O 시간복잡도는 노드·간선 수 등 입력 크기에 따른 점근적 증가율만 나타낼 뿐, 상수항이나 그래프의 특성, 기기 성능 같은 요인은 반영하지 않기 때문에 Dijkstra의 실제 실행시간이 충분한지 알기 어렵다. \ +// 그래서 *"이 트레이드오프를 감이 아닌 숫자로 계산해서 상황에 따른 정확한 알고리즘을 선택할 수는 없을까?"*라는 질문에서 출발하여 입력 그래프와 기기 성능만으로 Dijkstra의 실제 실행시간을 예측하는 모델을 연구했다. + +// IB 소논문 활동에서 시작해 계속 발전시켜 현재는 외부 학술지에도 기제된 연구로, 목표는 그래프의 노드 수, 간선 수, 가중치의 분산, 기기 성능만으로 이집 힙이 적용된 Dijkstra의 실행시간을 예측하는 것이다. +// ] + +#activity_table() + #let RS = math.italic("RS") #let RSR = math.italic("RSR") #activity_process( - title: "통제된 환경", + title: [*통제된 환경*], + hook: [통제된 환경에서 벗어나다.], )[ #problem()[ 실행 시간 측정의 신뢰도와 타당도를 높이기 위해서는 일정한 환경을 유지하는 것이 중요하다. @@ -445,80 +452,80 @@ ] ] -#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) - $ - ] +// #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$를 세 변수만으로 계산할 수 있게 되었다. +// 실행해야만 알 수 있던 $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) - $ - ] +// #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$의 함수이거나 상수가 되어 식에 남아 있던 미지수가 전부 사라진다. +// 세 값은 모두 $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) - $ - ] +// #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를 한 번도 실행하지 않고 실행시간을 예측할 수 있다.* -] +// 최종 식의 세 변수 모두 실행 전에 그래프에서 직접 추출할 수 있는 값이기에, \ +// *Dijkstra를 한 번도 실행하지 않고 실행시간을 예측할 수 있다.* +// ] -#activity_result(title: "남은 오차")[ - #figure( - image("assets/research/dijkstra/comparison_plot.png"), - caption: [실제 경로 데이터에 대한 실행시간 예측과 $RS$ 예측], - ) +// #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: [생성 그래프에 대한 예측값과 실측값], - ) +// #figure( +// image("assets/research/dijkstra/predicted_vs_real.png", width: 60%), +// caption: [생성 그래프에 대한 예측값과 실측값], +// ) - 내삽에 대해 실행 시간 예측에 대해서 $96.9%$를 설명에 성공했다. \ - 게다가 실제 경로 데이터(외삽)에서도 $RS$예측에 대해 일관된 정확도를 보였다. \ - 그러나 실전 상황에서 그래프가 커질수록 실행시간 예측은 과대평가하는 경항이 보였다.\ +// 내삽에 대해 실행 시간 예측에 대해서 $96.9%$를 설명에 성공했다. \ +// 게다가 실제 경로 데이터(외삽)에서도 $RS$예측에 대해 일관된 정확도를 보였다. \ +// 그러나 실전 상황에서 그래프가 커질수록 실행시간 예측은 과대평가하는 경항이 보였다.\ - 이 결과들에서 내 연구의 의의와 한계가 뚜렷하게 드러난다. \ - $RS$는 그래프의 구조만으로 결정되므로, 그래프의 근본적인 특성까지 쪼개었더니 정확하게 설명이 가능해졌으나, 실행시간은 파이썬 아래의 캐싱이나 하드웨어적 특성까지 쪼개지 못해 예측과 실측값 차이가 벌어졌다. +// 이 결과들에서 내 연구의 의의와 한계가 뚜렷하게 드러난다. \ +// $RS$는 그래프의 구조만으로 결정되므로, 그래프의 근본적인 특성까지 쪼개었더니 정확하게 설명이 가능해졌으나, 실행시간은 파이썬 아래의 캐싱이나 하드웨어적 특성까지 쪼개지 못해 예측과 실측값 차이가 벌어졌다. - #table( - columns: (auto, 1fr), - table.header([*문제 상황*], [*극복 방법*]), - [학습 데이터의 부재], [분포를 분석해 864,000개를 직접 생성], - [실행해야 알 수 있는 값], [$E times RSR$로 쪼개 미지수를 하나로 축소], - [다중공선성], [$V$별 개별 회귀 후 기여도 기준으로 정밀도 배분], - ) +// #table( +// columns: (auto, 1fr), +// table.header([*문제 상황*], [*극복 방법*]), +// [학습 데이터의 부재], [분포를 분석해 864,000개를 직접 생성], +// [실행해야 알 수 있는 값], [$E times RSR$로 쪼개 미지수를 하나로 축소], +// [다중공선성], [$V$별 개별 회귀 후 기여도 기준으로 정밀도 배분], +// ) - 모든 문제 상황에서는 직면한 큰 문제를 작은 단위들로 쪼개고, 작은 문제들의 해결책들을 종합하여 전체 문제를 해결해나갔다. - 실행시간 측정을 위한 통제된 환경은 직접 구축한 홈서버의 가상화 환경(PVE)를 통해 구현했다. +// 모든 문제 상황에서는 직면한 큰 문제를 작은 단위들로 쪼개고, 작은 문제들의 해결책들을 종합하여 전체 문제를 해결해나갔다. +// 실행시간 측정을 위한 통제된 환경은 직접 구축한 홈서버의 가상화 환경(PVE)를 통해 구현했다. - 이제 남은 오차는 파이썬이라는 언어 아래의 저차원에 위치해 있다. \ - 카이스트에서 언어와 하드웨어 수준의 저차원 요소를 배워 이 모델의 정확도를 끌어올리고, 완성한 모델을 실제 임베디드 시스템에서 알고리즘 선택의 지표로 적용하려 한다. +// 이제 남은 오차는 파이썬이라는 언어 아래의 저차원에 위치해 있다. \ +// 카이스트에서 언어와 하드웨어 수준의 저차원 요소를 배워 이 모델의 정확도를 끌어올리고, 완성한 모델을 실제 임베디드 시스템에서 알고리즘 선택의 지표로 적용하려 한다. - #context ref_evidence() -] +// #context ref_evidence() +// ] #add_evidence( activity_ref: ref(label("Dijkstra Runtime Analysis")), diff --git a/template.typ b/template.typ index 1ce6340..cdf09b4 100644 --- a/template.typ +++ b/template.typ @@ -326,7 +326,7 @@ align(bottom)[ #hl[] *활동 증빙 자료:* - #underline[#ref(label("Evidence) " + ca.name))] + #underline[#ref(label("evidence) " + ca.name))] ] } @@ -364,7 +364,7 @@ )[ #context { let m = meta.get() - link((page: 1, x: 0pt, y: 0pt))[#m.cur_domain. #m.domain_name] + link((page: 2, x: 0pt, y: 0pt))[#m.cur_domain. #m.domain_name] h(1fr) if show_activity { let ca = cur_activity() @@ -441,17 +441,47 @@ ] } -// Table of contents templage function -#let table_of_contents() = page( - footer: footer_template(), -)[ - #context { - let m = meta.get() - heading(level: 1, outlined: false, numbering: none)[#m.cur_domain. #m.domain_name] - } +// Table of contents template function +#let table_of_contents() = context { + let cp = color-palette.get() + let m = meta.get() - #outline(title: none, depth: 2) -] + page( + footer: footer_template(), + )[ + #show outline.entry.where(level: 1): it => link(it.element.location())[ + #block(above: 25pt)[ + #grid( + columns: (1fr, auto), + align: horizon, + text(font: font-subhead, size: 15pt, weight: 700)[ + #it.indented(it.prefix(), heading_text(it.body())) + ], + text(size: 10pt, fill: color-ink-helper)[ + #it.page() + ], + ) + + #let desc = it.element.supplement + + #if desc != [domain] and desc != [evidence] { + text(fill: color-ink-helper, size: 10pt)[ + #it.element.supplement + ] + } + + #v(10pt) + + #line(length: 100%, stroke: (paint: cp.accent-faint, thickness: 0.5pt)) + ] + ] + + #heading(level: 1, outlined: false, numbering: none)[#m.cur_domain. #m.domain_name] + #label("table_of_contents") + + #outline(title: none, depth: 1) + ] +} // Domain frame template function #let domain_frame( @@ -477,7 +507,7 @@ #set text(fill: font_color) #show strong: set text(fill: font_color) - #heading(level: 1)[ + #heading(level: 1, supplement: [domain])[ #title ] @@ -485,21 +515,29 @@ ] // Activity cover template function -#let activity_cover(name: "", hook: "", content) = page( - header: header_template(), - footer: footer_template(), -)[ - #heading(level: 1)[ - #name - ] - #label(heading_text(name)) +#let activity_cover(name: "", hook: "", content) = context { + let cp = color-palette.get() - #block_quote()[ - #hook - ] + page( + header: header_template(), + footer: footer_template(), + fill: cp.cover-surface, + )[ + #show heading.where(level: 1): set block(above: 0em, below: 25pt) + #heading(level: 1, supplement: hook)[ + #name + ] + #label(heading_text(name)) - #content -] + #block_quote()[ + #hook + ] + + #v(25pt) + + #content + ] +} // Activity intro template function #let activity_intro(title: "", content) = page( @@ -508,21 +546,81 @@ )[ #kicker("프로젝트 소개") - #heading(level: 2)[ + #heading(level: 2, outlined: false)[ #title ] #content ] +#let activity_table() = context { + let cp = color-palette.get() + let ca = cur_activity() + let level1s = query(heading.where(level: 1, outlined: true)) + let n = counter(heading).get().at(0) + let sel = heading.where(level: 2, outlined: true).after(ca.location) + if n < level1s.len() { + sel = sel.before(level1s.at(n).location(), inclusive: false) + } + + page( + header: header_template(show_activity: true), + footer: footer_template(), + )[ + #show outline: it => [ + #line(length: 100%, stroke: (paint: cp.accent-faint, thickness: 0.5pt)) + + #it + ] + + #show outline.entry.where(level: 2): it => link(it.element.location())[ + #set par( + spacing: 1em, + ) + + #block(above: 15pt)[ + #grid( + columns: (1fr, auto), + align: horizon, + text(size: 12pt, weight: 700)[ + #it.body() + ], + text(size: 8pt, fill: color-ink-helper)[ + #it.page() + ], + ) + + #let desc = it.element.supplement + + #par( + spacing: 0pt, + leading: 0pt, + )[ + #text(fill: color-ink-helper, size: 10pt)[ + #it.element.supplement + ] + ] + + #line(length: 100%, stroke: (paint: cp.accent-faint, thickness: 0.5pt)) + ] + ] + + #heading(level: 2, outlined: false)[ + 시행착오 목차 + ] + + #outline(title: none, target: sel) + ] +} + // Activity process -#let activity_process(title: "", content) = page( +#let activity_process(title: "", hook: [], content) = page( header: header_template(show_activity: true), footer: footer_template(), )[ #kicker("시행착오") - #heading(level: 2)[ + #heading(level: 2, supplement: hook)[ #title ] @@ -551,9 +649,12 @@ header: header_template(), footer: footer_template(), )[ - #set heading(numbering: (..nums) => { - numbering("A", nums.at(1)) - }) + #set heading( + numbering: (..nums) => { + numbering("A", nums.at(1)) + }, + supplement: [evidence], + ) #show heading.where(level: 2): it => { let num = counter(heading).display( (..nums) => numbering("A", nums.at(1)), @@ -576,7 +677,7 @@ #let cnt = ed.len() #for (name, data) in ed [ #heading(level: 2, supplement: "evidence")[#name] - #label("Evidence) " + name) + #label("evidence) " + name) #table( columns: (10em, 1fr), @@ -719,50 +820,6 @@ fill: color-ink, ) - // outline config - set outline( - indent: 2em, - ) - - show outline: set par(leading: 1em) - - show outline.entry: it => link( - it.element.location(), - )[ - #grid( - columns: (1fr, auto), - it.indented(it.prefix(), heading_text(it.body())), it.page(), - ) - ] - - show outline.entry.where(level: 1): it => { - set text( - font: font-subhead, - size: 15pt, - weight: 700, - ) - - block(above: 50pt)[ - #it - #line(length: 100%, stroke: (paint: color-ink-secondary, thickness: 1pt)) - ] - } - - show outline.entry.where(level: 2): it => { - set text( - font: font-body, - size: 12pt, - weight: 400, - fill: color-ink-secondary, - ) - - if it.element.supplement.text != "evidence" { - block(above: 20pt)[ - #it - ] - } - } - // render content doc }