金沢湯涌温泉に行ってきました.Part1

 

こんにちは,ABS104aです.

 

今回は,石川県,湯涌温泉に行ってきましたのでその写真をという事で,簡単にですが記事にしたいと思います.

 

前々から家族旅行をという事で計画を立てていて,今まで行ったことのない場所,割と実家から近い,観光地が近くにあると言うことで絞り込んだ結果このような場所になりました.

 

宿泊場所を予約してれっつごーです><

 

f:id:ABS104a:20130902140500j:plain

温泉入り口部分です.

案内板,何か見覚えがあるなぁ・・・(汗

バス停も湯涌温泉のとなりに湯乃鷺温泉と書いてあります.ちょっと実感が湧きますね!

f:id:ABS104a:20130904065813j:plain

f:id:ABS104a:20130904065520j:plain

所々にぼんぼり祭りのポスターが(^_^;) 町おこしですね.

ここで道路が2手に分かれていて,1日目の宿泊先は右手にあります.

f:id:ABS104a:20130902141403j:plain

進んでいくと夢二館があります.時間が余りなかったので3日目に残してとりあえずスルー.

その奥にはちょっとした広場と奥に稲荷神社です.

f:id:ABS104a:20130902141704j:plain

ぼんぼり祭りですよ!>< ちょっとテンション上がってきたです.

f:id:ABS104a:20130902142217j:plain

ちなみに途中,観光協会に寄ったのですが完全にいろは一色でした.

f:id:ABS104a:20130902145215j:plain

f:id:ABS104a:20130902145058j:plain

 

一通りあたりを散策した後,旅館に戻りチェックイン.ロビーやお土産コーナーにもいろはの展示やグッズが置いてありました.

f:id:ABS104a:20130907002049j:plain

 

部屋で休んだ後に入浴.時間が早かったのか誰もいなかったので1枚だけ取らせてもらいました.

f:id:ABS104a:20130902163401j:plain

劇中シーンにある場面を見るとちょっとテンション上がりますよね!

その後部屋にてご飯,とてもおいしかったです.写真の後にも次々と料理が運ばれてきて,個人的には量が多いと感じました.仲居さんも気さくな方で話しやすいです.

f:id:ABS104a:20130902175527j:plain

 

一日目はこんな感じで完全に巡礼ですね(笑

ただ,見所としては江戸村もありますし,1日回れます.

個人的にはインターネット環境がなかったのが痛いです.

docomoとauは3Gこそ入りますが,当然LTEは全滅.

ソフバン,EMは完全に圏外.WiMAXは場所により一部入ります.

旅館は無線等のインフラは全く無いのでそれだけですね.

 

次は,本命で金沢市街地(2日目)について記事にしたいと思います.

それでは!

 

全通りの組み合わせを羅列するプログラム

こんにちは,ABS104aです.

 

今回は,前回の記事の延長のような物です.

前回では全通りの探索を木構造の幅優先で探索を行いました.

 

今まで,あまりこういうことやってこなかったので時間がかかってしまい自分の未熟さを実感させられました...orz もっと頑張らねば,

 

という事で,全通りの探索といって思いつく方法についてプログラムを自分で書いてみました.

一番自分で書くのがコーディング力あがるよねっ!って事でトライ.

 

とりあえず思いつく方法として,

 

・スタック

・キュー

・再帰関数

 

こんなところでしょうか.

 

まずは,スタックから行きましょう.

スタックを用いた方法では,木構造のある点における状態をスタックに格納します.

f:id:ABS104a:20130828225400p:plain

図を見てもらえれば分かるとおり,スタックでは最後に入ったオブジェクトが最初に取り出されます.最初に入ったオブジェクトは最後まで出てこない理不尽仕様です.

 

これによって,深さ優先探索が可能になります.要は使用したオブジェクトをすぐに使い回して条件を満たすまで掘り下げる訳です.

 

独自プログラム以下記述

    /**
	 * 入力したアルファベットの全通りの組み合わせを羅列するメソッド
	 * (重複あり,Stack)
	 * @param length
	 * @param value
	 */
	public static void combination_Stack(int length,char value){
		LinkedList stack = new LinkedList();
		stack.clear();
		for(int t = 0;t < value.length;t++){
			String tmpString = new String();
			tmpString += value[t];
			stack.push(tmpString);
			while(stack.size() > 0){
				tmpString = stack.pop();
				for(int s = 0;s < value.length;s++){
					String newString = new String(tmpString + value[s]);
					//判定条件(ステップ数)
					if(newString.length() == length){
						System.out.println(newString);
					}else
						stack.push(newString);
				}
			}
		}	
	}

 

こんな感じで実装しました.ステップ数を制限しないとドンドン掘り下がっていきます.注意.

 

次にキュー構造です.

キューはなじみ深いと思います.要は先入れ先出しですね.

例えば自動販売機のジュースとかはこんな感じですし,お店の行列なんかもこれです.(お店の行列がスタックだったらお客激怒ですよ(^_^;))

f:id:ABS104a:20130828230458p:plain

これを使うことで,幅優先で探索する事が可能になります.木構造の上部から順番に下に向かって探索をします.何かの手順を探索する場合はこれを使うと多くの場合,最短手順を導き出すことができるみたいです.

 

独自プログラム以下記述

    /**
	 * 入力したアルファベットの全通りの組み合わせを羅列するメソッド
	 * (重複あり,Queue)
	 * @param length
	 * @param value
	 */
	public static void combination_Queue(int length,char value){
		LinkedList queue = new LinkedList();
		queue.clear();
		//RootをQueueに貯める
		for(int t = 0;t < value.length;t++){
			String tmpString = new String();
			tmpString += value[t];
			queue.offer(tmpString);
		}
		
		while(queue.size() > 0){
			for(int u = 0;u < value.length;u++){
				String tmpString = queue.poll();
				for(int t = 0;t < value.length;t++){
					String newString = new String(tmpString + value[t]);
					//判定条件(ステップ数)
					if(newString.length() == length){
						System.out.println(newString);
					}else
						queue.offer(newString);
				}
			}
		}
	}

 

このように組んでみました.とりあえず根が分からなかったので,厳密に言うと根の一つ下のステップからのスタートですね.

 

こんな雑なコードで良いのかな・・・(汗

 

最後に再帰関数です.

 

再帰関数は多分C言語とか習うと必ず一回は聞いたことあると思いますが,関数内で自分の関数を呼び出す事です.コードをミスるとすぐに無限ループ→スタックオーバーフローなので危険はありますが,物にできるとかなりスッキリした書き方ができます.

 

以下独自コード

 

   
    /**
	 * 入力したアルファベットの全通りの組み合わせを羅列するメソッド
	 * (重複あり,再帰)
	 * @param tmp
	 * @param length 組み合わせ長さ
	 * @param value 入力文字
	 */
	public static void combination_return(String tmp, int length,char[] value){
		// 検索するステップに達した時
		if(tmp.length() == length)
			System.out.println(tmp);
		// それ以外
		else {
			for (int i = 0; i < value.length; i++)
				combination_return(tmp + value[i],length, value);
		}
	}

こんな感じに書きました.かなり短く書くことができますね.便利!

これはスタックと同じで深さ優先ですかね.

 

場合によって使い分けれると便利そうです.

将来的に効率的なコードの実装方法を選択して組めるようになりたいなぁと思うこのこの頃です.

 

今日はこれぐらいで,また!

2つのバケツ問題

こんにちは、今日はプログラミングのことについて最近やっていることをお話します。

アルゴリズムについてなのかな? ある問題を解いていました。

問題「5ℓはいるバケツと3ℓはいるバケツがあります。これらに水を注いだり移し替えたりして、4ℓの水を図ってください。」

ただ、この内容だけでしたら、
①5ℓのバケツをいっぱいにする。
②3ℓに水を移す
→この時点で5ℓのバケツに2ℓ水が入っている
③3ℓのバケツを空にする。
④5ℓのバケツの中身を3ℓのバケツに移す
→この時点で3ℓのバケツに2ℓ水が入っている
⑤5ℓのバケツをいっぱいにする。
⑥3リットルのバケツにできるだけ移し替える
→ここで3ℓのバケツは空きが1ℓのため、5ℓのバケツに4ℓの水が残る。

完成!

というわけですが、今回はこの手順を導出するプログラム(導出可能かどうかも判定する)を書いてみようということで昨日から少し考えていました。

Twitterなどでいろいろな方から事前知識をいただいていたので、その影響が強いですが考えとしては、、、

・5ℓはいるバケツ→バケツA
・3ℓはいるバケツ→バケツB

とすると、動作の取り方は、

・バケツAをいっぱいにする。
・バケツAを空にする。
・バケツAの中身をバケツBに移す。

・バケツBをいっぱいにする。
・バケツBを空にする。
・バケツBの中身をバケツAに移す。

の六通りとあらわすことができるわけです。  一番初めは両方共のバケツが空なのでこれがスタートです。

プログラムではとりあえず、順々に手順を試行してチェック→条件確認
といったところでしょうか。

はじめの状態を根として、手順を全通り試行して掘り下げていき試行を繰り返します。
構造としては木構造ですね。

ただ、言っといてよく知らないんだなこれが、、

木構造の探索法に関しては調べてみると深さ優先探索幅優先探索とあるらしいです。
今回は深さが無限に増加していくことと、最短手順を調べるということなので幅優先で行きましょう。(分かってないです,エッヘン

f:id:ABS104a:20130824000120p:plain


こんな感じで、階層の上のほうから順に探索を進めていきます。(たぶん
正直、探索法知ったの昨日でよくわかってないのでセオリーとかわかんないですし、かなり非効率な気もしますが、せっかくコード書いたので載せようと思います。(5ℓのカップでかくね?とか英語おかしいとかはやめて>< 分かってるから・・・orz

//--Cup関数(バケツのつもり(汗)-----//

package com.abs104a.cuptest.data;

public class Cup {
    
	//現在のカップに入っている量
	private final int now;
	//このカップの最大容量
	final private int capacity;
	
	/**
	 * インスタンス生成,カップの最大容量を決定する
	 * @param capacity カップの最大容量
	 */
	public Cup(int capacity){
		this.capacity = capacity;
		now = 0;
	}
	
    /**
     * インスタンス生成,内部用データ再生成
     * @param now カップの現在の容量
	 * @param capacity カップの最大容量
	 */
	private Cup(int now,int capacity){
		this.now = now;
		this.capacity = capacity;
	}
	
	/**
	 * 現在の容量を返す
	 * @return
	 */
	public int getNow(){
		return now;
	}
	
	/**
	 * このカップを満タンにする
	 * @return 現在の容量
	 */
	public Cup full(){
		return new Cup(capacity,capacity);
	}
	
	/**
	 * 自分のカップをからにする
	 * @return ゼロ
	 */
	public Cup empty(){
		return new Cup(0,capacity);
	}
	
	/**
	 * 自カップへの移し替えを行う
	 * 自分A→引数cupBへ内容を移し替える
	 * @param cup 相手のカップ
	 * @return 自分のカップの容量
	 */
	public Cup pour(Cup cup){
		Cup result = new Cup[2];
		int _sum = now + cup.now;
		result[CUP_OTHER] = new Cup(Math.min(cup.capacity, _sum),cup.capacity);
		result[CUP_MINE] = new Cup(Math.max(0, _sum - cup.capacity),capacity);
		return result;
	}
	
    //自分のカップ
	public static final int CUP_MINE = 0;
    //相手のカップ
	public static final int CUP_OTHER = 1;
}

 

このクラスにて,バケツ操作を受け持ちます.現在の容量と最大容量を記憶します.

そして,木構造においてそれらCupオブジェクトを関連付けるHolderクラスを定義します.

//--CompareHolderクラス-----//

package com.abs104a.cuptest.data;

public final class CompareHolder {
    
	//子要素の関連
	private final CompareHolder children;
	//親要素の関連
	private final CompareHolder rootHolder;
	
	//バケツAの内容
	private final Cup tmpResult_A;
	//バケツBの内容
	private final Cup tmpResult_B;
	
	//現在の配列位置
	private final int position;
	
	/**
	 * 比較する際のホルダー
	 * @param rootHolder 上位のクラス
	 * @param tmpResult 現時点での値
	 * @param maxChildren 最大の持つべき子の数
	 * @param pattern 
	 */
	public CompareHolder(CompareHolder rootHolder,Cup tmpResult_A,Cup tmpResult_B,int position,int maxChildren){
		this.rootHolder = rootHolder;
		this.tmpResult_A = tmpResult_A;
		this.tmpResult_B = tmpResult_B;
		children = new CompareHolder[maxChildren];
		this.position = position;
	}
	
	public int getPostion(){
		return position;
	}
	
	public CompareHolder getRootHolder(){
		return rootHolder;
	}
	
	public Cup getTmpResult_A(){
		return tmpResult_A;
	}
	
	public Cup getTmpResult_B(){
		return tmpResult_B;
	}
	
	public boolean setChildren(int position,CompareHolder holder){
		if(position < 0 || position >= children.length)
			return false;
		else{
			children[position] = holder;
			return true;
		}
	}
	
	public CompareHolder getChildren(int position){
		if(position < 0 || position >= children.length)
			return null;
		else
			return children[position];
	}

}

 ほとんどゲッターとセッターですね.

この二つがこのプログラムの基となります.

何かある意味で双方向リストみたいな感じになってしまいました.

このホルダーではその木要素のポジションにおける状態の記憶と上流,下流へのアクセスができるようになっています.

もし解が確定した場合,親のクラスを遡る事で解答の手順を取得する事が可能です.

 

そしてメインルーチン(探索部分ですね

//--searchメソッド-----// 

public final static int PATTERN = 3*2;
     /**
     * メインルーチン
	 * 探索を行う
	 * @param root
	 * @param capacity_A
	 * @param capacity_B
	 */
	public void search(final int capacity_A,final int capacity_B,final int goal){
		//ルートホルダーの作成
		final CompareHolder srootHolder = new CompareHolder(null, new Cup(capacity_A), new Cup(capacity_B),-1, PATTERN);
		//探索用のキュー
		final LinkedList list = new LinkedList();
		//枝切り用の解答キャッシュ
		final ArrayList cache = new ArrayList();
		
		
		list.offer(srootHolder);
		//現在の木位置記憶用
		CompareHolder tmpHolder = null;
		//ループ判定用フラグ
		boolean roopFlag = true;
		//試行回数
		int count = 0;
		do{
			
			CompareHolder rootHolder = list.poll();
			for(int i = 0;i < PATTERN;i++){
				Cup tmp = doActions(i, rootHolder.getTmpResult_A(), rootHolder.getTmpResult_B());
				tmpHolder = new CompareHolder(rootHolder, tmp[DATA_A], tmp[DATA_B],i,PATTERN);
				rootHolder.setChildren(i, tmpHolder);
				count++;
				MapData data = new MapData(tmp[DATA_A].getNow(),tmp[DATA_B].getNow());
				//判定を行う
				if(tmp[DATA_A].getNow() == goal || tmp[DATA_B].getNow() == goal){
					System.out.println(i + ": A:"+tmp[DATA_A].getNow()+" ,B:"+tmp[DATA_B].getNow());
					roopFlag = false;
					break;
				}else if(!(data.getA_data() == 0 && data.getB_data() == 0)){
					if(cache.indexOf(data) == -1){
						list.offer(tmpHolder);
						cache.add(data);
					}
				}
			}
		}while(roopFlag && list.size() > 0);
		
		System.out.println("試行回数は"+count+"回でした.");
		
		if(!roopFlag){
			//結果が出ている場合
			LinkedList resultStrings = new LinkedList();
			while(tmpHolder.getRootHolder() != null){
				resultStrings.push(getString(tmpHolder.getPostion()));
				tmpHolder = tmpHolder.getRootHolder();
			}
			while(resultStrings.size() > 0){
				System.out.println(resultStrings.pop());
			}
		}else{
			//結果がでない場合
			System.out.println("この試行は不可能です");
		}
		
	}


この部分は付随するメソッドがあるのですが一部省略させてください.

簡単に説明すると,

・ホルダーを作ってそれぞれの子要素を作成,計算を行う.

・子要素の解が解答であるか確認する.

・解答でない場合で,双方ともに0または既出以外であればキューに入れる.

・キューが捌けるまで試行を繰り返す.

このような感じです.

キューが捌けた時点で解答が見つからない場合は試行不可能という結論になります.

 

色々中途半端な気もしますが,今日はもう力尽きてしまったのでこの辺にさせてください.(^_^;)

気が向いたらまた編集かけます.

 

それでは!

 

追記:

ソースは

https://github.com/ABS104a/cuptest

に置いておきます.突っ込みや質問はTwitterまでお願いします.

 

ReadyNas OS 6.0.8 において特定タブでConnectionLostが発生する件

こんにちは,ABS104aです.

今回はBiyonとは関係無い記事です.

f:id:ABS104a:20130822221302p:image

以前よりNASとして共用のストレージを自宅で使用していたのですが,やはり冗長性は必要だろうという考えのもと,NTT-Xで12000円を切っていたのを良いことにRN10200を購入しました.

早速HDDをセッティングして,

手順としては,
①電源を入れる

https://readycloud.netgear.com/ にアクセス

③検出ボタンをクリック

④管理用のIDとPassを設定,RN10200の場合はバックアップボタンを押して紐付けする.

⑤完了

というかなり簡単な物です.

ただ,管理画面を少し構っているとConnectionLostが頻発,特にネットワークタブについては再現性100%で画面にリセットがかかるので設定できません.

そこでメーカーに問い合わせをしてみました.

結果としては,OSの不具合で現在修正をしています.
β版にて解決しているのでとりあえずそれを適用してみてはどうでしょうか?
と言うことでした.

以下,メールの内容(一部抜粋)
-----------------------------------------------------------------
ファームウェア更新方法】
1.ReadyNAS内データをバックアップをします。

2.下記URLよりファームウェア 6.1.0-T1700をダウンロードします。
http://www.netgear.jp/support/download/ReadyNASOS-6.1.0-T1700-arm.img
 ※上記アドレスにアクセス後、「保存」をクリック頂き
  任意の場所に保存をお願いします。

3.ReadyNASの管理画面を起動し、画面上部メニューの
 システム> 設定> アップデートファームウェアインストール
 を選択します。

f:id:ABS104a:20130822221303p:image:w640

4.ファイル選択画面で、手順2でダウンロードして頂いた
 「ReadyNASOS-6.1.0-T1700-arm」を選択し、
 「アップロード」をクリックします。

5.ReadyNASの再起動の確認画面が表示されるので「再起動」を
 クリックした次に「はい」をクリックします。

-----------------------------------------------------------------
これで上記の問題は発生しなくなりました.

一応β版ですのでデータのバックアップは必ず取ってくださいとの事です.
自分の環境では今のところ安定動作していますが,万一データが吹っ飛んでも自己責任でお願いします.