情報科学( 2 ) 対象のモデル化とデータ構造 ( 2 ). 連想メモリ( Associative memory ) 一般的な離散写像をデータモデル化したもの 例 数学の点数 山田 →65 ,鈴木 →83 ,田中 →71 ,山本 →95 , … cf. 配列は連続した整数の有限部分集合を定義域とする写像.

Slides:



Advertisements
Similar presentations
シミュレーション演習 G. 総合演習 ( Mathematica 演 習) システム創成情報工学科 テキスト作成: 藤尾 光彦 講義担当: 尾下 真樹.
Advertisements

アルゴリズムとデータ構造 第2回 線形リスト(復習).
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
基本情報技術概論 I 演習(第5回) 埼玉大学 理工学研究科 堀山 貴史
Generic programming と STL
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第4回 配列(2) 情報・知能工学系 山本一公
5.データ構造入門 5-1.連結リスト(Linked List) 5-2.スタック(Stack) 5-3.キュー(Queue)
全体ミーティング (4/25) 村田雅之.
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
基本情報技術概論(第4回) 埼玉大学 理工学研究科 堀山 貴史
2章 データ構造.
情報工学概論 (アルゴリズムとデータ構造)
プログラミング言語論 第4回 式の構文、式の評価
オペレーティングシステムJ/K 2004年11月4日
アルゴリズムとデータ構造 第3回基本的なデータ構造(リスト) 2015/10/28 アルゴリズムとデータ構造 2015.
第6章 2重ループ&配列 2重ループと配列をやります.
プログラミング論 II 電卓,逆ポーランド記法電卓
データ構造とアルゴリズム 第13回 スタックとキュー
アルゴリズムと データ構造 第4回 スタック・キュー.
アルゴリズムとデータ構造 第2回 線形リスト(復習その2).
①データ構造 ②アルゴリズム ③プログラム言語 ④マークアップ言語
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
二分探索木によるサーチ.
2009/10/16 いろいろなデータ構造 第3講: 平成21年10月16日 (金) 4限 E252教室 コンピュータアルゴリズム.
データ構造とアルゴリズム 第4回 リスト ~ データ構造(1)~.
データ構造とアルゴリズム (第2回) ー線形構造ー.
データ構造とアルゴリズム 第6回 キュー ~ データ構造(2)~.
プログラミング 4 記憶の割り付け.
プログラミング言語入門.
データ構造と アルゴリズム第4回 知能情報学メジャー 和田俊和.
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
アルゴリズムとデータ構造1 2005年7月1日
Cプログラミング演習 第10回 二分探索木.
アルゴリズムとプログラミング (Algorithms and Programming)
情報処理Ⅱ 第2回:2003年10月14日(火).
第2回課題 配布した通り.氏名・学生番号を忘れないこと.
プログラミング 3 スタックとキュー.
明星大学 情報学科 2012年度 後期   情報技術Ⅱ   第8回
アルゴリズムとデータ構造 2011年7月8日課題の復習
6.データ構造入門 6-1.連結リスト(Linked List) 6-2.スタック(Stack) 6-3.キュー(Queue)
15.cons と種々のデータ構造.
データ構造とアルゴリズム 第11回 リスト構造(1)
アルゴリズムとデータ構造 第3章 ヒープ 5月31日分
アルゴリズムとデータ構造 第3章 ヒープ 5月31日分の復習
情報数理Ⅱ 第11章 データ構造 平成29年1月18日.
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング 3 2 次元配列.
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
データ構造とアルゴリズム (第3回) 静岡大学工学部 安藤和敏
アルゴリズムからプログラムへ GRAPH-SEARCH
プログラミング入門 電卓を作ろう・パートI!!.
アルゴリズムとプログラミング (Algorithms and Programming)
オペレーティングシステムJ/K (管理のためのデータ構造)
第11回放送授業.
アルゴリズムとデータ構造1 2009年6月15日
ネットワーク・プログラミング Cプログラミングの基礎.
pf-6. スタック (Python プログラミング基礎を演習で学ぶシリーズ)
情報処理Ⅱ 2005年10月28日(金).
プログラミング 4 文字列.
アルゴリズムとデータ構造 2010年6月17日
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
データ構造と アルゴリズムI 第三回 知能情報学部 新田直也.
プログラミング入門2 第5回 配列 変数宣言、初期化について
情報処理Ⅱ 小テスト 2005年2月1日(火).
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング論 バイナリーサーチ 1.
Presentation transcript:

