Gizport
1 回答
0
Share (facebook)
306
view
全般

<VBA> & <C言語> ある本で...

<VBA> & <C言語>
ある本で見つけたC言語による<ランダム順列>生成リスト(1行(=1ステップ以上)が作者が消してる)
があります

これをその1行を想像してEXCEL97VBAに改変したのですが、 重複した順列が表示されてしまう

> ●どこを修正すれば良いでしょうか?

プログラム名は
C言語 =CPERM; 当方=VBA253 としました

本には
k番目の要素を未決定要素 a[k],a[k+1],・・・・a[n] の中から 1/(n-k+1)の確率で決めていく
但し,重複は許さない
とあります

●CPERM
/*集合 {1,2,・・・,n} から r個を取り出し、1列に並べる部分順列をランダムに生成*/
/*要素交換に基づく方法*/

#include <stdio.h>
#include <stdlib.h>
#define N 20 /*集合の最大要素数*/
#define RMAX 32767.0 /*2の15乗 - 1*/
int a[N+1], /*部分順列を保存する配列*/
count, /*部分順列の個数*/
n, /*集合の要素数*/
r; /*取り出す個数*/

void perm(int k);

int main() {
int i, j;

/*乱数の初期値を設定*/
srand(1);

while (1) {

/*n , r の読み込み*/
scanf("%d%d", &n, &r);
if ( (n <= 0) || (n> N ) || (r > n) ) { break; }

/*初期設定*/
for ( j=1; j<=n; j++ ) { a[j] = j; }

/*ランダム部分順列の生成*/
for ( i=1; i<=5; i++ ) { perm(1); }
printf("n=%d r=%d
",n,r);
}
}

void perm(int k) {
int j, w;
float ran;

if ( k > r ) {
/*部分順列表示*/
for ( j=1; j<=r; j++ ) { printf ("%d", a[j]); }
printf(
);
} else {
ran = rand() / RMAX; /* 確率 */
j = ran * (n - k + 1) + k /* 交換する位置 */
/*交換*/
/*=======================*/ ◆ (消された1行)
perm k + 1
}
}



●VBA253
Public Sub VBA253

N = 4: R = 4: PSN = Application.Permut(N, R)
ReDim PS(PSN)
For J = 1 To N: PS(J) = J: Next
SU = 0
Randomize
'ランダム順列発生
For J = 1 To 24: PERM 1: Next
Debug.Print "N = " & N, "R = " & R, "SU = " & SU: Debug.Print
End Sub

Private Sub PERM(K As Integer)
Dim JX As Integer
If K > R Then
SU = SU + 1
FS = ""
For I = 1 To R: FS = FS & PS(I): Next
Debug.Print SU & ". " & FS
Else
JX = Int(Rnd * (N - K + 1) + K)
'交換
SWAP PS(JX), PS(K)
PERM K + 1
End If
End Sub
---------------------------
(VBA253)
N,R,I,J,PS(),FSはグローバル変数
PS[] ->a[]
SU -> count
JX -> j
に相当
メインVBA253から PERMを再帰呼出している
交換はSWAP X,Yというユーザー関数
交換対象が正しいかは不明?です

(CPERM)
C言語 :rand()は 0~32767を乱数発生 rand()/RMAXで 0~1へ変換

テストはCPERM5通り、VBA253はN=4,R=4として24通り出力

なお,C言語の方は転記なのでフォーマット崩れはご容赦

//
システムは windows xp sp3
XLは 97VBA
Yahoo!知恵袋 4010日前
コメントする
お気に入り
1
質問者が選んだベストソリューション
順列が重複しないようにしようと思ったら重複した時に入れ替えをやり直すようにするしか手がないように思うのですが…そのブランクでは普通は不可能ですから、この問題の意味は「1つの順列内での要素の重複を許さない」という意味なのではないでしょうか。
Yahoo!知恵袋 4003日前
シェア
 
コメントする
 

参考になったと評価
  このQ&Aは参考になりましたか?

Share (facebook)
その他の解決方法を知っていますか?
回答する
全般
51
Views
質問者が納得>どうやら合っているようなのですが、「0:00」が「0」として認識されないようです この辺がXL特有の演算誤差っぽいですね わざとN10を以下のようにしてみたらどうでしょうか? =TEXT(〜,"h:mm")*1 これで変われば演算誤差 整数部、小数点以下を含め16桁存在する微小な数値誤差です //
3563日前view51
全般
27
Views
質問者が納得順列が重複しないようにしようと思ったら重複した時に入れ替えをやり直すようにするしか手がないように思うのですが…そのブランクでは普通は不可能ですから、この問題の意味は「1つの順列内での要素の重複を許さない」という意味なのではないでしょうか。
4010日前view27
全般
147
Views
質問者が納得Yahooオークションで出品されています。 残り2日ですが、1,698円で即決落札できますよ!! 消費税はかかりません!! “早い者勝ち”の限定1個です。 貴方のテレビにピッタリの純正品ですよ~ yahooオークションの売り子がいれば・・・・・ 暇だったので、“こんな感じかな?”とやってみました。 下記を参照して頂ければ、同型品がありましたので・・・・・ http://page17.auctions.yahoo.co.jp/jp/auction/v194711362 あと・・・・ 送料を忘れて...
4610日前view147
全般
39
Views
質問者が納得物理的原因を考えてみてはどうでしょうか? LANケーブルは問題ないでしょうか? LANケーブル自体に破損があったり、コネクタに問題がないかは調べてみましたか? 後は、バックアップを行ってから全て初期化しての再設定ですかね。 意外と簡単なところに解決策がある場合もありますので。
4901日前view39
全般
115
Views
質問者が納得マルチという意味がわかりませんが。 現在は、あいにく品切れのようですが、ここのACアダプターは種類も多く、安いです。 ただしコネクターは、一般的な5mm◎のものになっていますから、なんらかの変換をしないとだめかもしれません。 http://akizukidenshi.com/catalog/g/gM-00244
5387日前view115

関連製品のQ&A