示例我有这个对象的ArrayList:
clusterData: [{BitSet: [1, 1], Entropy: 0.0}, {BitSet: [1, 0], Entropy: 1.0}, {BitSet: [0, 0], Entropy: 0.0}, {BitSet: [0, 0], Entropy: 0.0}, {BitSet: [0, 0], Entropy: 0.0}]
具有类似BitSet和Entropy值的那些将成为可能的对,并且在这种情况下它产生:
与#3对#2对
与#4对#2对
配对#3与配对#4
那么,从三个生成的对中,如何从三个可能的对中随机选择一个并存储在另一个ArrayList中?
这是我的代码:
System.out.println("clusterData: " + clusterData);
for (int i = 0; i < clusterData.size()-1; i++){
for (int j = i+1; j < clusterData.size(); j++){
if (clusterData.get(i).getBitSet().equals(clusterData.get(j).getBitSet()) && clusterData.get(i).getEntropy() == clusterData.get(j).getEntropy()){
System.out.println("Pair #" + i + " WITH Pair #" + j);
}
}
}
请帮忙。
答案 0 :(得分:0)
从整个集合中随机选取第一个。从一个较小的集合中取下一个(表示您不希望两个数字相同的事实)。如果第二个匹配或超过第一个,请添加一个。然后分配到i
和j
,以便i < j
。
// pick a from set [0..n)
// pick b from set [0..n-1)
// which can also be represented as two sets
// [0..a)[a..n-1)
// add one when b >= a, meaning b is in the sets:
// [0..a)(a..n)
Random r;
int a = r.nextInt(clusterData.size());
int b = r.nextInt(clusterData.size()-1);
if (b >= a)
b++;
if (a < b) {
i = a;
j = b;
} else {
i = b;
j = a;
}
答案 1 :(得分:0)
您可以将所有可能的对添加到List
并随机选择其中一个元素。
此代码将在O(N²)
中运行,其中N
是输入数据的大小。
更有效的方法是将群集数据分组到等价类(假设相似关系是等价关系,这似乎就是这种情况[传递性对于这种方法很重要])。
我将在这里使用ClusterData
作为元素类型的类型名称。
如果群集数据相似,则覆盖equals
的{{1}}和hashCode
以返回ClusterData
/相同的哈希码。
然后创建true
将不同的Map<ClusterData, List<Integer>>
值映射到ClusterData
列表中元素索引的列表。
clusterData
在下一步中计算可能的对数:
Map<ClusterData, List<Integer>> equivalenceClasses = IntStream.range(0, clusterData.size()).boxed()
.collect(Collectors.groupingBy(clusterData::get));
public static int choose2(int elements) {
return elements * (elements - 1) / 2;
}
决定其中一个等价类,其中每个等价类的概率与它可以提供的对数成比例:
int pairCount = equivalenceClasses.values().stream().mapToInt(lst -> choose2(lst.size())).sum();
最后从等价类中选择一个组合:
if (pairCount == 0) {
throw new IllegalArgumentException("No valid combinations");
}
Random random = ...
int choice = random.nextInt(pairCount);
List<Integer> classIndices = null;
for (List<Integer> indices : equivalenceClasses.values()) {
choice -= choose2(indices.size());
if (choice < 0) {
classIndices = indices;
break;
}
}
这应该在int first = random.nextInt(classIndices.size());
int second = random.nextInt(classIndices.size()-1);
if (second >= first) {
second++;
}
int firstIndex = classIndices.get(first);
int secondIndex = classIndices.get(second);
// TODO: swap indices, if firstIndex needs to be smaller than secondIndex
// and it's not already the case
System.out.println("Chosen combination: Pair #" + firstIndex + " WITH Pair #" + secondIndex);
上运行,并提高大输入数据的性能。