情報科学( 2 ) 対象のモデル化とデータ構造 ( 2 )

連想メモリ( Associative memory ) 一般的な離散写像をデータモデル化したもの 例 数学の点数 山田 →65 ,鈴木 →83 ,田中 →71 ,山本 →95 , … cf. 配列は連続した整数の有限部分集合を定義域とする写像 コンピュータのメモリの線形アドレスをうまく利用している 膨大な定義域に散らばるデータとその像の対をコンパクトに表現す る 人の名前の集合を辞書順序で並べた巨大な表を作れば,辞書を引くように 写像を計算することができる しかし, 1 つの教室は高々 50 人なので(定義域が小さいので) ムダ 一般的にはハッシュと呼ばれる計算メカニズムを利用して実現 配列のアクセスより時間コストが高い

ハッシュ( Hash ) marks = {" 山田 " => 65, " 鈴木 " => 83, " 田中 " => 71, " 山本 " => 95} marks[" 大田 "] = 75 marks[" 井上 "] = 48 # このようにどんどん定義域を広げていくことができる marks[" 鈴木 "] # 鈴木君の点を訊く # 最初の行と同じことは以下のようにしても可能 marks = Hash.new(0) # 登録されていない学生はとりあえず 0 点に marks[" 山田 "]=65 marks[" 鈴木 "]=83 marks[" 田中 "]=71 marks[" 山本 "]=95 Ruby 中カッコ に注意

大きさが不定のデータ構造 配列もレコードもデータを作るときに大きさが決まる あらかじめ必要な大きさが予想できない場合? 途中で大きさが変化する場合? 文字列はその典型例 あらかじめ大き目の文字の配列を用意 足りなくなったらもっと大きな配列を用意してコピー このようにシステムが裏方でがんばってくれる場合もある 多様なデータ構造についてシステムががんばってくれる ことは期待できない 不定の大きさのデータ構造にユーザが自分で対処する必要 あらかじめ大き目の配列を用意するのは一つの手 実際の情報が配列のどこまで入っているかを自分で管理 currentMaxarrayBody k+1 k レコード配列 未使用部分 k-1 k+1

中身サイズ可変の配列 # Ruby ではちょっと無理のある例だが … FillArray = Struct.new(:currentMax, :arrayBody) # FillArray と,先頭が大文字になっていることに注意 # とりあえずサイズ 100 の配列を用意 fillArray = FillArray.new(0, Array.new(100)) # 第 0 要素に "hello" ,第 1 要素に "world" を入れてみる fillArray.arrayBody[fillArray.currentMax] = "hello" fillArray.currentMax += 1 # currentMax を 1 増やす fillArray.arrayBody[fillArray.currentMax] = "world" fillArray.currentMax += 1 Ruby

再帰( recursion ) 落語の「頭山」 頭の上にできた水溜りを嘆いて,そこに飛び込んでしまった男の噺 ― 自分で自分に飛び込む ? 仕事を下請けに出したら,巡り巡ってその仕事の一部が自分に戻って きた 友達 A のことを紹介しようとして,「 A のいい加減なことといったら, A みたいにいい加減なんだ」と言ってしまった 辞典で「白い」を引いたら「雪のような色」と書いてあったが, 「雪」を引いたら「空から降ってくる,雨が凍った白く冷たいもの」 と書いてあった 「秘妙」という造語の意味を説明をしようとして,「『秘妙』という 言葉の意味は非常に秘妙であり,説明が難しい」と言ってしまった しかし,堂々巡りにならないのであれば, 再帰は非常に強力な計算の原理

再帰的定義 簡単な例 階乗の定義 factorial(n) ≡ if n<2 then 1 else n*factorial(n-1) Fibonacci 数の定義 fib(n) ≡ if n<2 then 1 else fib(n-1)+fib(n-2) ちゃんとした再帰的定義は堂々巡りにならず, いつかは終端に達する ある漢和辞典(明解漢和辞典 1927 年 )の例 九 八に一を足した數 八 七に一を足した數 … 二 一に一を足した數 一 對なき數.數の始め

リスト構造( list ) 必要な分だけをつないで使う 例 道順の説明 交差点ごとに直進,右折,左折を示す " 直進 " " 右折 "" 直進 "" 左折 " どこも指して いないことを 意味するポイ ンタ null また は nil " 直進 "" 右折 "" 直進 "" 左折 " " 直進 " いきなり途中の交差点が増えても(減っても)大丈夫 構造のほかの場所に影響を与えないで情報更新 [ex] 配列で同じことをしたらどうなるか ? 2 つのフィールドをもつセ ル ポインタは切ったり 張ったりできる

