2013-11-04 45 views
3

我有以下的Hashmap:基於值的頻率隨機選擇的一個關鍵

Map <Country, List<City>> map = new HashMap<Country, List<City>>(); 

我想挑選一組國家的隨意,具有以下條件:國家數字較小的城市應該有更高的被選中的可能性。

爲了解決這個問題,我想我會創建以下地圖:

Map <Country, Integer> map = new HashMap<Country, Integer>(); 

其中整數代表的List<City>大小。

這樣我就可以根據Integer值對Map進行排序,然後選擇具有低整數值的國家。

但是,看起來我正在以非常長的方式做到這一點,加上它不是很隨機。你有什麼建議如何有效地解決這個問題?

+2

你如何使用帶有你自己的'Comparator'的'TreeMap',它會根據大小自動對值進行排序? –

+0

你指的是什麼T和List?請從我們的角度重新閱讀您的帖子(因爲您沒有發佈任何內容而沒有看到您的代碼的人),並對其進行編輯,以便一切都清晰可見。 –

+1

地圖得到/放大概需要O(1),所以你的想法與額外的地圖保持價值頻率看起來不是「很長的路」 –

回答

2

在這裏有一個與遺傳算法中使用的技術平行。

這是很簡單的實現:

  1. 創建國家組成的數組誰大小是所有國家的總整數
  2. 把每個國家N次的數組,其中N是數城市
  3. 陣列

的國家將等於他們的城市

的號碼的概率採摘隨機選擇一個值

編輯:如果城市數量非常大,您可以通過除以最低城市數量來標準化數字,以便每個國家都保留在表格中。

+0

這使得擁有更多城市的國家被選中的概率更高。我想的恰恰相反,所以城市數量較少的國家很有可能被選中。 – RegUser

+0

也許倒數,然後乘以100?因爲你會得到一個低於1的數字? – RegUser

+0

我剛剛意識到這不是一個好主意,因爲我的一些值= 0,你不能被0除。那麼是否有另一種方法來做到這一點不涉及反轉)? – RegUser

0

我想挑選一組城市數量最少的國家。

然後你想要一個List國家的秩序或城市數量。爲什麼不創建一個Country類,它包含城市的List

public class Country{ 
    private final List<String> cityNames = new ArrayList<String>(); 
    private String name; 
    public Country(String n) { name = n; } 
    public void addCity(String name){ 
     cityNames.add(name); // omitting validation 
    } 
    public List<String> getCityNames(){ 
     List<String> newList = new ArrayList<String>(); 
     newList.addAll(cityNames); 
     return newList; 
    } 
    public int numberOfCities(){ 
     return cityNames.size(); 
    } 

    public String getName() { return name; } 

    @Override 
    public String toString(){ 
     return name + ": Number of Cities = " + cityNames.size(); 
    } 
} 

現在您可以排序基於城市國家名單指望這樣

... // inside some method 

     Collections.sort(countries, new Comparator<Country>() { 
     @Override 
     public int compare(Country o1, Country o2) { 
      if(o1.numberOfCities() < o2.numberOfCities()){ 
       return -1; 
      } 
      if(o1.numberOfCities() > o2.numberOfCities()){ 
       return 1; 
      } 
      return 0; 
     } 
    }); 

我只是用下面的(注測試這樣的:我添加了一個 「的toString()」 方法於國家或地區)

public static void main(String[] args) { 
    Country usa = new Country("USA"); 
    Country canada = new Country("Canada"); 
    Country brazil = new Country("Brazil"); 
    usa.addCity("Lansing"); 
    usa.addCity("New York"); 
    usa.addCity("Los Angeles"); 
    usa.addCity("Houston"); 

    canada.addCity("Toronto"); 

    canada.addCity("Niagra"); 

    brazil.addCity("Vila Velha"); 
    brazil.addCity("Rio"); 
    brazil.addCity("Barbacena"); 

    List<Country> countries = new ArrayList<Country>(); 
    countries.add(usa); 
    countries.add(brazil); 
    countries.add(canada); 
    System.out.println("\n\nAfter Sorting..."); 
    it = countries.iterator(); 
    while(it.hasNext()){ 
     System.out.println(it.next()); 
    } 
    Collections.sort(countries, new Comparator<Country>() { 
     @Override 
     public int compare(Country o1, Country o2) { 
      if(o1.numberOfCities() < o2.numberOfCities()){ 
       return -1; 
      } 
      if(o1.numberOfCities() > o2.numberOfCities()){ 
       return 1; 
      } 
      return 0; 
     } 
    }); 

    System.out.println("\n\nAfter Sorting..."); 
    it = countries.iterator(); 
    while(it.hasNext()){ 
     System.out.println(it.next()); 
    } 

} 

和輸出

Before sorting.... 
USA: Number of Cities = 4 
Brazil: Number of Cities = 3 
Canada: Number of Cities = 2 


After Sorting... 
Canada: Number of Cities = 2 
Brazil: Number of Cities = 3 
USA: Number of Cities = 4 
+0

」地圖是* un *排序集合。「取決於實施。例如LinkedHashMap維護一個插入順序。 – Julien

+0

好點。我將刪除該文本。 – MadConan

+0

排序後,你只是使用Math.Random,如果數字<0.8,那麼你從前50%選擇一個隨機指數,如果它> 0.8,你使用最後50%的隨機指數? – RegUser