Weighted random map

五迷三道 提交于 2019-12-06 09:23:09

One way to look at the problem is to ignore (for the moment) the fact that you're dealing with a 2d grid. What you have are a set of weighted items. A standard way of randomly selecting from such a set is to:

  1. sum the weights, call the sum s
  2. select a uniform random value 0 <= u < s
  3. iterate through the items, keeping a running total t of the weights of the items you've examined
  4. as soon as t >= u, select the item you're currently looking at (the one whose weight you just added).

This can be modified to make multiple selections without replacement by adding the following steps:

  • After each selection, deduct the weight of the selected item from s (if your weights are floating point and stability is an issue, you might prefer to recalculate it from scratch, at least occasionally).

  • repeat from 2, but in step 3 skip items that have been previously selected.

If summing the weights is infeasible or undesirable (which it may be if your array is particularly large) there are other options. The first that comes to mind is rejection sampling, which is a fairly broad topic so I'll just refer you to google and wikipedia on that one, as their coverage is pretty good.

EDIT: Forgot to come back to the fact that you have a 2D array. You can speed things up significantly by pre-computing (MIPMAP-style) the sums of weights of a hierarchy of regions in the map, so you can skip quickly to the location of the actual selected weight.

the code:

  count = 0
  maxPointsInSet = 100
  foreach(point in array){
      if(randomWithChacnce(point.value))) {
         addToSet(point)
         count++
      }
      if(count == maxPointsInSet)
         break;
  }

  function randomWithChacnce(int num){
    random = a randomized number between 0 to 1 // or random from 1 to 100 num*100
    if(num >= random)
     return true;
    return false
  }

if u need it in any specific language just ask me

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!