バイナリヒープの使い方

プログラマーに欠かせない、配列の処理を最適化する方法

こんにちは。開発担当のマットです。
プログラムし始めたときのことを振り返ってみました。

バイナリヒープとの出会い・・・

何か面白いアプリケーションを作ろうと思って、プログラミングを勉強している方が多くいると思います。
特にゲームを作ろうと思っている方…

私もプログラミングの勉強を始めたころ、いずれゲーム作成に挑戦しようかと思っていました。
最初に作ったプログラムはJavascriptの”Hello World”でしたが、その後とても簡単なシミュレーション・ゲームを作ることに挑戦しました。

ランダムに生成された世界地図上で、多くの国や部族が戦いあって敵を全て倒すと勝つというごく一般的なゲームでしたが、作ることはとても楽しかったです。

最初に作ってみたゲーム
最初に作ってみたゲーム・・・見るとなつかしい

世界地図のランダム生成アルゴリズムが完成し、次は敵の国を作ることに挑戦しました。
敵国の動きがあまりにも読みやすかったら困るので、AIのコーディングに結構時間をかけてしまいました。

ある程度できあがって、実行しようと思ったら、、、
ガタガタと重くなりました。
処理が重くて、敵の駒が動くのに数秒かかるようになってしまいました。

まだJavascriptの世界から卒業していなかったため、重くなっていることをブラウザのせいにし「ブラウザに頼らない言語で書いていたら問題はなかった」と信じて一旦ゲームを忘れました。

その後ある日、Javaでゲームを開発しているYoutubeシリーズを見て前に作ったゲームを思い出し、再びゲーム作成に挑戦しようと決めました〜 でも今回はJavaで!

今回は全く違うゲームですが、AIを同様に作ってみました。

今回こそ!
次はJavaで作った海賊ゲーム・・・

今回は速い!
今回は問題無い!
と思いきや、またガタガタ重くなってしまいました。。。

ブラウザのせいにしていたのは大間違いで問題は私が書いたコードにありました。

コードを必死に読んで、デバッギングをして、問題を特定できました!
一つのものすごい重いファンクションのせいでした。

そのファンクションはある配列の中の一番少ない値を返してくれるものでした。
なお、そのファンクションは一秒間に何度も呼び出される。

つまり、もし配列に1000個の値が入っているとしてその処理を一秒間に1000回読んでしまえば、毎秒毎秒100万の比較処理となってしまいます。

恐ろしいループの中のループでした。

配列の最小値、(または最大値)を取得する軽い方法はないか?と悩んで、調べたらバイナリヒープに出会いました。

バイナリヒープとは?

バイナリヒープは「二分ヒープ」とも呼ばれますが、簡単に説明するとバイナリヒープは、
必ず、最小値(または最大値)が常に最初のキーに入るよう管理をきちんとされている配列です。

つまり、配列がarrayとしたら、arrayの最小値(または最大値)は必ずarray[0]にあります。
これがあると、ループをしなくても最小値・最大値をすぐ取得することができ負荷を減少するものとなります。

でも、まさか配列をソートすることになってしまうと余計処理時間がかかりそうので具体的にどうやってするのでしょうか?

配列に潜んでいる特徴

通常、配列をこのように想像します。
0から数えるキーがありそれぞれのキーに値が当てはまります。

配列の普通の形

しかし、形を変えて想像すると配列に潜んでいた面白い特徴を見ることができます。
それぞれのキーに親子関係を作ることができるのです。

バイナリヒープとして想像したら
このように並ぶと、
array[0] の子供は array[1]とarray[2]
array[3] の子供は array[7]とarray[8]
array[5] の親は array[2]
array[4] の親は array[1]
などなど・・・

パターンは既に見られているかもしれませんが、
親から見た場合、
= n としたら
左の子供 = n*2+1
右の子供 = n*2+2

子供から見た場合、
子供 = n としたら
= (n-1)/2   *分数を捨てる

バイナリヒープでできること

このバイナリヒープに値を入れる時、
または、バイナリヒープから値を削除する時、
その値の親と子供の上下関係さえ守れば、最小値・最大値は必ず、array[0]になります。

