2011-01-04 6 views
1

あなたは数字の二組があれば検討します線形最小二乗を使用して同様の数値のセットをマッチングしますか?

瀬田:

10 
20 
30 
40 

と数字の別の大きなセット:

SETB:

15 
20 
35 
40 
50 

をゴールは排除することです2つのセットのうちの大きい方のアイテムから、両方のセットに同じ数のアイテムが存在するようになり、あなたは可能な限り「近い」セットとして残りますble。私は、各アイテムのすべてのペアを試し、その差の二乗を最小限に抑えることができるという考えを得ました。例えば、私は上記の解決策があることだと思う:それはあなたの最も小さいDiffSquaredSumを与える組み合わせですので

SetA SetB Diff DiffSquared 
10 15  5  25 
20 20  0  0 
30 35  5  25 
40 40  0  0 

DiffSquaredSum == 50 

それは解決策です。私は本当に一緒にアイテムのペアリングを気にしませんが、それは主に、より大きなセットを同じ数のアイテムであるセットにトリミングすること、およびアイテムができるだけ接近しているところです。私はこれを解決するために線形最小二乗法の概念を使うことができたことに気付きましたが、私はこれをコーディングするところでどこから始めるのかは分かりません。私はSQLを使用する方が好きですが、一般的なアプローチのアイデアを得て正確なソリューションを生成することには心配していません。

は、私はそれが二組のすべての可能な組み合わせを試す基本的に伴うだろうと思います:

SetA SetB Diff DiffSquared 
10 15  5  25 
20 20  0  0 
30 35  5  25 
40 50  10 100 

SetA SetB Diff DiffSquared 
10 15  5  25 
20 20  0  0 
30 40  10 100 
40 50  10 100 

等は、その後DiffSquaredの最小和のグループを選択します。私は、瀬田のためROW_NUMBERを生成することから始め、その後、SETBのため、そしてその上で参加し、答えを与えるために起こっているが、それは唯一の偶然である可能性があります

Row# SetA SetB 
1  10 15 
2  20 20 
3  30 35 
4  40 40 
5  NULL 50 

私は希望の答えを見つけてくださいするには何とかこれを何度もやり直す必要があり、どのグループが私にそれによってグループを行い、次にそれぞれの合計を見ることができるかを教えてくれるIDを持っている必要があります。 でも、私はこのセットを取得する方法がわからないです:

Attempt# Row# SetA SetB 
1   1  10 15 
1   2  20 20 
1   3  30 35 
1   4  40 40 
2   1  10 15 
2   2  20 20 
2   3  30 35 
2   4  40 50 
3   1  10 15 
3   2  20 20 
3   3  30 40 
3   4  40 50 
etc.... 

お知らせ私はSETBから異なるアイテムを排除した各試行#。実際には、SetBはAよりも多くのアイテムである可能性があります。そのため、削除されるアイテムが増え、可能性が増します。私は上記を持っていると、私はフィールドを追加するだけで差の二乗を計算し、次にグループとの合計を試行#で行います。次に、最小のSumDiffSquaredで試行#を選択することができました。おそらく中間テーブルを一時テーブルまたはテーブル変数に格納する必要があるため、そのIDから後ろに歩いて成功したセットの要素を取得することができます。

問題は次のとおりです。これらの「試行」のすべての順列を生成するにはどうすればよいですか?

答えて

1

setA(正確には20と40)で完全に一致するsetBからすべてを取り出し、setA(10 + 30 = 40)の残りの数字を合計して、 setBの同数のオペランド(2、10、30)で合計します。 あなたの例では、15 + 35 = 50になります。

なぜ違いを二乗しているのか分かりません。

両方のセットのすべての可能な組み合わせが必要な場合は、ON句のない外部結合を使用します。

+0

最初に二乗の差について学んだとき、私は同じことを考えました。平方和は、2つのデータセットがどれだけ近いかを判断する概念です。しかし、これは伝統的に曲線をデータに適合させるために適用されます。しかし基本的にコンセプトは、あなたが(1,12)と(6,7)を持っていれば、1と6は5の差があり、12と7は5の差があるので、差の合計は10であるが、平方和は50(25 + 25)である。あなたが(5,16)と(6,7)を持っていれば、差の合計も10ですが、平方和はもっと大きくなります**、81 = 1^2 + 9^2、そうですより悪い「フィット」と考えられる。 – AaronLS

+0

これがビジネスが最も近い「適合」を定義する方法であれば、それを実行する必要があります。 – Beth

1

あなたはdbmsについて言及していないので、私はOracleを使用しました。

with crossjoined as(
    select b 
     ,a 
     ,abs(a-b) as diff 
     ,row_number() over(partition by b order by abs(a-b), a) as rn 
    from SetA cross join SetB 
) 
,ranked as(
    select b,a,diff, row_number() over(order by diff,a) as rn 
    from crossjoined 
    where rn = 1 
) 
select b 
    from ranked 
where rn <= (select count(*) from SetA) 
order by b; 

私はそれがどのように動作するかを説明し、あなたが問題を正しく理解したかどうかを判断できます。クエリは、3つの部分があります。

パート1.私はだからあなたのサンプルデータを使用してAとBのすべての組み合わせを作成する。ここ を「crossjoined」、B15は、その上のA10、A20、A30、A40とと対になっています。各Bについて、私はすべてのAをその差でランク付けします。いくつかのAに同じ差がある場合(A10とA20がB15の場合)、最初に最も低いAをソートします。クエリのこの部分のサンプルを以下に示します。 「ランク付け」

B A DIFF RN 
-- -- ---- -- 
15 10 5  1 
15 20 5  2 
15 30 15  3 
15 40 25  4 
20 20 0  1 
20 10 10  2 
20 30 10  3 
20 40 20  4 

第2部では、クエリの この部分は、基本的にはこれはwhere rn = 1によって実装された各B.のための最高のAを選びます。結果には、元のBごとに1つの行があります。行はその差異によってソートされます。 2つの行の差が同じ場合、Aが最も小さい行がfrstでソートされます。以下は、「crossjoined」と「ランクの」与えられたサンプル・データの完全な結果である:

B A DIFF RN 
-- -- ---- -- 
20 20 0 1 
40 40 0 2 
15 10 5 3 
35 30 5 4 
50 40 10 5 

パート3「メイン・クエリ」今では同じ数の項目としてにそのセット内の項目を排除する時が来ました最小の差を持つセットを見つけるためのロジックに従って、「ランク付け」された部分のランク(rn)を使用し、最初のN行を選択します。ここで、NはAの項目数です。

詳細を何か説明できるかどうか教えてください。

+1

これは必須条件ではありませんが、これはセットの各メンバーが一度しか使用できないことを保証していますか? SetAが '10,20'でSetBが' 9,10'の場合、クエリは '10,10'と' 10,9'を返すか、 '10,9'と' 20,10'を返しますか? –

+0

@Martinでは、BとA10の両方をペアにします。だから私のクエリは一度使われたAを "消費"しません。 – Ronnis

+0

はい、私は小さなセットを大きくしたいのではなく、より大きなセットを小さくして、2セットの中で最小のユニットの数に合わせたいと思っています。つまり、それらを複製するのではなく、アイテムを削除することです。 – AaronLS

関連する問題