質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

515閲覧

ピポット要素の特性 `7n/10`になることはあるのか

langhtorn

総合スコア104

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/12/04 13:42

編集2020/12/04 13:52

###実現したいこと
中央値の中央値のアルゴリズムを作ってみました。
n個のリストについて考えます。
ここで再帰関数により選んだピポット要素より小さい値が7n/10ちょうどのときを探しています。
そのようになる値が出てくるようにリストとその要素数をランダムに作成しました。そしてそれを何回もシュミレーションするプログラムを作りました。しかし、ぴったり7n/10のとなるときは一度もありませんでした。
最大でも(7n/10)-1でした。
ぴったり7n/10となることはないのでしょうか。それかプログラムが間違っているのでしょうか。
###コード

python

1#選択アルゴリズムk番目 2 3import math 4import random 5def selection(a,k,num): 6 #print("input:",a,"k =",k) 7 n=len(a) 8 small=[] 9 smallb=[] 10 pilist=[] 11 def pivot(a,k): 12 if n>=5: 13 #先頭から5つずつに分けていく 14 for i in range(0,n,5): #[0]から[n]まで5こずつ 15 if i+4<n: #nが5の倍数ではない場合、最後は廃棄 16 start=i #分けた配列の最初の添え字 17 end=i+5 #分けた配列の最後の添え字 18 #print("start=",start,"end=",end) 19 20 small=a[start:end] #小配列を作る 21 smallb=sorted(small) #ソートした小配列 22 #print("smallb=",smallb) 23 #print("smallb[2]=",smallb[2]) 24 pilist.append(smallb[2]) #ピポット要素の配列 25 small.clear() 26 smallb.clear() 27 28 #ピポット要素の配列でさらに中央値を求める(再帰) 29 k=len(pilist)/2.0 30 pip=selection(pilist,math.ceil(k),num) 31 #print("return:",pip) 32 else: 33 k=n/2.0 34 k=math.ceil(k) 35 pip=a[k] 36 #print("returnpip:",pip) 37 return pip 38 n=len(a) #aのデータ数 39 L=[] 40 R=[] 41 if n<5: 42 b=sorted(a) 43 #print("k=",k) 44 #print("return:",b[k-1]) 45 return b[k-1] 46 else: 47 pi=pivot(a,k) #ピポット要素 48 #分割する 49 for i in range(n): 50 if a[i]<pi: 51 L.append(a[i]) 52 elif a[i]>pi: 53 R.append(a[i]) 54 nL=len(L) #Lのデータ数 55 nR=len(R) #Rのデータ数 56 numi=(7*num)/10 57 numi=math.floor(numi) 58 #print("numi=",numi) 59 if (numi-1)<=nL: 60 print("num=",num) 61 print("numi=",numi) 62 print("☆☆☆nL=",nL) 63 print("ピポット要素:",pi) 64 #print("L=",L) 65 66 #k番目を探す 67 if k<=nL: 68 ans=selection(L,k,num) 69 elif nL==k-1: 70 #print("return:",pi) 71 return pi #ピポット要素がk番目 72 else: 73 #print("②") 74 ans=selection(R,k-nL-1,num) 75 #print("return:",ans) 76 return ans 77 78# 重複なし 79def rand_ints_nodup(a, b, k): 80 ns = [] 81 while len(ns) < k: 82 n = random.randint(a, b) 83 if not n in ns: 84 ns.append(n) 85 return ns 86 87a=[] #リスト 88#リストに入力していく 89for i in range(1000): 90 num=random.randint(20,50) #リスト数 91 #print("num=",num) 92 a=rand_ints_nodup(0,100,num) #リストの中身 93 print("a=",a) 94 k=random.randint(1,num) 95 print("answer:",selection(a,k,num))

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

以下の箇所で、pilistの長さが偶数の時、常に中央2つの小さい側をpivotに採用しているので、
pivotより小さい値の数が少なくなる方に偏るのでしょう。

Python

1 #ピポット要素の配列でさらに中央値を求める(再帰) 2 k=len(pilist)/2.0 3 pip=selection(pilist,math.ceil(k),num)

偶数の時、常に中央2つの大きい側をpivotに採用するようにすれば、
長さが10の倍数のときにぴったり7n/10になる可能性が出てきます。

Python

1 #ピポット要素の配列でさらに中央値を求める(再帰) 2 k=(len(pilist)+1)/2.0 3 pip=selection(pilist,math.ceil(k),num)

投稿2020/12/04 15:45

actorbug

総合スコア2224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

langhtorn

2020/12/07 13:26

アドバイスありがとうございます。おかげで求めていた値が出てきました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問