詳しく、説明します。
*説明では、「最小値」を返すバイナリヒープを紹介しますが、最大値を返すヒープは同様な動きです。

バイナリヒープにINSERT

バイナリヒープに新しい値を挿入する時、その値を配列の一番後ろに付け加えます。
次、新しく入れた値をその親と比較します。
もし新しい値の方が大きい場合、何もしません。
けれども新しい値の方が小さい場合、親と場所を交換し動作を繰り返します。

これをきちんとすると、最小値が必ず、「ルート」(array[0])の位置に上がってきます。

先ほどの配列に「3」を挿入してみましょう。

バイナリヒープに値を挿入

バイナリヒープからPOP

最小値を配列から取って削除したい場合、動作が反対となります。
まずは最小値(array[0]にあるもの)を消し、配列の一番最後の値をarray[0]に持ってくる。
その新しくなったarray[0]を子供達と比較し、大きければ一番小さい子供と場所を交換し動作を繰り返します。

バイナリヒープのルートをPOP

バイナリヒープの特長

通常1000個の値を持っている配列の最小値を取得しようと思ったら、1000回ループしなければなりません。

でもデータをバイナリヒープの形で管理したら、最小値をループせずに取得でき最大でも9回の比較だけでヒープを整え直すことができます。
(1,000 < 2^10)

配列が大きければ大きほど最適化の効果が見られます。
例えば、1,000,000個の値を持っている配列でも最大でも、たったの19回の比較で整え直すことができます。1,000,000回ループするより速いでしょう。
(1,000,000 < 2^20)

実際のコード

私は最近Sportareの開発に関わり、Swift言語でのプログラミングが好きになりました。

そこでSwiftで書いたバイナリヒープのコードを紹介したいと思います。

通常ならばもっとコード整理しますが、以下のコードはバイナリヒープを把握するために作ったのでそのままベタ書きしました。
Swiftに慣れていない方でも、すぐわかると思います〜

これからも、頑張りましょう!

思わず誰かに紹介したくなる、とてもかわいいお菓子屋「calico」さん

毎日35℃越えで耐えられない!
こんにちわ。リエです。

最近とてもかわいいお菓子屋さんを知るきっかけがありました。
(このきっかけが何なのかは近日中にお話しする予定です!お楽しみに!)
calicoさんという京都のお菓子屋さんなのですが、ネコちゃんがモチーフとなっていて店名も猫の種類からきているそうです。

というわけでさっそく購入。
購入したのは、ネコセットSキャリコセットSの2種類です。
IMG_4735
※写真はキャリコセットSです。

めちゃめちゃかわいい~!!!!
食べるのがもったいなさすぎる・・・。
でも食べます!

見た目はもちろん味もとってもおいしいです。
ひとつひとつ丁寧に作られたお菓子は店主の橋川さんのこだわりがつまっています。

販売は店舗ではなくネット通販のみとなりますが、何度でも食べたくなるお菓子です。
calicoさん
素敵なお菓子ありがとうございました^^

「RubyWorld Conference 2016」に協賛させていただきます

banner_SPONSOR_1

「RubyWorld Conference 2016」に、Goldスポンサーとして協賛させていただきます。

<期間>
2016年11月3日(木)、4日(金)
<会場>
島根県立産業交流会館「くにびきメッセ」3階 国際会議場
<主催>
RubyWorld Conference開催実行委員会
「RubyWorld Conference 2016」公式サイト

直感的な操作で近くのジムや体育館などを簡単検索! 無料iPhoneアプリ『Sportare(スポルタル)』をリリース

ユニエム株式会社(本社:大阪市都島区、代表取締役:山村 涼)とスプラウト株式会社(本社:大阪市西区、代表取締役:前田 益宏)は2016年7月27日(水)に、近くにあるジムや公園、体育館などを簡単に探せる無料アプリ『Sportare(スポルタル)』をApp Storeでリリースしました。

sportare_press_image

『Sportare』詳細
https://sportare.jp/
ダウンロードページ
https://itunes.apple.com/jp/app/sportare/id1122820082