木構造( tree ) 数式の構造は木構造になじむ / + 1 - 3* **2 5* 数式を扱おうとすると,因数分解や展開 でどんどん数式の形が変わる. このようにあらかじめデータの大きさも 形も予測できない場合,ポインタを使っ て自由に大きさを変えられるとうれしい

再帰的データ構造 リスト構造 ::= セル | nil | 数や文字列などの基本データ型 セル ::= リスト構造とリスト構造の対 木構造 ::= 変数名 | 数 | 木構造と演算子と木構造の 3 組 ::= は「定義」の意味 | (縦棒)は「または」と読む リスト構造も木構造もいろいろなものがある. ここに示したのはその一例

再帰的データ構造定義の例 # 中置記法の数式に合わせて Expr = Struct.new(:left, :operator, :right) # 前のスライドの例を無理やり作ってみた Expr.new( Expr.new(3, :*, Expr.new(:x, :**, 2)), :-, Expr.new(5, :*, :x)), :/, Expr.new(:y, :+, 1)) Ruby :left と :right に Expr が出てくるので,本来 再帰的なデータ構造定 義だが, Ruby では陽 に Expr と書かなくてよい ので再帰であることが 見えにくい

基礎的なデータモデル スタック ここではオブジェクトとして定義( Ruby のオブジェク ト) キュー (待ち行列) 同じデータモデルの実現にもいろいろなデータ構造が ある グラフ構造(地下鉄路線図) 目的に合ったデータ構造の設計

スタック( stack ) 後入れ先出し( Last-in First-out )でデータを貯めるもの 原義:干草などを積み重ねたもの コンピュータ(特にプログラミング言語の処理系)では重要な概 念 しかし,「後入れ先出し」は一般社会では使わないことが推奨さ れる スーパーの倉庫「先入れ先出しを守れ」(賞味期限がある) 片付かない机の上は先入れ先出しがしにくい構造 例外:トランプの独り遊びには頻出 基本操作 push データを積む pop データを取り出す,降ろす (降ろさないで見るだけの操作も 通常はある) empty? 空っぽ?と聞く top bottom

スタックの定義 class Stack def initialize(size) # new = = -1 がスタックのトップを表す.最初はボトムを指す -1 . end def push(obj) # obj += と同じ意味 = obj # 前頁の図では上のほうが番地が大きい end def -= 1 # 先にトップへのポインタを減らす + 1] # ∵ 最後の式が値となるため end def == -1 end end Ruby この定義の後に 試してみよう s = Stack.new(100) s.push :abc s.push :def p s.pop

キュー(待ち行列, queue ) 先入れ先出し( First-in First-out )でデータを貯めるもの 要するに先着順( First-Come First-Service ) OS ,ネットワーク,シミュレーション,探索などで使われる 基本操作 enqueue データをキューに並ばせる(末尾につける) dequeue キューの先頭からデータを取る empty? キューが空? top last tail この順に並んでる

キューの3通りのデータ構造 ( 1 ) 配列 top=i last=j i j 配列 top=m last=n m n 列の最大長さよりも大きい 1次元配列を用意し,それを 循環的に使う top と last のほかにキューの 長さを表す変数を使うことも ある 変数 tail が,次にデータが 入るところの添え字を表す 方法もある(こちらのほうが 普通) 1次元配列とそれの添え字を値としてとる 2 個の変数で 表す まず,複雑なデータ構造の定義がしにくい言語での方法

配列 top=i last=j i j 配列 top=m last=n m n enqueue

配列 top=i last=j+1 i j+1 配列 top=m last=n m n enqueue

配列 top=i last=j+1 i j+1 配列 top=m last=n m n enqueue

配列 top=i last=j+1 i j+1 配列 top=m last=n+1 mn+1 enqueue

配列 top=i last=j i j 配列 top=m last=n m n dequeue

配列 top=i+1 last=j i+1 j top=m last=n m n dequeue 配列

top=i last=j i+1 j top=m+1 last=n m+1 n dequeue 配列

キューの3通りのデータ構造 ( 2 ) j レコード(簡略に書いた) array i 変数と配列を一体化したレコードにする方法 ここでは,キューの最後を次に並ぶ場所の添え字にす る さらにキューに並んでいるデータの個数もレコードに 入れる toptaillength ijn n

