Rでポケモンスタンプラリー(3/3) {TSP}で巡回セールスマン問題
estrellita.hatenablog.comの続き。最後は{TSP}
を利用して移動距離が最短となるようスタンプ設置駅を周回する順番を求める。
- データ準備
- 路線ネットワークに必要なノードとエッジのデータを作成
{tidygraph}
でスタンプ設置駅間の最短経路探索- 路線ネットワークデータからスタンプ設置駅の最短距離を探索
{TSP}
で巡回セールスマン問題を解く( ← イマココ)- 各スタンプ設置駅間の距離行列から移動距離が最短となるような巡回順を探索
目次
- 距離行列の作成
- 巡回セールスマン問題
- 結果の確認
Rでポケモンスタンプラリー(2/3) {tidygraph}で最短経路検索
estrellita.hatenablog.com の続き。今回は{tidygraph}
を利用してスタンプ設置駅間の最短経路を取得する。
- データ準備
- 路線ネットワークに必要なノードとエッジのデータを作成
{tidygraph}
でスタンプ設置駅間の最短経路探索( ← イマココ)- 路線ネットワークデータからスタンプ設置駅の最短距離を探索
{TSP}
で巡回セールスマン問題を解く- 各スタンプ設置駅間の距離行列から移動距離が最短となるような巡回順を探索
目次
- グラフオブジェクトの作成
- ネットワークグラフの可視化
- 最短経路の取得
Rでポケモンスタンプラリー(1/3) データ準備編
最後のー 休みがー 今年もー 終わったなー♪
9月に入り、今年の夏休みも終わりましたがみなさまいかがお過ごしでしょうか。 夏休みの風物詩といえばJR東日本が毎年催すポケモンスタンプラリー。
https://www.jreast.co.jp/press/2019/tokyo/20190628_to02.pdf
昨年より減ったものの43駅あるので全ての駅を制覇しようとするといかに効率的に回るかよく考える必要があり、それだけで酒が呑める!という方々と最近を仕事をしているのですが自分はそこまで鉄道に興味がないのでRで楽したい。というわけで以下の流れでスタンプ設置駅間の移動距離が最小となるように巡回セールスマン問題で解いて巡回する順番を求める。
- データ準備( ← イマココ)
- 路線ネットワークに必要なノードとエッジのデータを作成
{tidygraph}
でスタンプ設置駅間の最短経路探索- 路線ネットワークデータからスタンプ設置駅の最短距離を探索
{TSP}
で巡回セールスマン問題を解く- 各スタンプ設置駅間の距離行列から移動距離が最短となるような巡回順を探索
目次
- データの取得
- 路線情報の取得
- 隣接駅情報を取得
- 乗り換え駅データの取得
- ネットワークデータの作成
- スタンプ設置駅のデータ作成
- ノード情報の作成
- エッジ情報の作成
people analytics tokyo #1に参加してきました。
以前、以下の本を読んで人と人とのつながりが組織のパフォーマンスに影響するということを知り、ちょうど勉強会が開催されたので無理をお願いして参加させていただきました。
データの見えざる手: ウエアラブルセンサが明かす人間・組織・社会の法則
- 作者: 矢野和男
- 出版社/メーカー: 草思社
- 発売日: 2014/07/17
- メディア: 単行本
- この商品を含むブログ (24件) を見る
- 作者: ベン・ウェイバー,千葉敏生
- 出版社/メーカー: 早川書房
- 発売日: 2014/05/23
- メディア: 単行本
- この商品を含むブログ (3件) を見る
以下メモ
{lexRankr}で文章要約を試す
LINE Messaging APIでLINE botを作る(4) センサー連携
の続き。
スマート家電コントローラRS-WFIREX3には気温・湿度・照度をGoogleスプレッドシートに記録してくれるIFTTTアプレットがある。せっかくなのでこれらのセンサーデータをリプライするようにechoman()
を修正する。
センサーデータの記録
RATOC SystemsからセンサーデータをGoogleスプレッドシートに記録するアプレットが公開されているのでそのまま利用する。
- IFTTTのトップページ検索欄に「ratoc」を入力
- 検索結果から「センサー情報をスプレッドシートへ記録」を選択
- 歯車アイコンを選択
- 計測するリモコンを選択し、記録するスプレッドシートのフォルダ・ファイル名を設定し「Save」
node参照用のGoogleスプレッドシートの作成
node.jsからGoogleスプレッドシートを参照する際にあらかじめセルの範囲を把握しておく必要があるようだが、上記の設定だとシートに行が追加されていくため、入力されているセル範囲がわからない。そのため上記で作成したスプレッドシートに行が追加されたら別のシートに追加された行の値を保持するIFTTTアプレットを作成する。
- 「+this」を選択
- 検索欄に「sheets」を入力し「Google Sheets」を選択
- 「New row added to spreadsheet」を選択
- 前節で設定したスプレッドシートのフォルダ・ファイル名を入力し、「Create trigger」を選択
- 「+that」を選択
- 検索欄に「sheets」を入力し「Google Sheets」を選択
- 「Update cell in spreadsheet」を選択
- 最新データのみ保持するシートのフォルダ・ファイル名を入力し、「Which cell?」には"A1", 「Value」には"{{ColumnA}},{{ColumnB}},{{ColumnC}},{{ColumnD}},{{ColumnE}}"
- 「Finish」を選択して設定完了
Googleスプレッドシートへのアクセス設定
node.jsからGoolgeスプレッドシートにアクセスするにはあらかじめアクセス権の設定などが必要となる。リンク先を参考に鍵ファイルの作成およびシートの共有設定を行う。
echoman()の更新
node.jsからGoogleスプレッドシートが参照できるようになったのでメッセージに「何度」「温度」といった単語が含まれる場合、センサーデータを返すように更新する。
センサーデータを取得するgetSensorValue()
は以下の通り。
const GoogleSpreadsheetAsPromised = require('google-spreadsheet-as-promised') const CREDS = require('./credentials.json') const sheetId = process.env.SHEET_ID // id from sheet URL async function getSensorValue () { const sheet = new GoogleSpreadsheetAsPromised() await sheet.load(sheetId, CREDS) const worksheet = await sheet.getWorksheetByName('シート1') const cell = (await worksheet.getCells('A1:A1')).getAllValues() return cell[0].split(',') }
最終的にechoman()
は以下のようになりました。
async function echoman (ev) { // const pro = await client.getProfile(ev.source.userId) let msg = '' if (ev.message.text.includes('おやすみ')) { goodNight() } if (ev.message.text.includes('掃除') | ev.message.text.includes('片付け')) { tidyMyRoom() } if (ev.message.text.includes('何度') | ev.message.text.includes('温度')) { const sensorValues = await getSensorValue() msg = await `${sensorValues[0]} ${sensorValues[1]}計測\n 温度: ${sensorValues[2]}℃\n 湿度: ${sensorValues[3]}%\n 照度: ${sensorValues[4]} lx\nです。` } if (msg === '') { msg = await conversation(ev.message.text) } console.log(`[in]echoman(): msg = ${msg}`) return client.replyMessage(ev.replyToken, { type: 'text', text: msg }) }
我が家のエアコンのリモコンはBluetoohのためRS-WFIREX3から操作できないのが残念だが部屋を擬人化したbotとしてだいたいやりたいことはできた。
試してると愛着が湧いてきて引越しするのが辛くなるなと思って試しにメッセージ送ってみたら
速攻で新しい家人探し始めた。。。orz