1. ホーム
  2. c

[解決済み] すべての不連続なペアのセット

2022-02-20 11:11:51

質問

ある集合が与えられると {1,2,3,4,5...n}n 要素から、不連続なペアの集合をすべて見つける必要があります。

例えば、n=4 の場合、出力は次のようになります。

{(1,2),(3,4)},   {(1,3),(2,4)},   {(1,4),(2,3)}

何から手をつければいいのかすらわからない状態です。どのアルゴリズムを使うべきか、そしておそらく実装の詳細についても、誰かが提案してくれることを期待しています。

どのように解決するのですか?

編集する。
n=2*k の要素から (n-1)!!! の集合 (1*3*5*7...n-1) を再帰的に生成する Delphi のコード。

var
  A: TArray<Integer>;

  procedure Swap(i, j: integer);
  var
    t : integer;
  begin
    t := A[i];
    A[i] := A[j];
    A[j] := t;
  end;

  procedure MakePairs(Start: Integer; Pairs: string);
  var
    i: Integer;
  begin
    if Start >= Length(A) then
      Writeln(Pairs)
    else
    for i := Start + 1 to High(A) do begin
      Swap(Start + 1, i); //store used element in the array beginning
      MakePairs(Start + 2, Pairs + Format('(%d,%d)', [A[Start], A[Start + 1]]));
      Swap(Start + 1, i); //get it back
    end;
  end;

begin
  A := TArray<Integer>.Create(1,2,3,4,5,6);
  //be sure that array length is even!!!
  MakePairs(0, '');
  Writeln(PairCount);

出力します。

(1,2)(3,4)(5,6)
(1,2)(3,5)(4,6)
(1,2)(3,6)(5,4)
(1,3)(2,4)(5,6)
(1,3)(2,5)(4,6)
(1,3)(2,6)(5,4)
(1,4)(3,2)(5,6)
(1,4)(3,5)(2,6)
(1,4)(3,6)(5,2)
(1,5)(3,4)(2,6)
(1,5)(3,2)(4,6)
(1,5)(3,6)(2,4)
(1,6)(3,4)(5,2)
(1,6)(3,5)(4,2)
(1,6)(3,2)(5,4)
15

追加
奇数長の配列でも動作するバリエーション(変な並び方)

  procedure MakePairs(Start: Integer; Pairs: string);
  var
    i: Integer;
    OddFlag: Integer;
  begin
    if Start >= Length(A) then
      Memo1.Lines.Add(Pairs)
    else begin
      Oddflag := (High(A) - Start) and 1;
      for i := Start + OddFlag to High(A) do begin
        Swap(Start + OddFlag, i);
        if OddFlag = 1 then
          MakePairs(Start + 2, Pairs + Format('(%d,%d)', [A[Start], A[Start + 1]]))
        else
          MakePairs(Start + 1, Pairs);
        Swap(Start + OddFlag, i);
      end;
    end;
  end;

を(1,2,3,4,5)に置き換えます。

(2,3)(4,5)
(2,4)(3,5)
(2,5)(4,3)
(1,3)(4,5)
(1,4)(3,5)
(1,5)(4,3)
(2,1)(4,5)
(2,4)(1,5)
(2,5)(4,1)
(2,3)(1,5)
(2,1)(3,5)
(2,5)(1,3)
(2,3)(4,1)
(2,4)(3,1)
(2,1)(4,3)
15

現在は関係ありません。
もし、すべてのペアが一度だけ発生するのであれば(n=4の例では明らかではありません)、次のようにします。 ラウンドロビン・トーナメント・アルゴリズム

n=4 ケースはこちら