2014-02-14 31 views
0

鑑於數據中心這是DC1,DC2,DC3和機器,H1,H2,H3,H4的名單列表 -如何預先計算有效數量的組合而不是使用while循環?下面所提到

Datacenters = dc1, dc2, dc3 
Machines = h1, h2, h3, h4 

我想生成以下唯一組合 -

a) {dc1=h1, dc3=h3, dc2=h2} 

b) {dc1=h2, dc3=h4, dc2=h3} 

c) {dc1=h3, dc3=h1, dc2=h4} 

d) {dc1=h4, dc3=h2, dc2=h1} 

每個通道中的每個數據中心都應該獲得備用機器/主機。他們不應該得到相同的機器。例如在a中,如上所示 - dc1 gets h1,dc2 gets h2,dc3 gets h3所以所有機器對於每個數據中心都不相同。並且在b - 現在爲dc1 gets h2(因爲dc1已經在第一階段中已經獲得h1)中顯示的第二階段中,dc2 got h3(bcoz dc2在第一階段中已經獲得了h2)以及dc3 got h4(bcoz dc3在第一階段中已經獲得了h3)和等等等等

而且一個例子 - 如果我只有三個主機,然後在下面結合我應該得到的只有 -

Datacenters = dc1, dc2, dc3 
Machines = h1, h2, h3  

{dc1=h1, dc3=h3, dc2=h2} 
{dc1=h2, dc3=h1, dc2=h3} 
{dc1=h3, dc3=h2, dc2=h1} 

於是我想出了下面的代碼工作完全正常 -

public class DataCenterMapping { 

    public static void main(String[] args) { 

    DatacenterMachineMapping dcm = new DatacenterMachineMapping(Arrays.asList("dc1", "dc2", "dc3"), Arrays.asList(
     "h1", "h2", "h3", "h4")); 

     // is there any way to avoid while loop here? 
     while (true) { 
      Map<String, String> coloHost = dcm.getDatacenterMachineMapping(); 
      System.out.println(coloHost); 
      for (Map.Entry<String, String> entry : coloHost.entrySet()) { 

      } 
     } 
    } 
} 

class DatacenterMachineMapping { 

    private boolean firstCall = true; 
    private int hostListIndex = 0; 
    private List<String> datacenterList, hostList; 
    private Map<String, Set<String>> dataCenterHostsMap = new HashMap<String, Set<String>>(); 

    public DatacenterMachineMapping(List<String> datacenterList, List<String> hostList) { 
    this.datacenterList = datacenterList; 
    this.hostList = hostList; 
    } 

    public Map<String, String> getDatacenterMachineMapping() { 
    Map<String, String> datacenterMachineMapping = new HashMap<String, String>(); 
    if (!firstCall) { 
     if (hostListIndex <= 0) { 
     hostListIndex = hostList.size(); 
     } 
     hostListIndex--; 
    } else { 
     firstCall = false; 
    } 
    for (String datacenter : datacenterList) { 
     if (hostListIndex == hostList.size()) { 
     hostListIndex = 0; 
     } 
     if (addDataCenterHost(datacenter, hostList.get(hostListIndex))) { 
     datacenterMachineMapping.put(datacenter, hostList.get(hostListIndex++)); 
     } 
    } 
    hostListIndex--; 
    return datacenterMachineMapping; 
    } 

    private boolean addDataCenterHost(String datacenter, String host) { 
    Set<String> dataCenterHostSet = dataCenterHostsMap.get(datacenter); 
    if (dataCenterHostSet == null) { 
     dataCenterHostSet = new HashSet<String>(); 
     dataCenterHostsMap.put(datacenter, dataCenterHostSet); 
    } 
    return dataCenterHostSet.add(host); 
    } 
} 

問題陳述: -

唯一的問題是我有一個while循環,這將繼續始終運行,

有什麼辦法,我可以預先計算使用while循環有效組合的數量,而不是?

+0

有效組合數= Max(Datacenters_Count,Machines_Count) – MBo

回答

1

你說的是數學。答案是(n選擇k),其中n是機器的數量,k是數據中心的數量。

原因如下:排序並不重要,所以我們假設數據中心總是按照相同的順序排列。對於第一個數據中心,我們可以選擇任何一臺n機器。第二,我們可以選擇任何一臺機器,除了之前選擇的機器,因此n * (n-1)。下一個數據中心將導致n * (n-1) * (n-2)可能出現的情況。

因此,如果你有10臺機器,和4級的數據中心,你會:

10 * 9 * 8 * 7不可能性的組合。

此處瞭解詳情:http://en.wikipedia.org/wiki/Combination

如果你想有一個函數來爲你做的工作,它是在Apache Commons:中http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/ArithmeticUtils.html#binomialCoefficientDouble%28int,%20int%29

但是,如果你實際上是想產生這些組合,那麼你需要一個for循環。

+0

謝謝。我應該從這個[list](http://mvnrepository.com/artifact/org.apache.commons)爲此使用哪個Maven依賴項。它有點讓我困惑。 – AKIWEB

+0

http://mvnrepository.com/artifact/org.apache.commons/commons-math3/3.2 –

0

不是很確定你在這裏問了什麼,但我想我可以看到問題出在哪裏,每次打電話得到映射你只會產生1行。所以我重寫了代碼,以便生成所有這些代碼並返回地圖列表。所以你可以做他們需要的東西。

public class DataCenterMapping { 

    public static void main(String[] args) { 

     DatacenterMachineMapping dcm = new DatacenterMachineMapping(
       Arrays.asList("dc1", "dc2", "dc3"), Arrays.asList("h1", "h2", 
         "h3", "h4")); 


      List<Map<String, String>> coloHost = dcm 
        .getDatacenterMachineMappings(); 

      System.out.println(coloHost); 

    } 
} 

class DatacenterMachineMapping { 

    private boolean firstCall = true; 
    private int hostListIndex = 0; 
    private List<String> datacenterList, hostList; 

    public DatacenterMachineMapping(List<String> datacenterList, 
      List<String> hostList) { 
     this.datacenterList = datacenterList; 
     this.hostList = hostList; 
    } 

    public List<Map<String, String>> getDatacenterMachineMappings() { 
     List<Map<String, String>> grid = new ArrayList<Map<String, String>>(); 
     for (int i = 0; i < datacenterList.size(); i++) { 

      Map<String, String> datacenterMachineMapping = new HashMap<String, String>(); 
      String[] line = new String[hostList.size()]; 
      for (int j = 0; j < line.length; j++) { 
       int off = j + i; 
       if (off >= datacenterList.size()) { 
        off -= datacenterList.size(); 
       } 
       datacenterMachineMapping.put(hostList.get(j) ,datacenterList.get(off)); 
      } 

      grid.add(datacenterMachineMapping); 
     } 
     return grid; 
    } 

} 

輸出示例:

[{h4=dc1, h1=dc1, h3=dc3, h2=dc2}, {h4=dc2, h1=dc2, h3=dc1, h2=dc3}, {h4=dc3, h1=dc3, h3=dc2, h2=dc1}] 
+0

我剛剛運行了代碼,它給了'java.lang.ArrayIndexOutOfBoundsException:3'。我在'hostsList'中增加了一個主機作爲'h5',然後運行它。 – AKIWEB

+0

此外,如果您看到輸出,則它有dc1兩次,dc2兩次..在一行中,它應該是dc1,dc2,dc3只.. – AKIWEB

相關問題