簡體   English   中英

Java中的內置比較排序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM