szmlb.net

tips for robotics

読書メモ: 没頭力「なんかつまらない」を解決する技術

没頭力「なんかつまらない」を解決する技術 のまとめと感想.

没頭力 「なんかつまらない」を解決する技術

没頭力 「なんかつまらない」を解決する技術

何についての本?

日本放送のよっぴーさんこと吉田尚記さんの著書. 「人生を上機嫌 (=ワクワクして目が醒めて, 夜満ち足りて眠るような状態)で過ごす方法を論理的に考えたい」というモチベーションから始まり, 「没頭する時間を増やすことで, 上機嫌な人生を送れるのではないか?」と考え, 「ではいかに没頭する時間を再現するか」, ということを論じている本です. 没頭するというのはどういう状態なのか, その定義から始まって, 没頭する状態になるにはどうしたらいいのかまで説明されています.

読もうと思った経緯は?

twitterを眺めていたらたまたま目に入り,「最近没頭できてないなあ」という漫然とした悩みというか, フラストレーションみたいなものがあったので, これを読んで参考になったらいいな, と思ったからです. これまで, もちろん没頭してきたことはたくさんあったのですが, その状態に意図的に持っていくヒントが何か得られれば良いなと.

本の特徴は?

よっぴーさんはニコ生のチャンネルを持っていて, 過去のニコ生で話した内容を書籍化した点が特徴的です. 放送時の視聴者のコメントも一部記載されていて, 読み手の疑問に都度答えるような形になっており, 非常に読みやすいです. 200ページ程度で, 1~2時間で一気に読めます.

本の内容の要約は?

没頭するための条件を本から引用すると, 以下の8つになります.

  1. ゴールとルールがはっきりしていて, フィードバックがはやいこと
  2. 目の前のことに100%集中していること
  3. 無意識に体を動かしていること
  4. 自分というものをなくしていること
  5. 時間の感覚がなくなっていること
  6. その場の状況を自分でコントロールできていること
  7. その行動自体が目的になっていること
  8. 自分の持っているスキルと行為のバランスが取れていること

ここで, 1, 6, 8が外的要因であり, その他が没頭した状態の結果についての説明なので, 没頭するためには特に1, 6, 8に注視する必要がある, と述べられています.

具体的な方策として, 以下の3つが提案されています.

  • 自分なりのルールを決める
  • 結果が得られるまでのスパンを短くする
  • 自分のスキルより4%難しいことに挑戦する

また, 没頭した状態にさらに入りやすくするためのステップとして, 「不安→開き直り→没頭」という手順が良い, としています. まずはストレスとかけて, 次にリラックスし, 最後に目の前のやるべきことに集中する, という手順が没頭しやすい. twitterとかをダラダラと見てしまうのは, ストレスがかかっていない「安定した状態」なので, ワクワク感のある没頭した状態からは遠ざかってしまうそうです.
そのほかにも, 開き直るためにはどうしたらいいのか, 没頭するものを見つけるにはどうしたらいいのか, 没頭するためのさらなるテクニック等, 色々書いてあるので, 気になる方は読んでみてください.

所感

上に書いてある内容で, 没頭している状態についての説明は, 「まあ言われてみればその通りだな」という感じなのですが, 言語化されているのは今の自分にとって参考になりました. 会社の仕事なんかだと, 個人で完結するような作業以外は, やっぱり没頭するのは難しいのかなーとか. 色々これやりたいありやりたいとか勝手に考えることには没頭できるんですが. 上の定義からいうと, プログラミングとかものを作ったりするときは, ほぼ条件を満たしそうな気がします. 最近没頭できてないなーと感じていたのは, 「自分の持っているスキルと行為のバランスが取れていること」という条件を満たしていないことが原因な気がします. 最近は自分のスキル以上の難しいことに興味がいっていて, その勉強をしようと思っても集中力がすぐに切れてしまう場合が多いです. じゃあこんな時に没頭するためにはどうすれば良いのかというと, 背伸びせずに順を追って勉強しろ, という感じになるのかな. 難しい論文を読もうとして諦めて, 調べようと思ったらいつの間にかtwitter見て...というケースが多い気がしたので, 勉強の計画をもう少し真面目にやろうと思いました.

次に読む本は?

実はこの本にはタネ本があります. 少し高めですが, 読むとしたら次はこの本だと思います. よっぴーさんの本は安いしすぐ読めるので, 一発目としておすすめです.

フロー体験入門―楽しみと創造の心理学

フロー体験入門―楽しみと創造の心理学

Visual StudioでCMakeを使ってライブラリをインストール

最近, やりたくないけどwindowsで作業せざるをえず, 色々と詰まってしまっていたのでメモしておく. qpOASESをwindowsにインストールする場合を例にして, visual studioでビルドからインストールするまでの手順をメモ.

1. CMakeのインストール

CMakeを入れる. 普通にバイナリインストールでOK.
Download | CMake

pathを通しておくことを忘れずに.

2. qpOASESのダウンロード

zipファイルをダウンロード.
QpoasesDownload – qpOASES

展開しておく.

3. visual studioコマンドプロンプトを開く

スタートメニューから探していくと見つかる.
開いたら, qpOASESのフォルダ(CMakeLists.txtがあるところ)までcdする.

4. CMake configuration

続いて以下のコマンドを叩く.

mkdir build
cd build
cmake -G "Visual Studio 14 2015" ..

buildフォルダの中に, ビルド&インストール用のvisual studioプロジェクトファイルが生成される.

5. ビルド&インストール

visual studioを管理者権限で開く
・buildフォルダ内の ALL_BUILDプロジェクトを開く
・ビルドモードをDebugからReleaseに変える
・ALL_BUILDをビルドする
・INSTALLをビルドする

エラーがなければ, ¥C:/Program Files 以下にqpOASESフォルダが現れ, 中にincludeフォルダとlibフォルダが生成される.

6. qpOASESを使う

5. で生成されたincludeファイルとlibファイルをインクルードおよびリンクして使う

ハッシュ探索 (アルゴリズムクイックリファレンス 5.3)

ハッシュ探索.
ハッシュテーブルを作って, そこから探索する. ハッシュテーブルに複数の要素が格納されると衝突が起きるので, 対策が必要. 衝突した要素を同じハッシュ表の空いている部分に入れておく方法がわかりやすい. 衝突が起きてハッシュ表の適切な場所に格納されなかった要素は線形探索等で探索する.

参考:
necophys.hatenablog.com

計算量

  • 最良 O(1)
  • 平均 O(1)
  • 最悪 O(n)

サンプルコード

function hash_store(A, hash_key)

    H = zeros(hash_key+1)
    for x in A
        k = Int(x % hash_key)
        while H[k+1] != 0
          k = (k + 1) % hash_key
        end
        H[k+1] = x
    end

    return H

end

function hash_search(ls, x, hash_key)

    k = Int(x % hash_key)
    while ls[k+1] != 0
        if ls[k+1] == x
            return k + 1
        else
            k = (k + 1) % hash_key
        end
    end

    return nothing

end

function hashSearch(A, hash_key, t)

    hash_array = hash_store(A, hash_key)
    hash_index = hash_search(hash_array, t, hash_key)

    return hash_array, hash_index

end

function main()

  # list to be sorted
  rng = MersenneTwister(1234);
  list_size = 10
  A = shuffle(rng, Vector(1:list_size))

  # Search
  search_num = 10
  hash_array, index_found = @time hashSearch(A, 11, search_num)

  print("Search for : ")
  println(search_num)

  print("Found index: ")
  print(index_found)
  println(" (in hash array)")

  print("Found value is ... ")
  println(hash_array[index_found])

end

if contains(@__FILE__, PROGRAM_FILE)
    main()
end

二分探索 (アルゴリズムクイックリファレンス 5.2)

続いて二分探索.
リストの中央値の値と探索したい値を大小比較して, 中央値が大きければ, 中央値より小さい領域を探索. 大きければ, 中央値より大きい領域を探索. この処理を繰り返す. 二分探索実行時にはリストは整列されている必要がある.

計算量

  • 最良 O(1)
  • 平均 O(log n)
  • 最悪 O(log n)