j i toptaillength ijn n enqueue array

j+1 i toptaillength ijn+1 enqueue array

j i toptaillength ijn n dequeue array

j i+1 toptaillength ijn-1 dequeue array

キューの3通りのデータ構造 (3) レコードの中で配列の代わりにリスト構造 キューの最大長さが予測できないときに便利 リスト構造は先頭はともかく,末尾にアクセスするのに時間がかか る しかし,工夫すると,先頭も末尾もほぼ同じ速度でアクセス可能 以下はその一例(ほかにいっぱいデータモデル化の方法がある) top last キューへのポインタ 循環リストになっている

キューの3通りのデータ構造 (3) 続き top last キューへのポインタ enqueue どちらの操作もキューの長さに依存しない一定時間で処理することが可能 (キューが空から出発する,あるいは空になるときは処理に要注意) top last キューへのポインタ dequeue

キューの3通りのデータ構造 (3) 続き top last キューへのポインタ new enqueue どちらの操作もキューの長さに依存しない一定時間で処理することが可能 (キューが空から出発する,あるいは空になるときは処理に要注意) last キューへのポインタ dequeue top

キューの3通りのデータ構造 (3) 続き top last キューへのポインタ new enqueue どちらの操作もキューの長さに依存しない一定時間で処理することが可能 (キューが空から出発する,あるいは空になるときは処理に要注意) top last キューへのポインタ dequeue

キューのデータ構造 ( 2 ) MyQueue = Struct.new(:top, :tail, :length, :array) def enqueue(q, data) q.array[q.tail] = data q.tail = (q.tail + 1) % q.array.size # % は余りを求める演算 (循環するため) q.length += 1 end def dequeue(q) value = q.array[q.top] q.top = (q.top + 1) % q.array.size q.length-= 1 value end def empty?(q) q.length == 0 end Ruby 試してみよう q = MyQueue.new(0, 0, 0, Array.new(100)) p empty?(q) enqueue(q, :x) p empty?(q) enqueue(q, :y) enqueue(q, :z) p dequeue(q) p empty?(q)

キューのデータ構造 ( 3 ) Cell = Struct.new(:value, :next) $ptr = nil def enqueue(data) if $ptr != nil cell = Cell.new(data, $ptr.next) $ptr.next = cell $ptr = cell else $ptr = Cell.new(data, nil) $ptr.next = $ptr end Ruby def dequeue cell = $ptr.next if $ptr.next != $ptr $ptr.next = cell.next else $ptr = nil end cell.value end def empty? $ptr == nil end 一言リマーク: Ruby では.オブジェクトにしないのが 不自然 $ は大域変数の意味

地下鉄路線図

地下鉄路線図のデータモデル データモデルにして何をしたいかをまず考える 発駅から着駅までの最短の経路を探索する 発駅から着駅までの最も安い経路を探索する 発駅から着駅までの乗り換え回数最小の経路を探索す る 乗り換え所要時間も考慮に入れる? 発駅から5駅以内で行けるすべての駅を数え上げる 駅名が漢字5文字以上の駅を列挙する JR との乗換駅を列挙する … どの操作が最も頻繁に使われるか,重要かを考 える それらに適したデータモデル化(一つとは限らない) アルゴリズムやプログラミングに関する土地勘が必要 次回以降の講義でそれらの素養を学ぶ

地下鉄路線図のデータモデルの一例 (1) linenameupupDdowndownDexchangeList " 東西線 "" 茅場町駅 " 駅のデータの集合として地下鉄路線図を表す 例えば東西線茅場町駅を表すデータ( Station ) 大文字の D は距離( Distance )の意味 東西線日本橋駅のデータ 東西線門前仲町駅のデータ 日比谷線茅場町駅のデータ stationtimeForExchangenextExchange 3 プログラミング言語 で書くのは演習

地下鉄路線図のデータモデルの一例 (2) 人が見る時刻表のように路線ごとにまとめて表にしてしまうのでもよい このとき路線名や駅名から連想メモリを使うのではなく,それらに通し番号を つけると配列だけでかなりのことができる 銀座線 丸の内線 東西線 有楽町線 南北線 大江戸線 … ー 中野 0 落合 2.0 高田馬場 1.9 早稲田 1.7 神楽坂 1.2 飯田橋 1.2 … 3134 路線番号 駅番号 所要時間 乗換え 距離 次候補