2013-11-04 49 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