注文データからの商品の関連度計算

■ 解き方の方針 数式の各記号が、どの変数で数えられているかを対応付けます。itemを商品x、otherItems[i]を商品yと読み替えると、三つの空欄を順に決められます。 ■ ループ内で数えているもの itemCount: orderにitemが含まれるたびに増えるので、商品xを含む注文数$K_x$です。 arrayK[i]: 商品yが含まれる注文で、商品xの有無に関係なく増やす必要があります。したがって商品yを含む注文数$K_y$です。 arrayM[i]: 商品yを含み、さらに商品xも含む注文だけで増やします。したがって両商品を同時に含む注文数$M_{xy}$です。 ■ 空欄aとb 内側のifは「xとyの両方がある注文」で実行されるので、aは arrayM[i] です。その外側では「yがある注文」ごとに増やすので、bは arrayK[i] です。 ■ 空欄c 全注文数をNとおくと、計算式は$L_{xy}=(M_{xy} × N)/(K_x × K_y)$です。プログラムの分子はarrayM[i] × cなので、cは全注文数を表す ordersの要素数 です。 例の注文データでは、Aを含む注文は1、2、3、4の4件、Bを含む注文は1、4、5の3件です。したがって $L_{AB}=(2 \times 6)/(4 \times 3)=1.0$ となり、問題文の例と一致します。 注文 商品 item=A を含む B を含む Kを増やす(B) Mを増やす(AとB) 1 A, B, D ○ ○ ○ ○ 2 A, D ○ 3 A ○ 4 A, B, E ○ ○ ○ ○ 5 B ○ ○ 6 C, E item=A、otherItems[i]=B のとき、itemCount=4、arrayK=3、arrayM=2 になります。 ■ 正解と誤答の見分け方 したがって、正解は オ です。 allItemsやotherItemsの要素数は商品種類数であり、注文数ではありません。cには必ずordersの要素数を使います。

次のプログラム中の  a  〜  c  に入れる正しい答えの組合せを、解答群の中から選べ。ここで、配列の要素番号は1から始まる。

一度の注文で購入された商品のリストを、注文ごとに記録した注文データがある。
表に、注文データの例を示す。

表 注文データの例

注文番号

購入された商品のリスト

1

A、B、D

2

A、D

3

A

4

A、B、E

5

B

6

C,E

注文データから、商品xと商品yとが同一の注文で購入されやすい傾向を示す関連度 LxyL_{xy} を、次の式で計算する。

Lxy=Mxy×全注文数Kx×KyL_{xy} = \frac{M_{xy} \times \text{全注文数}}{K_x \times K_y}

ここで、 MxyM_{xy} は商品xと商品yとが同一の注文で購入された注文数、 KxK_x は商品xが購入された注文数、 KyK_y は商品yが購入された注文数を表す。

表の例では、MABM_{AB}が2、全注文数が6、KAK_Aが4、KBK_Bが3であるので、商品Aと商品Bの関連度LABL_{AB}は、(2×6)/(4×3)= 1.0である。

手続 putRelatedItem は、大域変数 orders に格納された注文データを基に、引数で与えられた商品との関連度が最も大きい商品のうちの一つと、その関連度を出力する。

プログラムでは、商品は文字列で表し、注文は購入された商品の配列、注文データは注文の配列で表している。注文データには2種類以上の商品が含まれるものとする。また、注文データにある商品以外の商品が、引数として与えられることはないものとする。

[プログラム]
// 注文データ(ここでは表の例を与えている)
大域: 文字列型配列の配列: orders ← {{"A", "B", "D"}, {"A", "D"}, {"A"},{"A", "B", "E"}, {"B"}, {"C", "E"}}


○putRelatedItem(文字列型: item)
文字列型の配列: allItems ← ordersに含まれる文字列を重複なく辞書順に格納した配列
// 表の例では {"A", "B", "C", "D", "E"}


文字列型の配列: otherItems ← allItemsの複製から値がitemである要素を除いた配列


整数型: i, itemCount ← 0
整数型の配列: arrayK ← {otherItemsの要素数個の0}
整数型の配列: arrayM ← {otherItemsの要素数個の0}
実数型: valueL, maxL ← -∞
文字列型の配列: order
文字列型: relatedItem

for (orderにordersの要素を順に代入する)
if (orderのいずれかの要素の値がitemの値と等しい)
itemCountの値を1増やす
endif
for (iを1からotherItemsの要素数まで1ずつ増やす)
if (orderのいずれかの要素の値がotherItems[i]の値と等しい)
if (orderのいずれかの要素の値がitemの値と等しい)
  a  の値を1増やす
endif
 b  の値を1増やす
endif
endfor
endfor
for (iを1からotherItemsの要素数まで1ずつ増やす)
valueL ← (arrayM[i] ×  c  ) / (itemCount × arrayK[i])
if (valueLがmaxLより大きい)
maxL ← valueL
relatedItem ← otherItems[i]
endif
endfor
relatedItemの値とmaxLの値をこの順にコンマ区切りで出力する

出典令和6年度 公開問題 基本情報技術者試験 科目B 問5

a

b

c

ア

arrayK[i]

arrayM[i]

allItemsの要素数

イ

arrayK[i]

arrayM[i]

ordersの要素数

ウ

arrayK[i]

arrayM[i]

otherItemsの要素数

エ

arrayM[i]

arrayK[i]

allItemsの要素数

オ

arrayM[i]

arrayK[i]

ordersの要素数

カ

arrayM[i]

arrayK[i]

otherItemsの要素数