创建由 +6 个对象组成的 3 对,其中每对都有独特且不重复的对象

creating 3 pairs made from +6 objects where each pair has unique & unrepeated objects

我有一个可能的对象列表,长度可能为 6 个或更多 (+6 photons/gammas),我需要从这个列表中制作 3 对(3 个介子)。这些对都需要有唯一的对象,并且一旦成对就不能重复使用 gamma。

例如如果 pion1 由 gamma1(在代码中:ig1)和 gamma2(ig2)组成,那么 pions2 和 pions3 必须由 gammas3、4、5、6 等的所有可能组合组成(可能有超过 6 个伽马,但我只关心 3 个总介子),等等。

我尝试以下列方式进行下几个 for 循环:

int n_g = 8; // n_g >= 6
boolean hasDVPi0P = false;
for (int ig1 = 0; ig1 < n_g-5 && !hasDVPi0P ; ig1++) {
    for (int ig2 = ig1+1; ig2 < n_g-4 && !hasDVPi0P ; ig2++) {
        for (int ig3 = ig2+1; ig3 < n_g-3 && !hasDVPi0P ; ig3++) {
            for (int ig4 = ig3+1; ig4 < n_g-2 && !hasDVPi0P ; ig4++) {
                for (int ig5 = ig4+1; ig5 < n_g-1 && !hasDVPi0P ; ig5++) {
                    for (int ig6 = ig5+1; ig6 < n_g && !hasDVPi0P ; ig6++) {
                        System.out.println("(" + ig1 + "," + ig2 + ") , (" + ig3 + "," + ig4 + ") , (" + ig5 + "," + ig6 + ")");
                        }
                    }
                }
        }
    }
}  

这让我得到以下输出:

(0,1) , (2,3) , (4,5)
(0,1) , (2,3) , (4,6)
(0,1) , (2,3) , (4,7)
(0,1) , (2,3) , (5,6)
(0,1) , (2,3) , (5,7)
(0,1) , (2,3) , (6,7)
(0,1) , (2,4) , (5,6)
(0,1) , (2,4) , (5,7)
(0,1) , (2,4) , (6,7)
(0,1) , (2,5) , (6,7)
(0,1) , (3,4) , (5,6)
(0,1) , (3,4) , (5,7)
(0,1) , (3,4) , (6,7)
(0,1) , (3,5) , (6,7)
(0,1) , (4,5) , (6,7)
(0,2) , (3,4) , (5,6)
(0,2) , (3,4) , (5,7)
(0,2) , (3,4) , (6,7)
(0,2) , (3,5) , (6,7)
(0,2) , (4,5) , (6,7)
(0,3) , (4,5) , (6,7)
(1,2) , (3,4) , (5,6)
(1,2) , (3,4) , (5,7)
(1,2) , (3,4) , (6,7)
(1,2) , (3,5) , (6,7)
(1,2) , (4,5) , (6,7)
(1,3) , (4,5) , (6,7)
(2,3) , (4,5) , (6,7)

最初认为是正确的直到我检查了n_g=6,这让我

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

这显然是错误的输出。我试图通过以下方式找到 6 gamma 的所有唯一可能对:

n_g=6;
for(int ig1 = 0; ig1 < n_g-1; ig1++) {
    for(int ig2 = ig1+1; ig2 < n_g; ig2++) {
        System.out.print("(" + ig1 + "," + ig2 + ") ");
    }
    System.out.println("");
}

这给了我

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

有没有人知道我将如何使用 6 个 for 循环编辑第一个代码段以获得 3 对π介子,其中如果伽马用于 1 个π介子,它不会再次重复?对 中的顺序 很重要,这意味着如果一对是 (0,1),那么对 (1,0) 是不同的并且不可互换。

我建议将其分为两个步骤。

  1. 查找所有元素对(顺序很重要)。
  2. 查找所有组合对(顺序无关紧要)。

我整理了一个示例程序,你要分析的话

我做的第一件事是制作一个简单的 Pair class 来跟踪对、比较值并打印它们:

public class Pair {
  Integer one;
  Integer two;
  
  public Pair(Integer one, Integer two)
  {
    this.one = one;
    this.two = two;
  }
  