function binarySearch(A, t)

  low = 1
  high = length(A)
  while low <= high
    mid = Int(round((low + high) / 2))
    if t == A[mid]
      return mid
    elseif t < A[mid]
      high = mid - 1
    elseif t > A[mid]
      low = mid + 1
    end
  end
  return false

end

function main()

  # list to be sorted
  rng = MersenneTwister(1234);
  list_size = 1e7
  A = Vector(1:list_size) # The list is to be sorted for binary search

  # Search
  search_num = 3000
  index_found = @time binarySearch(A, search_num)

  print("Search for : ")
  println(search_num)

  print("Found index: ")
  println(index_found)

  print("Found value is ... ")
  println(A[index_found])

end

if contains(@__FILE__, PROGRAM_FILE)
    main()
end

実行結果

0.000010 seconds
Search for : 3000
Found index: 3000
Found value is ... 3000.0

逐次探索 (アルゴリズムクイックリファレンス 5.1)

続いて逐次探索.
その名の通り, リストの最初から終わりまで一致するものを探索する.

計算量

  • 最良 O(1)
  • 平均 O(n)
  • 最悪 O(n)

サンプルコード

function sequentialSearch(A, t)

  for (index, value) in enumerate(A)
    if value == t
      return index
    end
  end
  return false

end

function main()

  # list to be sorted
  rng = MersenneTwister(1234);
  list_size = 1e7
  A = shuffle(rng, Vector(1:list_size))

  # Search
  search_num = list_size/2
  index_found = @time sequentialSearch(A, search_num)

  print("Search for : ")
  println(search_num)

  print("Found index: ")
  println(index_found)

  print("Found value is ... ")
  println(A[index_found])

end

if contains(@__FILE__, PROGRAM_FILE)
    main()
end

実行結果

0.001650 seconds
Search for : 5000000
Found index: 2045999
Found value is ... 5000000

マージソート (アルゴリズムクイックリファレンス 4.7)

今日はマージソート.
マージソートではまず, 全体を大きさが等しい二つの集合に分けて, それぞれをソートする. そして, ソートされた集合をマージする.

例のごとく以下のページがわかりやすい.
www.codereading.com

#
# Merge Sort
#

function mergeSort(A)

  Anew = copy(A)
  mergesort_array(Anew,  A,  1,  length(A)+1)

end

function mergesort_array(A, result, left, right)

  if right - left < 2
    return
  end
  if right - left == 2
    if result[left] > result[left+1]
      result[left],  result[left+1] = result[left+1], result[left]
    end
    return
  end

  mid = Int(round((right + left) / 2))
  mergesort_array(result, A, left,  mid)
  mergesort_array(result, A, mid, right)

  i = left
  j = mid
  idx = left
  while idx < right
    if j >= right || (i < mid && A[i] < A[j])
      result[idx] = A[i]
      i = i + 1
    else
      result[idx] = A[j]
      j = j + 1
    end
    idx = idx + 1
  end

end

function main()

  # list to be sorted
  rng = MersenneTwister(1234);
  A = shuffle(rng, Vector(1:100))
  Aorigin = copy(A)

  # sorting
  @time mergeSort(A)

  print("The original list: ")
  println(Aorigin)

  print("The sorted list: ")
  println(A)

end

if contains(@__FILE__, PROGRAM_FILE)
    main()
end

バケットソート (アルゴリズムクイックリファレンス 4.6)

今日はバケットソート.
本よりこっちの方がわかりやすい.
www.codereading.com

#
# Bucket Sort
#

function bucketSort(A, min_bucket, max_bucket)
    buckets = []
    for i in min_bucket:max_bucket
        push!(buckets, nothing)
    end

    for i in A
        buckets[A[i]] = A[i]
    end

    x = 1
    for i in min_bucket:max_bucket
        if buckets[i] != nothing
            A[x] = buckets[i]
            x = x + 1
        end
    end
end

function sortValues(A)

  n = length(A)
  bucketSort(A, 1, n)

end

function main()

  # list to be sorted
  A = [15,  9,  8,  1,  4,  11,  7,  12,  13,  6,  5,  3,  16,  2,  10,  14]

  # sorting
  @time sortValues(A)
  print(A)

end

if contains(@__FILE__, PROGRAM_FILE)
    main()
end