[英]Built-in comparison sorting in Java
假設我想對項目1到10進行排序,以便在排序后從中隨機選擇,並且選擇的可能性與每個數字的權重相關(即1的權重= 10、2的= 30、4的= 15、5的= 35、6的= 10,以及其余的0); 假設在此之前我已經計算了權重之和。 現在,我首先必須根據數字的權重對它們進行排序,然后再次通過列表將它們除以所有的總和(即進行歸一化,以使它們的權重在[0,1]中)。 排序然后遍歷列表很慢,所以我嘗試將權重放在compareTo()
方法中,以便在排序時進行規范化,但如果我這樣做,Collections.sort()不會將它們按正確的順序排列。 有什么建議(除了不得不從頭開始編寫自己的高效排序算法)? 我希望我很清楚。
是什么讓你認為你需要按重量排序隨機選擇數字?
我會做:
int[] numbers;
int[] weight;
int totalweight;
for (int n : numbers) {
totalweight += weight[n];
}
int t = new Random().nextInt(totalWeight);
for (int n : numbers) {
t -= weight[n];
if (t < 0) return n;
}
如果要從同一數組中反復選擇,則可能希望預先計算部分和並對它們進行二進制搜索。
如果您的數組由范圍明顯小於其長度的數字組成,您可以調整計數排序的想法,即為每個不同的數字預先計算部分和,並對這些進行二進制搜索。
很容易看出,除非您對所涉及的數字或權重有一些先驗知識,否則您需要查看每個數字的權重(因為它可能使所有其他權重相形見絀),因此一般算法必須至少采用O( N)。
但是,其他約束允許更有效的實現。 如果您知道數字權重的上限相對較小,則可以進行A / R采樣:
int[] numbers;
int[] weight;
int maxWeight;
Random r = new Random();
do {
c = numbers[r.nextInt(numbers.length)];
} while (r.nextInt(maxWeight) > weight[c]);
return c;
假設ints
是一個List
:
Collections.sort(ints, new Comparator<Integer> () {
private int getWeight(Integer i) {
int weight = 0;
switch(i) {
case 1:
case 6: weight = 10; break;
case 2: weight = 30; break;
case 4: weight = 15; break;
case 5: weight = 35; break;
}
return weight;
}
public int compare(Integer i1, Integer i2) {
int w1 = getWeight(i1);
int w2 = getWeight(i2);
return (w1>w2)?1:(w1==w2?0:-1);
}});
for(int i:ints) {
System.out.print(i+",");
}
您可以使用枚舉或散列圖來存儲數字的權重,代碼是如何進行基於權重的比較的示例。
只是建議改進Meriton的優秀建議:
如果要使第一部分更快,可以創建索引,以減少需要循環的元素。 計數重量時,對於每N個數字,請記下數組/哈希中的索引以及到目前為止的總和。
然后,選擇要循環的數字t時,您可以在索引中查找,然后將元素跳轉到該位置。 如果您有大量條目和多次查找,可能會節省您的時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.