■『Sportare(スポルタル)』とは
『Sportare』は、近くにあるジムや公園、体育館などをすぐ見つけるためのサービスです。サービス名には「Sports」+「Portal」=「スポーツ総合サイト」という意味が込められています。
直感的なUIで、だれでもすぐ簡単に目的のスポーツ施設を探すことができ、“スポーツ施設を探しているけどうまく探せない”“特定の競技で利用ができるのかを知りたい”など、スポーツを楽しむ人の悩みを解決いたします。
今後は、アプリ限定特典や予約機能・口コミ評価機能などの追加を予定しております。

<特長>
1.すぐに見つかる!
起動してすぐに、地図上から現在地周辺のスポットを見つけることができます。

2.自分だけのリストを作成
お気に入りアイコンをタップするだけで、自分専用のスポットリストを作成できます。

3.カンタンに共有!
カンタンな操作で、スポットの情報をすぐに友達と共有することができます。

4.クーポンでおトクに!
ジムなどで利用できるクーポンがアプリ内にあり、おトクにスポーツをお楽しみいただけます。

■アプリ概要
サービス名称 :Sportare(スポルタル)
公式リリース日:2016年7月27日
サービス利用料:無料
言語     :日本語
対応端末   :iOS 8.2以降。iPhone、iPad、およびiPod touch

■運営会社概要
商号  : ユニエム株式会社 (英名 Unim Ltd.)
代表者 : 代表取締役 山村 涼
所在地 : 〒534-0015 大阪府大阪市都島区善源寺2-2-8-1101
設立  : 2015年7月
事業内容: ・WEBサービスの企画・運営
・人事・採用コンサルティング
・ITコンサルティング
URL   : https://unim.co.jp/

■開発会社概要
商号  : スプラウト株式会社 (英名 Splout Ltd.)
代表者 : 代表取締役 前田 益宏
所在地 : 〒550-0002 大阪府大阪市西区江戸堀1-23-13
設立  : 2014年12月
事業内容: ・コンサルティング
・システム開発・サーバー構築
・Webサイトデザイン制作・運営
URL   : https://splout.co.jp/

Sportareは、ユニエム株式会社とスプラウト株式会社が共同開発したサービスです。
ユニエム様よりプレスリリースをだしていただきました。
URL : https://www.atpress.ne.jp/news/108782
いつもスポーツを楽しんでらっしゃる方や普段は運動不足な方まで楽しんでご利用いただけると幸いです。\(^o^)/

社員旅行に行ってきたパート2

今年はやたら蚊に刺されます。。
こんにちわ。リエです。

昨日社員旅行についてブログを書きましたが
社員旅行に行ってきたパート1

パート2ということで、続きを書きたいと思います^^

シーアイガ海月さんにお世話になったあとは、宿泊先である、海月館さんへ移動します。

趣のある建物、こちらも目の前は海が広がっていて絶景のロケーション。
お部屋から海を眺めることができます。
ブログ1

お部屋からこの景色が見れるなんて贅沢すぎます。。

旅館についてからは、各自しばし休憩。
温泉に入ったりして身体を休めました。

そして、夕食をいただくため宴会場へ移動します。
ブログ2
立派な看板が・・!

そして、待ってました!
夕食\(^o^)/
ブログ3
彩海膳というお料理をいただいたのですが、すごい豪華です。
そして当たり前ですが美味しすぎました(>_<)

海鮮(エビ―)
ブログ7

お肉(ニクー)
ブログ8

お昼にあんなにごちそう食べたのに食べれる不思議・・。

9名でお伺いしたのですが、すごい広い宴会場をご用意いただきスペースを持て余してしまいました^^;
ブログ4
この写真からはあんまり伝わらないかな・・・。

美味しい食事を堪能した後は、花火へ。
海でBBQ・スイカ割り→花火とか夏を満喫しすぎですね( ;∀;)
ブログ6

みんな海遊びで疲れたのか疲労がすごかったので、この日はほどほどに解散し就寝。
朝7時にみんなで朝食をいただき、あっという間にチェックアウトの時間に。
名残惜しかったですが、海月館さんを後にしました。

本当にスタッフの皆様のお心遣いも素晴らしく、お部屋、お料理どれをとっても最高でした。
海月館さん。
本当に素敵なひと時ありがとうございました!

そして渦潮観光し大阪へ帰ってきて、社員旅行は無事幕をとじました。