- PR -

[VB.NET] 指定の数値群より近似値を求める方法

投稿者投稿内容
KIMERA
大ベテラン
会議室デビュー日: 2003/02/28
投稿数: 112
お住まい・勤務地: 兵庫県・大阪府
投稿日時: 2006-05-12 11:27
いつもお世話になっております。

VB.NETで下記のようなことをしたいのですが、具体的に処理を考え付けずに困っています。
アドバイスを頂ければと思います。

可変の配列に数値が格納されており、指定した値がその配列の中の数値と等しいものが見つからない場合に、近似値を返す。

例:
数値群{8,9,10,14,16,20}

10を指定した場合は10が返る
11を指定した場合は10が返る
12を指定した場合は10が返る(同じ近似値がある場合[10,14]小さい方を優先する)

こんな感じで関数を作りたいのですが、よい処理方法が思いつきません・・・。

一度全ての数値との差を求めた上で、更に差が一番0に近いものを抜き出し、それが複数からある場合に数の少ない方を優先する。

という考えで問題ないでしょうか。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-05-12 11:59
ソートして
自分以上になりまでループして
あとはインデックスの場所を頼りに
うにゃうにゃうにゃ
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2006-05-12 12:01
でいいんじゃないでしょうか。
あとは差の精度に気をつけるくらいですかねぇ。

引用:

数値群{8,9,10,14,16,20}


値が順に並んでるようですが、もしそういう前提があるならバイナリサーチ等でもいいかも。
並んでなくても
#Dim n() As Integer
n.Sort()
としてからバイナリサーチするとか。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-12 12:02
引用:

KIMERAさんの書き込み (2006-05-12 11:27) より:

一度全ての数値との差を求めた上で、更に差が一番0に近いものを抜き出し、それが複数からある場合に数の少ない方を優先する。
という考えで問題ないでしょうか。


For Each で配列内の要素を列挙し、= かどうかを求めるついでに、差を求めた方が良いでしょうか。
順番が約束されている (ソートされている) ならば、超えた時点での値と、
ひとつ前の値の差分を比較するという手もあるでしょう。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ぼのぼの
ぬし
会議室デビュー日: 2004/09/16
投稿数: 544
投稿日時: 2006-05-12 12:10
引用:

KIMERAさんの書き込み (2006-05-12 11:27) より:
12を指定した場合は10が返る(同じ近似値がある場合[10,14]小さい方を優先する)


具体的な方法は他の皆さんに譲るとして補足的な質問です。
負数の場合どうなります?数値として小さい方?絶対値が小さい方?負数は考慮しなくて良い?
たつごろー
ぬし
会議室デビュー日: 2004/10/25
投稿数: 496
投稿日時: 2006-05-12 12:18
引用:

一度全ての数値との差を求めた上で、更に差が一番0に近いものを抜き出し、それが複数からある場合に数の少ない方を優先する。


全部の差分を覚えておかなくてもいいと思いますよ。

・ソート済み
バイナリーサーチをして一番近い場所を求める
一致していれば終わり
一致していなかったら、前後の値から条件に合うものを選ぶ

・ソートされていないが件数はたいしたことない
全件なめる
一致するならそこで終わり
一致していなかったときは探す値との差分をスコアとして保存する
求める値より小さな値を優先とのことですので、そういう値にはボーナスとして小数点の(0.5とか)スコアを与える(この場合は0.5を引くことになります)
よりスコアの高いインデックスを覚えておく
全件走査してもっともスコアの高い(この場合は小さい値が高スコアですね)ものを探す

・ソートされていないが件数が膨大
ソートされていないが件数はたいしたことないのと、ソート済みの
ものを両方試してよいほうを選ぶ。



参考リンク (今回の件でこれらが使えるかどうかの検証はしていません)
.NET Framework クラス ライブラリ
Array.BinarySearch メソッド
http://msdn.microsoft.com/library/ja/cpref/html/frlrfsystemarrayclassbinarysearchtopic.asp

Array.Sort メソッド
http://msdn.microsoft.com/library/ja/cpref/html/frlrfsystemarrayclasssorttopic.asp

Visual Studio 2005
.NET Framework クラス ライブラリ
http://msdn2.microsoft.com/ja-jp/library/system.array.binarysearch.aspx
http://msdn2.microsoft.com/ja-jp/library/system.array.sort.aspx



_________________
たつごろー http://www.codeseek.net

[ メッセージ編集済み 編集者: たつごろー 編集日時 2006-05-12 12:20 ]
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-05-12 12:59
引用:

KIMERAさんの書き込み (2006-05-12 11:27) より:

一度全ての数値との差を求めた上で、更に差が一番0に近いものを抜き出し、それが複数からある場合に数の少ない方を優先する。



全件舐めながら、一番近かった要素と値を常に更新していくだけで良いように思い
ます。
うにくま
ベテラン
会議室デビュー日: 2005/11/05
投稿数: 82
投稿日時: 2006-05-12 13:25
もうちょっとキレイに書けるのかもしれませんが、とりあえず。
コード:
        private int GetApproximateValue(int[] array, int value)
        {
            Array.Sort(array);
            int index = Array.BinarySearch(array, value);
            if(index < 0)
            {
                index = Math.Abs(index) - 1;
                if((index < array.Length) && (index > 0))
                {
                    if(Math.Abs(value - array[index - 1]) <= Math.Abs(value - array[index]))
                    {
                        index = index - 1;
                    }
                }
                else if(index >= array.Length)
                {
                    index = array.Length - 1;
                }
            }
            return array[index];
        }


負数の場合は値の小さい方が優先されます。
数値群{-1, -3}
-1を指定した場合、戻り値は-1
-2を指定した場合、戻り値は-3
-3を指定した場合、戻り値は-3
なような感じです。

スキルアップ/キャリアアップ(JOB@IT)