Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何预先计算有效的组合数,而不是使用while循环?_Java_Algorithm_Map_While Loop - Fatal编程技术网

Java 如何预先计算有效的组合数,而不是使用while循环?

Java 如何预先计算有效的组合数,而不是使用while循环?,java,algorithm,map,while-loop,Java,Algorithm,Map,While Loop,给定数据中心列表(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} 每个过程中的每个数据中心都应获得备用

给定数据中心列表(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得到h1
dc2得到h2
dc3得到h3
,因此每个数据中心的所有机器都不同。在第二次传递中,如
b
-现在
dc1得到h2
(因为dc1在第一次传递中已经得到h1),
dc2得到h3
(bcoz dc2在第一次传递中已经得到h2),以及
dc3得到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);
    }
}
公共类数据中心映射{
公共静态void main(字符串[]args){
DatacenterMachineMapping dcm=新的DatacenterMachineMapping(Arrays.asList(“dc1”、“dc2”、“dc3”)、Arrays.asList(
"h1,"h2,"h3,"h4";;
//有什么方法可以避免while循环?
while(true){
Map coloHost=dcm.getDatacenterMachineMapping();
System.out.println(coloHost);
对于(Map.Entry:coloHost.entrySet()){
}
}
}
}
类DatacenterMachineMapping{
私有布尔值firstCall=true;
私有int hostListIndex=0;
私有列表数据中心列表、主机列表;
私有映射dataCenterHostsMap=newhashmap();
公共数据中心机器映射(列表数据中心列表、列表主机列表){
this.datacenterList=datacenterList;
this.hostList=主机列表;
}
公共地图getDatacenterMachineMapping(){
Map datacenterMachineMapping=新建HashMap();
如果(!firstCall){

如果(hostListIndex不确定您在这里问了什么,但我想我可以看到问题所在,每次get-call-get-mapping您只生成一行。因此我重写了代码,使其生成所有映射,并返回映射列表。这样您就可以对它们执行所需操作

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;
    }

}

你说的是数学,答案是(n选择k),其中n是机器的数量,k是数据中心的数量

原因如下:顺序并不重要,因此我们假设数据中心总是按照相同的顺序排列。对于第一个数据中心,我们可以选择
n
机器中的任何一台。对于第二个,我们可以选择任何一台机器,除了之前选择的机器,因此
n*(n-1)
。下一个数据中心将导致
n*(n-1)*(n-2)
可能的情况

因此,如果您有10台机器和4个数据中心,您将有:

10*9*8*7
可能的组合

更多信息请点击此处:

如果您想要一个函数为您完成工作,它位于Apache commons中:


但是,如果您确实想要生成这些组合,那么您需要一个for循环。

有效组合的数量=Max(数据中心计数、机器计数)我刚刚运行了代码,它给出了
java.lang.ArrayIndexOutOfBoundsException:3
。我刚刚在
hostsList
中添加了一个主机,作为
h5
,然后运行它。而且,如果您看到输出,它有两次dc1,两次dc2。在一行中,它应该是dc1,dc2,dc3。谢谢。我应该使用哪个Maven依赖项来实现它是这样的。这让我有点困惑。
[{h4=dc1, h1=dc1, h3=dc3, h2=dc2}, {h4=dc2, h1=dc2, h3=dc1, h2=dc3}, {h4=dc3, h1=dc3, h3=dc2, h2=dc1}]