In [3]:
(*我們先假設 P (i,j),意思是當裡面有 i 行文,j 張圖的時候,存放的分頁資訊,其型別為 Pagination*)
type pagination = {mutable isPagizable : bool; noOfPages : int; predecessor : int * int};;
Out[3]:
type pagination = {
  mutable isPagizable : bool;
  noOfPages : int;
  predecessor : int * int;
}
In [4]:
let t = 300;; (* 行數 *)
let f = 20;; (* 圖數 *)

let maxHeight = 25.0;;
let minHeight = 20.0;;

(*行屬性:height 高度,spaceHeight 其後空白高度,isPagizable 其後空白是否可分頁*)
type line = {height : float; spaceHeight : float; mutable isPagizable : bool};;

let tArray = Array.make (t+1) {height = 0.8; spaceHeight = 0.7; isPagizable = true};;

let fArray = Array.make (t+1) {height = 12.0; spaceHeight = 1.1; isPagizable = true};;

(*tArray與fArray 第0行是空行*)
let _ = tArray.(0) <- {height = 0.0; spaceHeight = 0.0; isPagizable = false} in
let _ = fArray.(0) <- {height = 0.0; spaceHeight = 0.0; isPagizable = false} in
for i = 1 to t do
  if i / 9 == 3 then
    let _ = tArray.(i).isPagizable <- false in ()
  else
  ()
done
Out[4]:
val t : int = 300
Out[4]:
val f : int = 20
Out[4]:
val maxHeight : float = 25.
Out[4]:
val minHeight : float = 20.
Out[4]:
type line = {
  height : float;
  spaceHeight : float;
  mutable isPagizable : bool;
}
Out[4]:
val tArray : line array =
  [|{height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = true};
    {height = 0.8; spaceHeight = 0.7; isPagizable = ...}; ...|]
Out[4]:
val fArray : line array =
  [|{height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = true};
    {height = 12.; spaceHeight = 1.1; isPagizable = ...}; ...|]
Out[4]:
- : unit = ()
In [5]:
(*連 p 0 0 都要加進去所以需要輸入 t+1 和 f+1 的矩陣*)
let p = Array.make (t+1) (Array.make (f+1) {isPagizable = false; noOfPages = -1; predecessor=(-1,-1)});;
Out[5]:
val p : pagination array array =
  [|[|{isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)}|];
    [|{isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)}|];
    [|{isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
      {isPagizable = false; noOfPages = ...; predecessor = ...}; ...|];
    ...|]
In [6]:
let nil = -1;; (*condition value*)


(* 圖片 k 對到哪一個文字*)
let referId k = 
if k < 1 then 1
else if k < 3 then 20
else if k < 6 then 40
else if k==7 then 42
else if k < 10 then 70
else if k == 11 then 80
else if k < 15 then 112
else if k == 16 then 120
else if k == 17 then 130
else 179

(*組頁*)
let makeOnePage (p : pagination array array) a b i j = 
  if a == i && b == j then false
  else if p.(i).(j).isPagizable == false then false
  else if referId j < i then false
  else 
  let textHeight = Array.fold_right (+.) (Array.map (fun x -> x.height) (Array.sub tArray (a+1) (i-a))) 0.0 in
  let textSpaceHeight = Array.fold_right (+.)  (Array.map (fun x -> x.height) (Array.sub tArray (a+1) (i-a-1))) 0.0 in
  let figHeight = Array.fold_right (+.)  (Array.map (fun x -> x.height) (Array.sub fArray (a+1) (i-a))) 0.0  in
  let figSpaceHeight = Array.fold_right (+.)  (Array.map (fun x -> x.height) (Array.sub tArray (a+1) (i-a-1))) 0.0 in
  let inputHeight = textHeight +. textSpaceHeight +. figHeight +. figSpaceHeight in
  if inputHeight > maxHeight then false
  else if inputHeight < minHeight then false
  else true;;

(*以下是分頁程式*)
let pagize p = 
let _ = p.(0).(0) <- {isPagizable = true; noOfPages = 0;  predecessor = (nil , nil)} in
for i=0 to t do
for j=0 to f do
    for a = 1 to i do
    for b = 1 to j do
        let canMakeOnePage =  makeOnePage p a b i j in
        if canMakeOnePage then
        let _ = p.(i).(j).isPagizable <- true in
        ()
        else
        ()
    done
    done
done
done;;
  
pagize p;;

p;;
Out[6]:
val nil : int = -1
Out[6]:
val referId : int -> int = <fun>
Out[6]:
val makeOnePage : pagination array array -> int -> int -> int -> int -> bool =
  <fun>
Out[6]:
val pagize : pagination array array -> unit = <fun>
Out[6]:
- : unit = ()
Out[6]:
- : pagination array array =
[|[|{isPagizable = true; noOfPages = 0; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)}|];
  [|{isPagizable = true; noOfPages = 0; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)}|];
  [|{isPagizable = true; noOfPages = 0; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = -1; predecessor = (-1, -1)};
    {isPagizable = false; noOfPages = ...; predecessor = ...}; ...|];
  ...|]
In [ ]:
let costFuncOfPredecessor p i j pred = 
  let  tracePage = ref [(i, j)] in
  let movablePred = ref pred in

  let _ =
     while !movablePred != (-1, -1) do
     let _ = tracePage := !movablePred :: !tracePage in
     let (x, y) = !movablePred in
     let _ =  tracePage := [p.(x).(y).predecessor] in  ()
     (*let _ = movablePred := p.(x).(y).predecessor in ()*)
     done
  in  !tracePage;;

costFuncOfPredecessor p 200 15 (199, 14);;