  public boolean hasNoMatchingValues(Pair other)
  {
    return !this.one.equals(other.one) && !this.one.equals(other.two) && !this.two.equals(other.one) && !this.two.equals(other.two);
  }
  
  public static boolean hasNoMatchingValues(Pair...values)
  {
    for(int i = 0; i < values.length - 1; i++)
    {
      for(int j = i + 1; j < values.length; j++)
      {
        if(!values[i].hasNoMatchingValues(values[j]))
          return false;
      }
    }
    return true;
  }
  
  @Override
  public String toString()
  {
    return "(" + one + ", " + two + ")";
  }
}

在此之后,我使用以下代码找到所有对,然后将它们匹配到 3 的组合中:

import java.util.ArrayList;
import java.util.List;

public class PairCombinations
{
  public static void main(String[] args)
  {
    //Builds the list of unique objects
    List<Integer> objectList = new ArrayList<>();
    for(int i = 0; i < 8; i++)
      objectList.add(i);

    //Finds all pairs and adds them to pairsList
    List<Pair> pairsList = new ArrayList<>();
    for(int i = 0; i < objectList.size() - 1; i++)
    {
      for(int j = i + 1; j < objectList.size(); j++)
      {
        pairsList.add(new Pair(objectList.get(i), objectList.get(j)));
        pairsList.add(new Pair(objectList.get(j), objectList.get(i)));
      }
    }
    
    //Loop three times since you want three combinations. Can be adjusted to a recursive form.
    List<List<Pair>> allCombos = new ArrayList<>();
    for(int i = 0; i < pairsList.size() - 2; i++)
    {
      for(int j = i + 1; j < pairsList.size() - 1; j++)
      {
        for(int k = j + 1; k < pairsList.size(); k++)
        {
          Pair one = pairsList.get(i), two = pairsList.get(j), three = pairsList.get(k);
          if(Pair.hasNoMatchingValues(one, two, three))
          {
            List<Pair> combos = new ArrayList<>();
            combos.add(one);
            combos.add(two);
            combos.add(three);
            allCombos.add(combos);
          }
        }
      }
    }
    
    //Print the results
    for(List<Pair> combo : allCombos)
      System.out.println(combo);
  }
}

如果您有任何问题,请告诉我。

万一有人想看到一个带有嵌套 for 循环的版本,以及一个将 (0,1) 视为与 (1,0) 相同的版本。这是一个比两个 类 的答案稍微简单的版本,我认为如果有人四处寻找以稍微不同的方式配对的方法,他们可能会受益。

int n_g = 6;
boolean hasDVPi0P = false;
for (int ig1 = 0; ig1 < n_g && !hasDVPi0P ; ig1++) {
    for (int ig2 = 0; ig2 < n_g && !hasDVPi0P ; ig2++) {
        for (int ig3 = 0; ig3 < n_g && !hasDVPi0P ; ig3++) {
            for (int ig4 = 0; ig4 < n_g && !hasDVPi0P ; ig4++) {
                for (int ig5 = 0; ig5 < n_g && !hasDVPi0P ; ig5++) {
                    for (int ig6 = 0; ig6 < n_g && !hasDVPi0P ; ig6++) {
                        if( true
                            && ig1<ig2 && ig3<ig4 && ig5<ig6 // different photons in each pair
                            && ig1<ig3 && ig1<ig5 && ig3<ig5 // unique first photon from each pair
                            && ig2!=ig3 && ig2!=ig4 && ig2!=ig5 && ig2!=ig6 // clean up rest of pairs below
                            && ig3!=ig4 && ig3!=ig5 && ig3!=ig6
                            && ig4!=ig5 && ig4!=ig6
                            ){
                            System.out.println("(" + ig1 + "," + ig2 + ") , (" + ig3 + "," + ig4 + ") , (" + ig5 + "," + ig6 + ")\n");
                        }
                    }
                }
            }
        }
    }
}

当然,您可以更改 int n_g = 6,但此方法保留嵌套的 for 循环并使用 if 语句来处理对,可以根据您可能需要的任何条件进行修改。

这最终对我来说是最有用的,因为另一个答案虽然内容广泛,但完全独立 类。我需要保持 3 对的支票完全包含并且比其他答案中提供的更短。