2016-11-04 33 views
0

我有任何長度的字符串項目的列表,我需要「正常化」此列表,以便每個項目是正常分佈的一部分,將權重附加到字符串。加權扁平列表的正常分佈

什麼是更有效的和數學/統計的方式去關於這個比我下面有什麼?

func normalizeAppend(in []string, shuffle bool) []string { 
    var ret []string 

    if shuffle { 
     shuffleStrings(in) 
    } 

    l := len(in) 
    switch { 
    case remain(l, 3) == 0: 
     l3 := (l/3) 
     var low, mid, high []string 
     for i, v := range in { 
      o := i + 1 
      switch { 
      case o <= l3: 
       low = append(low, v) 
      case o > l3 && o <= l3*2: 
       mid = append(mid, v) 
      case o >= l3*2: 
       high = append(high, v) 
      } 
     } 

     q1 := 1600/len(low) 
     q2 := 6800/len(mid) 
     q3 := 1600/len(high) 

     for _, v := range low { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q1)) 
     } 

     for _, v := range mid { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q2)) 
     } 

     for _, v := range high { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q3)) 
     } 
    case remain(l, 2) == 0 && l >= 4: 
     l4 := (l/4) 
     var first, second, third, fourth []string 
     for i, v := range in { 
      o := i + 1 
      switch { 
      case o <= l4: 
       first = append(first, v) 
      case o > l4 && o <= l4*2: 
       second = append(second, v) 
      case o > l4*2 && o <= l4*3: 
       third = append(third, v) 
      case o > l4*3: 
       fourth = append(fourth, v) 
      } 
     } 
     q1 := 1600/len(first) 
     q2 := 3400/len(second) 
     q3 := 3400/len(third) 
     q4 := 1600/len(fourth) 

     for _, v := range first { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q1)) 
     } 

     for _, v := range second { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q2)) 
     } 

     for _, v := range third { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q3)) 
     } 

     for _, v := range fourth { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, q4)) 
     } 
    default: 
     var first, second, third []string 
     q1 := (1 + math.Floor(float64(l)*.16)) 
     q3 := (float64(l) - math.Floor(float64(l)*.16)) 
     var o float64 
     for i, v := range in { 
      o = float64(i + 1) 
      switch { 
      case o <= q1: 
       first = append(first, v) 
      case o > q1 && o < q3: 
       second = append(second, v) 
      case o >= q3: 
       third = append(third, v) 
      } 
     } 
     lq1 := 1600/len(first) 
     lq2 := 3400/len(second) 
     lq3 := 1600/len(third) 
     for _, v := range first { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq1)) 
     } 

     for _, v := range second { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq2)) 
     } 

     for _, v := range third { 
      ret = append(ret, fmt.Sprintf("%s_%d", v, lq3)) 
     } 

    } 

    return ret 
} 

一些要求澄清:

我將從列表中選擇多次一個在由權重選擇一個時間項目的列表,開始與我有(隱含的)重物列表1:

[A_1,B_1,C_1,D_1,E_1,F_1,G_1,H_1,I_1,j_1,K_1]

我正在尋找一種更好的方式,使該列表到的東西產生更選擇權重的'正常'分佈:

[A_1,B_2,C_3,D_5,E_14,f_30,g_14,h_5,I_3,J_2,K_1]

或許很可能我需要改變我的方法來統計的東西更接地。底線是我想以多種方式控制項目列表中的選擇,其中之一是確保項目以接近正常曲線的方式返回。

+0

我不明白您的要求。你能澄清嗎?元素是正態分佈的一部分意味着什麼?通過附加重量,你的意思是簡單的字符串連接?也許你可以發表一個例子。 –

+0

這段代碼並不像問題和概念那麼重要,它只是對我正在工作的其他概念中的概念進行第一遍重擊。 – blueblank

+0

它只是關於計算權重(然後使用具有適當均值和方差的正態分佈公式)或關於從該分佈採樣(然後使用隨機生成器用於正態分佈)? –

回答

0

如果你只是想計算的權重對於給定的名單,那麼你需要下面的東西:

  • 正態分佈
  • 正態分佈
  • 一個discretizer的方差的平均值爲值

第一個很簡單。你想要的意思是在列表的中心。因此(假設從零開始的索引):

mean = (list.size - 1)/2 

第二種是隨意的,取決於你希望你的權重如何陡峭下降。在3 * standard_deviationmean之間的距離上,正態分佈的權重實際上爲零。因此,在大多數情況下,一個很好的標準偏差可能是第四和第六列表長度之間的事情:

standard_deviation = (1/4 .. 1/6) * list.size 
variance = standard_deviation^2 

假設你想要整型權,你需要從正態分佈離散的權重。最簡單的方法是通過指定最大重量(在平均位置的元素)。

就是這樣。 i位置的元素的重量爲:

weight[i] = round(max_weight * exp(-(i - mean)^2/(2 * variance)))