diff --git a/241208圖著色問題/backtraceGraphColor.py b/241208圖著色問題/backtraceGraphColor.py new file mode 100644 index 0000000..f4e534e --- /dev/null +++ b/241208圖著色問題/backtraceGraphColor.py @@ -0,0 +1,76 @@ +lines = [ + ['A','B'], + ['A','C'], + ['B', 'C'], + ['D', 'C'], + ['E','C'], + ['E','F'], + ['C', 'F'], + ['F','G'], + ['F','H'], + ['G', 'H'], +] + +'''the verteices of {'POINT', (ADAJACENT POINTS)}''' +vertex_and_adjs = dict() + +class Vertex: + def __init__(self, name, adjacent): + self.color = None + self.name = name + self.adjacents = set(adjacent) + + def add_adjacent(self, adj): + self.adjacents.add(adj) + def __repr__(self): + return '{' + f'{self.name} - color: {self.color}, adjs: {self.adjacents}' + '}' + + +def add_to_graph(vertexes, lines): + for line in lines: + point_a = line[0] + point_b = line[1] + + if not point_a in vertexes: + vertexes[point_a] = Vertex(point_a, point_b) + else: + vertexes[point_a].add_adjacent(point_b) + + if not point_b in vertexes.keys(): + vertexes[point_b] = Vertex(point_b, point_a) + else: + vertexes[point_b].add_adjacent(point_a) + return vertexes + +graph = add_to_graph(vertex_and_adjs, lines) + +def is_available(graph, vertex, color): + adjacents_of_vertex = graph[vertex].adjacents + unavailable_colors = list(map(lambda x : graph[x].color, adjacents_of_vertex)) + print("vertex", vertex) + print("color", color) + print("UN_COLORS", unavailable_colors) + print("==") + + if color in unavailable_colors: + return False + else: + return True + +colors = ['1','2','3','4'] + +def graph_add_color(graph, vertex_id, colors): + graph_len = len(graph) + graph_list = list(graph) + for color in colors: + if is_available(graph, graph_list[vertex_id], color): + graph[graph_list[vertex_id]].color = color + if vertex_id < graph_len-1 \ + and graph_add_color(graph, vertex_id+1, colors): + return True + else: + continue + return False + +res = graph_add_color(graph, 0, colors) +print(res) diff --git a/241216tex/texput.dvi b/241216tex/texput.dvi new file mode 100644 index 0000000..210e3ea Binary files /dev/null and b/241216tex/texput.dvi differ diff --git a/README.md b/README.md index 6cffbcc..c4b50a6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # misc-codes +雜錯(cha̍p-chhò)ê程式碼 -雜七雜八的程式碼 \ No newline at end of file +雜七雜八的程式碼 diff --git a/linebreaking/.vscode/launch.json b/linebreaking/.vscode/launch.json new file mode 100644 index 0000000..7b3e519 --- /dev/null +++ b/linebreaking/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // 使用 IntelliSense 以得知可用的屬性。 + // 暫留以檢視現有屬性的描述。 + // 如需詳細資訊,請瀏覽: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/linebreaking/LineBreaking.html b/linebreaking/LineBreaking.html new file mode 100644 index 0000000..a477c59 --- /dev/null +++ b/linebreaking/LineBreaking.html @@ -0,0 +1,7503 @@ + + + + + +LineBreaking + + + + + + + + + + + + +
+ +
+ + +
+ +
+
+ + diff --git a/linebreaking/LineBreaking.ipynb b/linebreaking/LineBreaking.ipynb new file mode 100644 index 0000000..278f953 --- /dev/null +++ b/linebreaking/LineBreaking.ipynb @@ -0,0 +1,47 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "84f35666-acd1-488e-8f4e-5ba394862efb", + "metadata": {}, + "outputs": [], + "source": [ + "(*有關於LaTeX使用於斷行的演算法\n", + "\n", + "首先我們要制定一個字元(包含斷行後新生的連字號,以及空白)在斷行前、斷行後的寬度\n", + "\n", + "*)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b7ca64bd-a6be-4e40-a180-5a70602d2130", + "metadata": {}, + "outputs": [], + "source": [ + "(*假設這段字元 wordList,SP表達半形空白,HY表達連字號*)\n", + "let wordList = [\"no\"; \"HY\", \"thing\", \"SP\", \"can\", \"SP\", \"stop\",\"SP\", \"the\", \"SP\", \"crocodile\"]" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "OCaml default", + "language": "OCaml", + "name": "ocaml-jupyter-default" + }, + "language_info": { + "codemirror_mode": "text/x-ocaml", + "file_extension": ".ml", + "mimetype": "text/x-ocaml", + "name": "OCaml", + "nbconverter_exporter": null, + "pygments_lexer": "OCaml", + "version": "4.13.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/linebreaking/LineBreaking.md b/linebreaking/LineBreaking.md new file mode 100644 index 0000000..e4df7ba --- /dev/null +++ b/linebreaking/LineBreaking.md @@ -0,0 +1,284 @@ +```OCaml +(*有關於LaTeX使用於斷行的演算法 + +首先我們要制定一個字元(包含斷行後新生的連字號,以及空白)在斷行前、斷行後的寬度 + +*) +``` + + +```OCaml +(*假設這段字元 word segment list = wordSegList,SP表達半形空白,HY表達連字號*) +let wordSegList = ["no"; "HY"; "thing"; "SP"; "can"; "SP"; "stop";"SP"; "the"; "SP"; "cro"; "HY"; "co";"HY" ;"dile"; "cross"; "SP"; "it."] ;; +``` + + + val wordSegList : string list = + ["no"; "HY"; "thing"; "SP"; "can"; "SP"; "stop"; "SP"; "the"; "SP"; "cro"; + "HY"; "co"; "HY"; "dile"; "cross"; "SP"; "it."] + + + +```OCaml +(*現在轉成每個word segment都附帶長度的格式*) +(* sg: 文段 segment +ow : original width 原來的寬度 +hw : hyphenated width 該處指定為斷字後的寬度*) + +type segment_with_length = { sg: string; ow: float; hw: float} +``` + + + type segment_with_length = { sg : string; ow : float; hw : float; } + + + +```OCaml +(* 每個segment之長度*) +let segOwList = List.map (fun x -> match x with + | "SP" -> 1.0 (*SP 通常寬度為1*) + | "HY" -> 0.0 (*HY 連字點寬度為0*) + | _ -> float_of_int (String.length x)) (*以chars的長度來當做文字寬度 假設是等寬半形字元*) + wordSegList + +``` + + + val segOwList : float list = + [2.; 0.; 5.; 1.; 3.; 1.; 4.; 1.; 3.; 1.; 3.; 0.; 2.; 0.; 4.; 5.; 1.; 3.] + + + +```OCaml +(*每個segment在其被斷行時的長度 *) +let segHwList = List.map (fun x -> match x with + | "SP" -> 0.0 (*SP 通常斷行後寬度為0*) + | "HY" -> 1.0 (*HY 連字點斷行後為1*) + | _ -> infinity)(*不可能斷行的地方,寬度設做0*) + wordSegList +``` + + + val segHwList : float list = + [infinity; 1.; infinity; 0.; infinity; 0.; infinity; 0.; infinity; 0.; + infinity; 1.; infinity; 1.; infinity; infinity; 0.; infinity] + + + +```OCaml +(*3個列表組合 zip 在一起*) + +let segListCombined = List.combine (List.combine wordSegList segOwList) segHwList;; + +(*然後變成type segment_with_length的列表*) + +let segWithLengthList = List.map (fun i -> match i with + | ((sg,ow),hw) -> {sg = sg; ow = ow; hw = hw}) segListCombined + + +``` + + + val segListCombined : ((string * float) * float) list = + [(("no", 2.), infinity); (("HY", 0.), 1.); (("thing", 5.), infinity); + (("SP", 1.), 0.); (("can", 3.), infinity); (("SP", 1.), 0.); + (("stop", 4.), infinity); (("SP", 1.), 0.); (("the", 3.), infinity); + (("SP", 1.), 0.); (("cro", 3.), infinity); (("HY", 0.), 1.); + (("co", 2.), infinity); (("HY", 0.), 1.); (("dile", 4.), infinity); + (("cross", 5.), infinity); (("SP", 1.), 0.); (("it.", 3.), infinity)] + + + + val segWithLengthList : segment_with_length list = + [{sg = "no"; ow = 2.; hw = infinity}; {sg = "HY"; ow = 0.; hw = 1.}; + {sg = "thing"; ow = 5.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "can"; ow = 3.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "stop"; ow = 4.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "the"; ow = 3.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "cro"; ow = 3.; hw = infinity}; {sg = "HY"; ow = 0.; hw = 1.}; + {sg = "co"; ow = 2.; hw = infinity}; {sg = "HY"; ow = 0.; hw = 1.}; + {sg = "dile"; ow = 4.; hw = infinity}; + {sg = "cross"; ow = 5.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "it."; ow = 3.; hw = infinity}] + + + +```OCaml +(* +我們可以定義在第 n 處斷行=>除了斷行點以外的文字消失,的成本函數 cost(n),成本函數越小越好。 +這時後需要用動態規劃解決。 +badness (k, n)是指k~n-1處若塞於一行,且n處斷行時的懲罰函數(等下介紹),越小越好 +cost(n) = baness(0,n) 若其為有限,否則 min of k in 0...n-1 of badness(k, n) + cost(k) + +懲罰函數badness定義是:若lineWidth >= widthBetween(a,b),則為二者之差的三次方,否則是無限大。 +k >= n +badness(k, n) = (lineWidth - widthBetween(k, n) )^3 if lineWidth >= widthBetween(k+1, n) + infinity elsewhere + +widthBetween(a,b)係指 a到b 塞在一行時的寬度 +widthBetween(a,b) = hw[b] + (sum{i=a...b-1} of ow[i] +*) +open Printf + +let lineWidth = 12.0;; (*一行最大寬度*) + +let widthBetween a b = if a> b then raise (Failure "Exception: widthBetween a b, a <=b ") + else (List.nth segWithLengthList b).hw +. (sumOfOw a (b-1) segWithLengthList);; +let badness k n = let remainedSpaceWidth = lineWidth -. (widthBetween k n) in + if remainedSpaceWidth >= 0. then + remainedSpaceWidth ** 3. + else infinity;; + +let minIndex = ref 0;; (*cost(x)發生的最小的k)值*) + +(*動態規劃存放 (min cost, 其中的 k 滿足 min cost) 之處*) +(*格式: n (minValue, minIndex) *) +let costKStorage = Hashtbl.create 10;; + +let rec cost n = + if Hashtbl.mem costKStorage n then (*若是已經存儲了,即用裡面的值,避免重複運算*) + let (minValue, minIndex) = Hashtbl.find costKStorage n in + minValue + else if (badness 0 n) < infinity then (badness 0 n) + else + let compareList = List.init n (fun k -> (badness k n) +. cost k) in + (*找最小值*) + let findMin lst = List.fold_left min infinity lst in + let minValue = findMin compareList in (*最小值*) + (*找最小值所在的索引index值*) + let findMinIndex lst = List.fold_left + (fun pos i -> if (List.nth lst i) == minValue then i else pos) + (-1) + (List.init (List.length lst) (fun x -> x)) in + let minIndex = findMinIndex compareList in + let _ = Hashtbl.add costKStorage n (minValue, minIndex) in + minValue;; +``` + + + val lineWidth : float = 12. + + + + val widthBetween : int -> int -> float = + + + + val badness : int -> int -> float = + + + + val minIndex : int ref = {contents = 0} + + + + val costKStorage : ('_weak11, '_weak12) Hashtbl.t = + + + + val cost : int -> float = + + + +```OCaml +(*sumOfOw : 上文的(sum{i=a...b} of ow[i]*) +(* sumOfOwAux:輔助函數*) +let rec sumOfOwAux i start final sum list = +if i < start then sumOfOwAux (i+1) start final sum list +else if (i>= start && i <= final) then sumOfOwAux (i+1) start final (sum +. (List.nth list i).ow) list +else sum ;; + +let sumOfOw start final list = sumOfOwAux 0 start final 0.0 list;; +``` + + + val sumOfOwAux : + int -> int -> int -> float -> segment_with_length list -> float = + + + + val sumOfOw : int -> int -> segment_with_length list -> float = + + + +```OCaml +(*算到第11之處的成本*) +(*結果 +no thing +can stop +crocodile +...........^ +最多只能塞到箭頭處*) +cost 11;; +``` + + + - : float = 179. + + + +```OCaml +(*找 costKStorage 目前的值*) +let a = ref "" in + let _ = (Hashtbl.iter (fun x y -> let (y1,y2) = y in a := !a ^ (sprintf "%d : %f %d\n" x y1 y2)) costKStorage) in !a;; +``` + + + - : string = + "6 : inf -1\n2 : inf -1\n8 : inf -1\n7 : 152.000000 3\n13 : 153.000000 7\n12 : inf -1\n4 : inf -1\n9 : 28.000000 5\n11 : 179.000000 7\n0 : inf -1\n10 : inf -1\n" + + + +```OCaml +(*找出每個斷行點,回溯的搜尋HashTable*) + + +let rec findBreakPointAux res k = +if Hashtbl.mem costKStorage k then + let (minValue, minIndex) = Hashtbl.find costKStorage k in + findBreakPointAux (List.append res [k]) minIndex + else (List.append res [k]);; + +let findBreakPoint n = findBreakPointAux [] n;; +``` + + + val findBreakPointAux : int list -> int -> int list = + + + + val findBreakPoint : int -> int list = + + + +```OCaml +findBreakPoint 13;; +``` + + + findBreakPoint <-- 13 + findBreakPointAux <-- [] + findBreakPointAux --> + findBreakPointAux* <-- 13 + Hashtbl.find <-- + Hashtbl.find --> + Hashtbl.find* <-- + Hashtbl.find* --> + findBreakPointAux <-- [13] + findBreakPointAux --> + findBreakPointAux* <-- 7 + Hashtbl.find <-- + Hashtbl.find --> + Hashtbl.find* <-- + Hashtbl.find* --> + findBreakPointAux <-- [13; 7] + findBreakPointAux --> + findBreakPointAux* <-- 3 + findBreakPointAux* --> [13; 7; 3] + findBreakPointAux* --> [13; 7; 3] + findBreakPointAux* --> [13; 7; 3] + findBreakPoint --> [13; 7; 3] + - : int list = [13; 7; 3] + + + diff --git a/linebreaking/Untitled.html b/linebreaking/Untitled.html new file mode 100644 index 0000000..490f505 --- /dev/null +++ b/linebreaking/Untitled.html @@ -0,0 +1,7583 @@ + + + + + +Untitled + + + + + + + + + + + + +
+
+ + diff --git a/linebreaking/a.pdf b/linebreaking/a.pdf new file mode 100644 index 0000000..eed0473 Binary files /dev/null and b/linebreaking/a.pdf differ diff --git a/linebreaking/a.tex b/linebreaking/a.tex new file mode 100644 index 0000000..b0ff9db --- /dev/null +++ b/linebreaking/a.tex @@ -0,0 +1,28 @@ +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{(*有關於LaTeX使用於斷行的演算法} + +\CommentTok{首先我們要制定一個字元(包含斷行後新生的連字號,以及空白)在斷行前、斷行後的寬度} + +\CommentTok{*)} +\end{Highlighting} +\end{Shaded} + +\begin{Shaded} +\begin{Highlighting}[] +\CommentTok{(*假設這段字元 wordList,SP表達半形空白,HY表達連字號*)} +\KeywordTok{let}\NormalTok{ wordList = [}\StringTok{"no"}\NormalTok{; }\StringTok{"HY"}\NormalTok{; }\StringTok{"thing"}\NormalTok{; }\StringTok{"SP"}\NormalTok{; }\StringTok{"can"}\NormalTok{; }\StringTok{"SP"}\NormalTok{; }\StringTok{"stop"}\NormalTok{;}\StringTok{"SP"}\NormalTok{; }\StringTok{"the"}\NormalTok{; }\StringTok{"SP"}\NormalTok{; }\StringTok{"cro"}\NormalTok{; }\StringTok{"HY"}\NormalTok{; }\StringTok{"co"}\NormalTok{;}\StringTok{"HY"}\NormalTok{ ;}\StringTok{"dile"}\NormalTok{; }\StringTok{"cross"}\NormalTok{; }\StringTok{"SP"}\NormalTok{; }\StringTok{"it."}\NormalTok{] ;;} +\end{Highlighting} +\end{Shaded} + +\begin{verbatim} +val wordList : string list = + ["no"; "HY"; "thing"; "SP"; "can"; "SP"; "stop"; "SP"; "the"; "SP"; "cro"; + "HY"; "co"; "HY"; "dile"; "cross"; "SP"; "it."] +\end{verbatim} + +\begin{Shaded} +\begin{Highlighting}[] + +\end{Highlighting} +\end{Shaded} diff --git a/linebreaking/a.typ b/linebreaking/a.typ new file mode 100644 index 0000000..5af2e3e --- /dev/null +++ b/linebreaking/a.typ @@ -0,0 +1,270 @@ +```ocaml +(*有關於LaTeX使用於斷行的演算法 + +首先我們要制定一個字元(包含斷行後新生的連字號,以及空白)在斷行前、斷行後的寬度 + +*) +``` + +```ocaml +(*假設這段字元 word segment list = wordSegList,SP表達半形空白,HY表達連字號*) +let wordSegList = ["no"; "HY"; "thing"; "SP"; "can"; "SP"; "stop";"SP"; "the"; "SP"; "cro"; "HY"; "co";"HY" ;"dile"; "cross"; "SP"; "it."] ;; +``` + +``` +val wordSegList : string list = + ["no"; "HY"; "thing"; "SP"; "can"; "SP"; "stop"; "SP"; "the"; "SP"; "cro"; + "HY"; "co"; "HY"; "dile"; "cross"; "SP"; "it."] +``` + +```ocaml +(*現在轉成每個word segment都附帶長度的格式*) +(* sg: 文段 segment +ow : original width 原來的寬度 +hw : hyphenated width 該處指定為斷字後的寬度*) + +type segment_with_length = { sg: string; ow: float; hw: float} +``` + +``` +type segment_with_length = { sg : string; ow : float; hw : float; } +``` + +```ocaml +(* 每個segment之長度*) +let segOwList = List.map (fun x -> match x with + | "SP" -> 1.0 (*SP 通常寬度為1*) + | "HY" -> 0.0 (*HY 連字點寬度為0*) + | _ -> float_of_int (String.length x)) (*以chars的長度來當做文字寬度 假設是等寬半形字元*) + wordSegList + +``` + +``` +val segOwList : float list = + [2.; 0.; 5.; 1.; 3.; 1.; 4.; 1.; 3.; 1.; 3.; 0.; 2.; 0.; 4.; 5.; 1.; 3.] +``` + +```ocaml +(*每個segment在其被斷行時的長度 *) +let segHwList = List.map (fun x -> match x with + | "SP" -> 0.0 (*SP 通常斷行後寬度為0*) + | "HY" -> 1.0 (*HY 連字點斷行後為1*) + | _ -> infinity)(*不可能斷行的地方,寬度設做0*) + wordSegList +``` + +``` +val segHwList : float list = + [infinity; 1.; infinity; 0.; infinity; 0.; infinity; 0.; infinity; 0.; + infinity; 1.; infinity; 1.; infinity; infinity; 0.; infinity] +``` + +```ocaml +(*3個列表組合 zip 在一起*) + +let segListCombined = List.combine (List.combine wordSegList segOwList) segHwList;; + +(*然後變成type segment_with_length的列表*) + +let segWithLengthList = List.map (fun i -> match i with + | ((sg,ow),hw) -> {sg = sg; ow = ow; hw = hw}) segListCombined + +``` + +``` +val segListCombined : ((string * float) * float) list = + [(("no", 2.), infinity); (("HY", 0.), 1.); (("thing", 5.), infinity); + (("SP", 1.), 0.); (("can", 3.), infinity); (("SP", 1.), 0.); + (("stop", 4.), infinity); (("SP", 1.), 0.); (("the", 3.), infinity); + (("SP", 1.), 0.); (("cro", 3.), infinity); (("HY", 0.), 1.); + (("co", 2.), infinity); (("HY", 0.), 1.); (("dile", 4.), infinity); + (("cross", 5.), infinity); (("SP", 1.), 0.); (("it.", 3.), infinity)] + + + +val segWithLengthList : segment_with_length list = + [{sg = "no"; ow = 2.; hw = infinity}; {sg = "HY"; ow = 0.; hw = 1.}; + {sg = "thing"; ow = 5.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "can"; ow = 3.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "stop"; ow = 4.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "the"; ow = 3.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "cro"; ow = 3.; hw = infinity}; {sg = "HY"; ow = 0.; hw = 1.}; + {sg = "co"; ow = 2.; hw = infinity}; {sg = "HY"; ow = 0.; hw = 1.}; + {sg = "dile"; ow = 4.; hw = infinity}; + {sg = "cross"; ow = 5.; hw = infinity}; {sg = "SP"; ow = 1.; hw = 0.}; + {sg = "it."; ow = 3.; hw = infinity}] +``` + +```ocaml +(* +我們可以定義在第 n 處斷行=>除了斷行點以外的文字消失,的成本函數 cost(n),成本函數越小越好。 +這時後需要用動態規劃解決。 +badness (k, n)是指k~n-1處若塞於一行,且n處斷行時的懲罰函數(等下介紹),越小越好 +cost(n) = baness(0,n) 若其為有限,否則 min of k in 0...n-1 of badness(k, n) + cost(k) + +懲罰函數badness定義是:若lineWidth >= widthBetween(a,b),則為二者之差的三次方,否則是無限大。 +k >= n +badness(k, n) = (lineWidth - widthBetween(k, n) )^3 if lineWidth >= widthBetween(k+1, n) + infinity elsewhere + +widthBetween(a,b)係指 a到b 塞在一行時的寬度 +widthBetween(a,b) = hw[b] + (sum{i=a...b-1} of ow[i] +*) +open Printf + +let lineWidth = 12.0;; (*一行最大寬度*) + +let widthBetween a b = if a> b then raise (Failure "Exception: widthBetween a b, a <=b ") + else (List.nth segWithLengthList b).hw +. (sumOfOw a (b-1) segWithLengthList);; +let badness k n = let remainedSpaceWidth = lineWidth -. (widthBetween k n) in + if remainedSpaceWidth >= 0. then + remainedSpaceWidth ** 3. + else infinity;; + +let minIndex = ref 0;; (*cost(x)發生的最小的k)值*) + +(*動態規劃存放 (min cost, 其中的 k 滿足 min cost) 之處*) +(*格式: n (minValue, minIndex) *) +let costKStorage = Hashtbl.create 10;; + +let rec cost n = + if Hashtbl.mem costKStorage n then (*若是已經存儲了,即用裡面的值,避免重複運算*) + let (minValue, minIndex) = Hashtbl.find costKStorage n in + minValue + else if (badness 0 n) < infinity then (badness 0 n) + else + let compareList = List.init n (fun k -> (badness k n) +. cost k) in + (*找最小值*) + let findMin lst = List.fold_left min infinity lst in + let minValue = findMin compareList in (*最小值*) + (*找最小值所在的索引index值*) + let findMinIndex lst = List.fold_left + (fun pos i -> if (List.nth lst i) == minValue then i else pos) + (-1) + (List.init (List.length lst) (fun x -> x)) in + let minIndex = findMinIndex compareList in + let _ = Hashtbl.add costKStorage n (minValue, minIndex) in + minValue;; +``` + +``` +val lineWidth : float = 12. + + + +val widthBetween : int -> int -> float = + + + +val badness : int -> int -> float = + + + +val minIndex : int ref = {contents = 0} + + + +val costKStorage : ('_weak11, '_weak12) Hashtbl.t = + + + +val cost : int -> float = +``` + +```ocaml +(*sumOfOw : 上文的(sum{i=a...b} of ow[i]*) +(* sumOfOwAux:輔助函數*) +let rec sumOfOwAux i start final sum list = +if i < start then sumOfOwAux (i+1) start final sum list +else if (i>= start && i <= final) then sumOfOwAux (i+1) start final (sum +. (List.nth list i).ow) list +else sum ;; + +let sumOfOw start final list = sumOfOwAux 0 start final 0.0 list;; +``` + +``` +val sumOfOwAux : + int -> int -> int -> float -> segment_with_length list -> float = + + + +val sumOfOw : int -> int -> segment_with_length list -> float = +``` + +```ocaml +(*算到第11之處的成本*) +(*結果 +no thing +can stop +crocodile +...........^ +最多只能塞到箭頭處*) +cost 11;; +``` + +``` +- : float = 179. +``` + +```ocaml +(*找 costKStorage 目前的值*) +let a = ref "" in + let _ = (Hashtbl.iter (fun x y -> let (y1,y2) = y in a := !a ^ (sprintf "%d : %f %d\n" x y1 y2)) costKStorage) in !a;; +``` + +``` +- : string = +"6 : inf -1\n2 : inf -1\n8 : inf -1\n7 : 152.000000 3\n13 : 153.000000 7\n12 : inf -1\n4 : inf -1\n9 : 28.000000 5\n11 : 179.000000 7\n0 : inf -1\n10 : inf -1\n" +``` + +```ocaml +(*找出每個斷行點,回溯的搜尋HashTable*) + + +let rec findBreakPointAux res k = +if Hashtbl.mem costKStorage k then + let (minValue, minIndex) = Hashtbl.find costKStorage k in + findBreakPointAux (List.append res [k]) minIndex + else (List.append res [k]);; + +let findBreakPoint n = findBreakPointAux [] n;; +``` + +``` +val findBreakPointAux : int list -> int -> int list = + + + +val findBreakPoint : int -> int list = +``` + +```ocaml +findBreakPoint 13;; +``` + +``` +findBreakPoint <-- 13 +findBreakPointAux <-- [] +findBreakPointAux --> +findBreakPointAux* <-- 13 +Hashtbl.find <-- +Hashtbl.find --> +Hashtbl.find* <-- +Hashtbl.find* --> +findBreakPointAux <-- [13] +findBreakPointAux --> +findBreakPointAux* <-- 7 +Hashtbl.find <-- +Hashtbl.find --> +Hashtbl.find* <-- +Hashtbl.find* --> +findBreakPointAux <-- [13; 7] +findBreakPointAux --> +findBreakPointAux* <-- 3 +findBreakPointAux* --> [13; 7; 3] +findBreakPointAux* --> [13; 7; 3] +findBreakPointAux* --> [13; 7; 3] +findBreakPoint --> [13; 7; 3] +- : int list = [13; 7; 3] +``` diff --git a/linebreaking/pageniation.py b/linebreaking/pageniation.py new file mode 100644 index 0000000..594d413 --- /dev/null +++ b/linebreaking/pageniation.py @@ -0,0 +1,619 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[26]: + + +pageHeight = 28.0 + + +# In[4]: + + +textHeight = 0.8 +textSpaceheight = 0.6 +figHeight = 25.2 +alpha = 1 +beta = 0 + + +# In[2]: + + +lineList = [('WL', True), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('Fig', False), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('Fig', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('Fig', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', False), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('Fig', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', False), + ('WL', True), + ('WL', True), + ('WL', True), + ('WL', True), + ('Fig', True), + ('Fig', True), + ('WL', True), + ('WL', True), + ('WL', True)] + + +# In[8]: + + +lineAssignInfo = dict() +figToRefer = {0 : 0} + + +# In[7]: + + +n = len(lineList) + +figAndRefer = dict() + +# In[53]: + + +def cost(n): + global pageHeight + global lineAssignInfo + global textHeight + global textSpaceheight + global alpha + global beta + if n == 0: + lineAssignInfo[n] = 0 + return 1 + min_cost = float("inf") + min_p = -1 + cost(n-1) + for p in range(n): + if previousSameItem(n) != -1 and p < lineAssignInfo[previousSameItem(n)]: + pass #cost = float("inf") + else: + # 對於所有的東西 + + input_texts_in_p = [k for k, v in lineAssignInfo.items() if v == p] + words_len_in_p = len(list(filter( + lambda i : lineList[i][0] == "WL" or lineList[i][0] == "EndOfPara", input_texts_in_p))) + + figs_len_in_p = len(list(filter( lambda i : lineList[i][0] == "Fig", input_texts_in_p))) + + input_texts_height_in_p = words_len_in_p * (textHeight + textSpaceheight) \ + + figs_len_in_p * (figHeight + textSpaceheight) - textSpaceheight + if (lineList[n][0] in ["WL", "EndOdPara"]) and input_texts_height_in_p + textSpaceheight + textHeight > pageHeight: + pass #cost = float("inf") + elif lineList[n][0] == "Fig" and input_texts_height_in_p + textSpaceheight + figHeight > pageHeight: + pass + else: + temp_max_page_no = p#max(p, max(lineAssignInfo.keys())) + if lineList[n][0] == "Fig": + print(f"fig n = {n}") #TMP + temp_total_diff = p - figRefererId(n) + sum([k - v for k, v in figToRefer.items()]) + else: + temp_total_diff = sum([k - v for k, v in figToRefer.items()]) + + tmp_cost_fun_of_p = temp_max_page_no * beta + temp_total_diff * alpha + print(f"n=={n}, p={p}, tmpCost = {temp_max_page_no}, {temp_total_diff}, lineAssignInfo = {lineAssignInfo}") + if min_cost > tmp_cost_fun_of_p: + min_cost = tmp_cost_fun_of_p + min_p = p + lineAssignInfo[n] = min_p + if lineList[n][0] == "Fig": + figToRefer[min_p] = lineAssignInfo[figRefererId(n)] + return min + + +def figRefererId(fig_id): + global figAndRefer + print(fig_id) #TMP + referer_id = -1 + for i in list(reversed(range(fig_id))): + if lineList[i][0] in ["WL", "EndOfPara"]: + referer_id = i + break + figAndRefer[fig_id] = referer_id + return referer_id + +def previousSameItem(n): + global lineList + previous_id = -1 + for i in list(reversed(range(n))): + if lineList[i][0] == lineList[n][0]: + previous_id = i + break + return previous_id + + +# In[54]: + + +cost(100) +print(lineAssignInfo) +print(figToRefer) +print(figAndRefer) \ No newline at end of file