07-22-2015 08:31 AM
お世話になります。
件名の通り2D配列検索の作成方法を教えていただけないでしょうか。
よろしくお願いいたします。
07-22-2015 10:41 AM
ninitaro12さん、こんにちは。
とりあえず、こんなのでいいですか?(誰かがもっと良いのを投稿してくれると思います)
0を検索すると、2つヒットしますが、5を検索すると、1つしかヒットしません。
これは1D配列検索の仕様によるものですから、内容を理解したら必要に応じて修正してください。
07-22-2015 11:55 PM
こんにちは。
S.A.MさんのVIを参考に作ってみました。(Ver.2012)
LabVIEWの「1D配列検索」関数では検出すると終了してしまうので、ループで回して全要素を確認するようにしてあります。
~簡単な説明~
①外側のループで2D配列から1行ずつ1D配列にしています。(ループの自動指標付け機能)
②その1D配列に対し、「検索する値」と一致するか確認しています。(1D配列の全要素を見ているので、ループで回しています。)
③一致していたら、その時のループのカウンタを拾ってきます。(外側ループカウンタは”行”、内側ループカウンタは”列”を示します。)
④「検出する値」が存在する指標が取得できます。
参考になれば幸いです。
07-23-2015 02:02 AM
一例ですが・・
LabVIEWの「1D配列検索」は、「開始指標」を与えることができますので、
1つ見つかったら、「その次」の指標を食わせれば、続きを探させることができます。
見た目があまりスッキリはしていないので、あくまでご参考、ですが、
①元の2D配列を、1Dに整形した上で、
②Whileループの中で、「1D配列検索」で、それ以上、値が見つからなくなるまで回し(実質全数検索)、
③見つかったすべての指標を、「元の配列だとどの行・列か?」を求めています。
(Whileの最後の回は余計な指標が出てきますので、それだけ削除しています)
07-23-2015 07:31 AM
S.A.M.さん、haljionさん、M.Shiraishiさん返答していただき、ありがとうございます。
非常に参考になりました。
重ねて質問をしていまい申し訳ありませんが、検索する値を1行2列の二次元配列にすることは可能でしょうか
例えばS.A.M.さんのⅥの場合、検索する値を(0 1)とすると検出指標が2となるようにしたいです。
1列目、2列目でそれぞれ1D検索配列をかけ、指標を出してもその後の処理がわかりません。
よろしくお願いいたします。
07-23-2015 08:54 AM
>>検索する値を1行2列の二次元配列にすることは可能でしょうか
>>例えばS.A.M.さんのⅥの場合、検索する値を(0 1)とすると検出指標が2となるようにしたいです。
いろいろやり方はありますが、今挙がっているもののなかでは、haljionさんのから変えるのが早いです。
haljionさんの二重のForループの内側をやめて、「検索する値」を配列にします。
1つになったForループで、2D配列から「列」が取り出され、検出する値はそれ自体配列なので、
「そのまま比較する」ことで、「列として同一か?」が判定できます。
このとき、検出する値のほうは、Forループの入り口で指標付けされないようにします。(というかForの中に入れちゃえばいい)
また、「=」は、右クリックで「基礎群の比較」にしておきます。
(デフォルトは、個々の要素を比較してブールの配列にするが、基礎群の比較にすると配列全体として等しいかどうか比較)
あとは、答えの検出指標は、「合致した行」を表すことになり、結果は1D配列になるので、そのように直します。
例では、SAMさんの配列の後ろにもう2つデータを足して (0 1) が2つになるようにして、
実際、答えの指標に1と4が返っている様子です。
ほかには、例えばもとの2D配列に入っている値がそんなに大きくないならば(例えば、せいぜい0~1000くらいとか)、
1列目の値を10000倍して2列目の値を加えておき(配列のまま計算できます)、それを「検出する値 (x y) のxの10000倍+y」と比べる、
というやり方もあります。
これだと、1D配列でできます。
また、
>>1列目、2列目でそれぞれ1D検索配列をかけ、指標を出してもその後の処理がわかりません。
は、その方法の場合は、出てきた2つの指標で「共通する値」があれば、その行は1列目も2列目も合致、ですので、
「1列目の検出指標」に対して、「2列目の検出指標」を1個1個、1D配列検索して、「あればOK」とすることになりますが、
いささかメンドクサイと思います・・・
07-23-2015 10:01 AM
既にM.Shiraishiさんから返信があったようなので、それでninitaro12さんの疑問解決しそうですか?
あと、細かいところですが、
Forループの入り口で指標付けされないようにします。(というかForの中に入れちゃえばいい)
の末尾( )内のコメントについては、
以下の理由により、現状のまま、Forループの外にあった方がよいような気がしますが、いかがでしょうか?
・Forループ内にフロントパネルの制御器があると、バッファ割り当てが発生する。
具体的には、操作バッファ<->転送バッファ<->実行バッファのメモリコピーが
ループ回数分発生してしまうのではないかかと・・・違ってますか?
ちょっとスレ内容からはずれそうですが、補足としてコメントいたしました。
以上です。 --- S.A.M.
07-23-2015 10:41 AM
補足のほうへ脱線してしまいますが・・・
>>Forループの入り口で指標付けされないようにします。(というかForの中に入れちゃえばいい)
>>の末尾( )内のコメントについては、
>>以下の理由により、現状のまま、Forループの外にあった方がよいような気がしますが、いかがでしょうか?
は、おっしゃる通りですが、今回、ご質問者様がまだ配列の扱いに慣れていない?という気もしたので、
指標付けするしないは、ご存じだろうとは思うが、そこを手こずる人もたまにフォーラムで見受けるので、
超老婆心ながら「仮にも指標付け不使用で良くわからなかったら中に入れちゃえ」、といった程度です。
勿論、絵にあるように、外にある方が良いです。
(中にあると、ループ中に制御器を変更すると途中から反映されちゃう、とかいう不具合の元にも)
実際のところ、リソース(メモリ・時間)を気にするほど、実は元の2D配列が大きい、とか、
検索して見つける指標の数がすごく多いと想定される、とかだとすると、リソース的好ましさは
配列の継ぎ足し < While出口で指標け < ブロックでメモリ確保し置換(必要に応じブロック拡張) < For出口で指標付け
と言われているので、今挙がっている方法(私のも含めて)はそれぞれに問題を抱えていて、
あまりにデータが沢山あるようであれば、1個1個の全数検索でなくなるべくLabVIEW関数で探させるよう
記述するとか、もうちょっと別の書き方にした方が良いだろう・・・・と思っています。
(1列目に着目して合致した中から、2列目が合致するものを拾う、とか)
まずは今回は2D配列検索にするには?というところで理解いただいて、
もし実使用上、何かメモリが足りなくなるとか異常に時間がかかる・・・・とかいうときに、
改めてさらにrefine、でしょうか・・・・・
07-23-2015 01:18 PM - 編集済み 07-23-2015 01:24 PM
M.Shiraishiさん、S.A.M.さん迅速に対応していただきありがとうございます。
おかげ様で疑問は解決致しました。
ご指摘の通り、LabVIEWを最近始めたばかりで理解はできても、応用することができず行き詰まり、質問をさせていただいた次第です。
30secあるいは60secほど2D配列を乱数生成しながら、新たな乱数を2D配列検索していくことを想定していますので、データはかなり多くなると思います。
サンプルでは待機を使用していますが、実際には使用しない予定です。
07-23-2015 02:06 PM
やはりアルゴリズム関連の返事は早いものだなと関心してしまいましたw