
エクセルで30行に0-4の間の乱数を発生させて合計数を常に100にするにはどうすればいいのでしょうか。
VBAではないのですがやりたいことはCのほうの過去ログにあったのですが
http://oshiete1.watch.impress.co.jp/qa4035587.html
見ても全くわかりませんでした。
No.3ベストアンサー
- 回答日時:
>エクセルで30行に0-4の間の乱数を発生させて合計数を常に100
乱数 個数 合計
0 0
1 0
2 0 0
3 20 60
4 10 40 0から4の数値、30個の合計が100になる為には
───────── 4の数値が最低限10個、必要
30 100
4の出る確率を上げてみました。
Sub Test()
Dim v(29)
Dim i As Long, n As Long
Randomize
Do
For i = 0 To 29
n = Int(Rnd() * 8)
If n > 4 Then n = 4
v(i) = n
Next
Loop Until Application.Sum(v) = 100
Range("A1").Resize(30).Value = Application.Transpose(v)
End Sub
数値を変えてもうまく動きました。教えいただきありがとうございます。簡潔なのと回答が早かったのでこちらをBAにさせていただきました。他の方も教えていただきありがとうございました。
No.4
- 回答日時:
おもしろそうだったのでやってみました。
やってみたのは3パターン
・「test1」
乱数でどこに、乱数で何(値 1 ~ 4)を、を求めて
値を設定しないところは 0 のまま
・「test2」
乱数でどこに、を求めて 1 を加算していく
最悪無限ループに陥るかも
・「test3」
test2 の改良バージョン
傾向としては、
test1 は、最大値がでやすい?(乱数でどこ・・・が同じなら加算していたので)
test2 / test3 は平均されやすい?(乱数の発生頻度と同じ?)
0 の出現は、 test2 / test3 では少ない様な気がします。
(乱数なので、そういうものとしても良いのかも)
While 内の実行回数の少ない順(変数 k の値)は、
test1(100回以下) < test3(100回) < test2(100回以上)
の様な感じ(雰囲気で)
説明は省いても良いですかね
確かめられるのであれば、
Const CNUMSUM As Long = 100 ' 合計値
Const CROWMAX As Long = 30 ' 行数
Const CNUMMAX As Long = 4 ' 最大値
の値を変更して、
CROWMAX * CNUMMAX > CNUMSUM になっていればソコソコ動くと思います。
Public Sub test1()
Const CNUMSUM As Long = 100
Const CROWMAX As Long = 30
Const CNUMMAX As Long = 4
Dim iAry(1 To CROWMAX) As Long
Dim i As Long, k As Long
Dim iNum As Long, iR As Long
Randomize
For i = 1 To CROWMAX
iAry(i) = 0
Next
k = 0
iNum = CNUMSUM
While (iNum > 0)
k = k + 1
i = Int(CROWMAX * Rnd()) + 1
iR = Int((CNUMMAX) * Rnd()) + 1
If (iAry(i) + iR > CNUMMAX) Then iR = CNUMMAX - iAry(i)
If (iR > iNum) Then iR = iNum
iAry(i) = iAry(i) + iR
iNum = iNum - iR
Wend
Debug.Print "k = " & k
Range("A1").Resize(CROWMAX) = _
WorksheetFunction.Transpose(iAry)
End Sub
Public Sub test2()
Const CNUMSUM As Long = 100
Const CROWMAX As Long = 30
Const CNUMMAX As Long = 4
Dim iAry(1 To CROWMAX) As Long
Dim i As Long, k As Long
Dim iNum As Long
Randomize
For i = 1 To CROWMAX
iAry(i) = 0
Next
k = 0
iNum = CNUMSUM
While (iNum > 0)
k = k + 1
i = Int(CROWMAX * Rnd()) + 1
If (iAry(i) < CNUMMAX) Then
iAry(i) = iAry(i) + 1
iNum = iNum - 1
End If
Wend
Debug.Print "k = " & k
Range("B1").Resize(CROWMAX) = _
WorksheetFunction.Transpose(iAry)
End Sub
Public Sub test3()
Const CNUMSUM As Long = 100
Const CROWMAX As Long = 30
Const CNUMMAX As Long = 4
Dim iAry(1 To CROWMAX) As Long, iPos(1 To CROWMAX) As Long
Dim i As Long, j As Long, k As Long
Dim iNum As Long, iHdn As Long
Randomize
For i = 1 To CROWMAX
iAry(i) = 0
iPos(i) = i
Next
k = 0
iNum = CNUMSUM
iHdn = 0
While (iNum > 0)
k = k + 1
j = Int((CROWMAX - iHdn) * Rnd()) + 1
i = iPos(j)
iAry(i) = iAry(i) + 1
If (iAry(i) >= CNUMMAX) Then
iPos(j) = iPos(CROWMAX - iHdn)
iHdn = iHdn + 1
End If
iNum = iNum - 1
Wend
Debug.Print "k = " & k
Range("C1").Resize(CROWMAX) = _
WorksheetFunction.Transpose(iAry)
End Sub
No.2
- 回答日時:
「30個の乱数を並べて100でなかったらやり直し」ってのが理屈は簡単そうです。
でも、おそらく時間がかかると思うので、合計100になる状態を作っておいて(例えば10個4で20個3みたいな感じ)あとは、好みの回数だけ、ランダムな所から1引いて、ランダムな所に1加えるって作業を繰り返せば、それなりの状況が出来るのではないでしょうか?(もちろん0から1引いたり4に1足したらいけませんからその手の処理は必要です。)
その他であれば、30カ所の中のランダムな所に1を加えるという作業を100回繰り返すって方が、速度的には速いかも。(もちろん4だったら1は足しません)
お試しください。
No.1
- 回答日時:
言語が違っても、同じやり方のプログラムは作れます。
別解:
「1~30の乱数 r を発生させ、 r行目を+1する。既に4なら4でない行になるまで乱数発生を繰り返す」を100回繰り返す
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 exitの使い方
-
フォームを開くときに、コンボ...
-
VBAで配列のNULL判定
-
Excel-vba 文字列と変数を...
-
VB6.0-整数と余りを求める
-
足して100になるような乱数のア...
-
数字の位ごとの値を表示するプ...
-
DWORDって
-
C#で動的にコントロールを取得...
-
スピンボタンで小数点
-
エクセルのマクロについて教え...
-
フリーランタイマーの時間差分...
-
3bitアップダウンカウンタ(Up/...
-
VBAでダブルコーテーション入り...
-
COLUMN(1:1)の意味を教え...
-
VisualStudio2022でC言語プログ...
-
Accessコンボボックスにレコー...
-
[VBS]変数を定数に変換する方法...
-
excelの、ある数式内の{}の意...
-
VBAのWorksheetFunctionの引数...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 exitの使い方
-
Excel-vba 文字列と変数を...
-
フォームを開くときに、コンボ...
-
数字の位ごとの値を表示するプ...
-
VB6.0-整数と余りを求める
-
C#で動的にコントロールを取得...
-
VBAで配列のNULL判定
-
フリーランタイマーの時間差分...
-
足して100になるような乱数のア...
-
DWORDって
-
ラジオボタンの値の取得につい...
-
VBAの定数の使い方で、計算値を...
-
コンボボックスの名前を変数に...
-
定数のメリットとは?
-
C#でのIF文 時間比較のやり方
-
Excel VBA Forの使い方について...
-
【C++/CLI】コンボボックスの値...
-
DataGridView 複数行同時変更...
-
CGIのPerlの変数をJavaScrip...
-
世界のナベアツ
おすすめ情報