给出dc1,dc2,dc3和机器列表的数据中心列表,h1,h2,h3,h4如下所述 -
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 :(得分: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公共区:http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/ArithmeticUtils.html#binomialCoefficientDouble%28int,%20int%29
但是,如果您实际上想要生成这些组合,那么您需要一个for循环。
答案 1 :(得分:0)
不确定你在这里问过什么,但我想我能看到问题所在,每次调用get map你只生成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}]