用于计算决策投票块的递归代码

时间:2016-11-27 21:34:12

标签: python

假设选举过程有双方,"对于" "对于"
我试图编写一个程序,将一个投票块列表作为参数,然后计算每个块对结果的影响次数。例如,假设传递了参数[1,2,3,4],它应该执行以下操作。

  1. 评估不含4的可能组合,因此如下:

    1. 1 + 2 + 3(for)vs. 0(反对)
    2. 1 + 2(for)vs. 3(反对)
    3. 1 + 3(for)vs. 2(反对)
    4. 1(for)vs. 2 + 3(反对)
    5. 2 + 3(for)vs. 1(反对)
    6. 2(for)vs. 1 + 3(反对)
    7. 3(for)vs. 1 + 2(反对)
    8. 0(for)vs. 1 + 2 + 3(反对)
  2. 在案例2-7中添加 4 会导致结果以一种方式或另一种方式(或平局)摆动。因此,该程序将打印最后一个块( 4 )在6个案例中具有决定性投票。

  3. 之后,对于投票区块 3 也会这样做,因此会发生以下情况:

    1. 1 + 2 + 4(for)vs. 0(反对)
    2. 1 + 2(for)vs. 4(反对)
    3. 1 + 4(for)vs. 2(反对)
    4. 1(for)vs. 2 + 4(反对)
    5. 2 + 4(for)vs. 1(反对)
    6. 2(for)vs. 1 + 4(反对)
    7. 4(for)vs. 1 + 2(反对)
    8. 0(for)vs. 1 + 2 + 4(反对)
  4. 在2,3,6和7的情况下,添加块 3 会改变结果,因此 3 是4个案例中的决定块。

    1. 等等 2 1
    2. 我已经提出了以下递归代码,但由于某种原因,它不会超过3个块作为参数。

      import math
      def deciding_votes_per_block(blocks):
          if sum(blocks)%2: # same as last one
              return 1
          out = []
          for x in range(0,len(blocks),1): # going through each number in the blocks
              print(x)
              lst = blocks[:]
              del lst[x]
              out +=[swing_count(lst,blocks[x])] # sending out a list without element being checked for swing code as well as the element itself separately
          return out
      
      def swing_count(lst_left, swing_vote, lst_right=[]):
          print(lst_left,swing_vote,lst_right)
          if not lst_left: # this in theory is compensated by next if statement
              return 0
          elif not lst_right: # where recursion starts because lst_right is defaulted to empty
              if swing_vote >= sum(lst_left): # if swing vote matters...
                  return math.factorial(len(lst_left)) + swing_count(lst_left[1:],swing_vote,lst_right+[lst_left[0]]) # return all possible arrangements of elements and shift first element of left list to the right list
              else: # if it doesn't
                  return swing_count(lst_left[1:],swing_vote,lst_right+[lst_left[0]]) # just shift first element of left list to the right list
          else: # if both lists are not empty
              if sum(lst_left)>sum(lst_right): # if left list is bigger we look if swing vote plus right list can overtake left list
                  if (swing_vote + sum(lst_right)) >= sum(lst_left):
                      return 2*math.factorial(len(lst_right)) * math.factorial(len(lst_left)) + swing_count(lst_left[1:],swing_vote,lst_right+[lst_left[0]]) 
                  else:
                      return swing_count(lst_left[1:],swing_vote,lst_right+[lst_left[0]])
              elif sum(lst_left)<sum(lst_right): # if right list is bigger we look if swing vote plus left list can overtake right list
                  if (swing_vote + sum(lst_left))>= sum(lst_right):
                      return 2*math.factorial(len(lst_right)) * math.factorial(len(lst_left)) + swing_count(lst_left[1:],swing_vote,lst_right+[lst_left[0]]) 
                  else:
                      return swing_count(lst_left[1:],swing_vote,lst_right+[lst_left[0]])
              else: # if sum of both lists is equal we get all possible arrangements of numbers and shift element from right list to left
                  if swing_vote>0:
                      return 2*math.factorial(len(lst_right)) * math.factorial(len(lst_left)) + swing_count(lst_left[1:],swing_vote,lst_right+[lst_left[0]]) 
                  else:
                      return swing_count(lst_left[1:],swing_vote,lst_right+[lst_left[0]])
      

      我添加了一些评论以使其更清晰。

      提前谢谢

0 个答案:

没有答案