【问题标题】:A strategy-proof method of finding the time complexity of complex algorithms?一种找到复杂算法时间复杂度的策略证明方法?
【发布时间】:2020-03-05 13:24:19
【问题描述】:

我对 Python 中的时间复杂度 (big-O) 有疑问。我想了解在尝试找到复杂算法的大 O 时需要实现的一般方法。我已经理解了计算简单算法的时间复杂度背后的原因,例如 for 循环遍历具有 O(n) 的 n 个元素的列表,或者有两个嵌套的 for 循环,每个循环遍历 2 个 n 元素列表,每个列表都有一个n**2 的大 O。但是,对于实现多个 if-elif-else 语句和 for 循环的更复杂的算法,我想看看是否有一种策略可以简单地基于代码以迭代方式确定我的代码使用了简单的启发式方法(例如,忽略恒定时间复杂度的 if 语句,或者在遍历 for 循环时总是对 n 求平方,或者在遇到 else 语句时做一些特定的事情)。

我创建了一个战舰游戏,我想使用上述策略来计算时间复杂度。


from random import randint

class Battle:
    def __init__(self):

        self.my_grid = [[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False],[False,False,False,False,False,False,False,False,False,False]]

    def putting_ship(self,x,y):
        breaker = False
        while breaker == False:
            r1=x
            r2=y
            element = self.my_grid[r1][r2]

            if element == True:
                continue
            else:
                self.my_grid[r1][r2] = True
                break


    def printing_grid(self):
        return self.my_grid


    def striking(self,r1,r2):

        element = self.my_grid[r1][r2]
        if element == True:
            print("STRIKE!")
            self.my_grid[r1][r2] = False
            return True
        elif element == False:
            print("Miss")
            return False


def game():
    battle_1 = Battle()
    battle_2 = Battle()

    score_player1 = 0
    score_player2 = 0
    turns = 5

    counter_ships = 2

    while True:
        input_x_player_1 = input("give x coordinate for the ship, player 1\n")
        input_y_player_1 = input("give y coordinate for the ship, player 1\n")

        battle_1.putting_ship(int(input_x_player_1),int(input_y_player_1))



        input_x_player_2 = randint(0,9)
        input_y_player_2 = randint(0,9)


        battle_2.putting_ship(int(input_x_player_2),int(input_y_player_2))

        counter_ships -= 1
        if counter_ships == 0:
            break


    while True:
        input_x_player_1 = input("give x coordinate for the ship\n")
        input_y_player_1 = input("give y coordinate for the ship\n")

        my_var = battle_1.striking(int(input_x_player_1),int(input_y_player_1))

        if  my_var == True:
            score_player1 += 1
            print(score_player1)


        input_x_player_2 = randint(0,9)
        input_y_player_2 = randint(0,9)


        my_var_2 = battle_2.striking(int(input_x_player_2),int(input_y_player_2))

        if  my_var_2 == True:
            score_player2 += 1
            print(score_player2)

        counter_ships -= 1
        if counter_ships == 0:
            break


    print("the score for player 1 is",score_player1)
    print("the score for player 2 is",score_player2)





print(game())

【问题讨论】:

    标签: python-3.x time-complexity big-o


    【解决方案1】:

    经验: 您可以在增加 n 的同时进行一些时间试验(所以可能会增加电路板尺寸?)并绘制结果数据。您可以通过线的曲线/斜率来判断时间复杂度是多少。

    理论: 解析脚本并跟踪您为任何给定的行或函数调用找到的最大 O()。任何排序操作都会给你 nlogn。 for 循环内的 for 循环将为您提供 n^2 (假设它们都在输入数据上进行迭代)等。时间复杂度与粗略有关。 O(n) 和 O(n*3) 都是线性时间,这才是真正重要的。我认为您无需担心所有 if-elif-else 逻辑的细节。也许只关注最坏的情况?

    【讨论】:

      【解决方案2】:

      如果它只是嵌套 for 循环和 if/else 语句,您可以采用 ibonyun 建议的方法 - 假设涵盖了所有 if/else 情况并查看最深的循环(注意某些操作例如排序或复制数组,可能会隐藏它们自己的循环。)

      但是,您的代码也有 while 循环。在这个特定的例子中,用fors 替换它们并不难,但是对于包含非平凡whiles 的代码,没有任何通用策略总是会给你带来复杂性——这是halting problem 的结果。

      例如:

      def collatz(n):
          n = int(abs(n))
          steps = 0
          while n != 1:
              if n%2 == 1:
                  n=3*n+1
              else:
                  n=n//2
              steps += 1
              print(n)
          print("Finished in",steps,"steps!")
      

      到目前为止,没有人能够证明这甚至可以完成所有 n,更不用说显示运行时的上限了。

      旁注:而不是破屏

      self.my_grid = [[False,False,...False],[False,False,...,False],...,[False,False,...False]]
      

      考虑类似:

      grid_size = 10
      self.my_grid = [[False for i in range(grid_size)] for j in range(grid_size)]
      

      这更容易阅读和检查。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-17
        • 1970-01-01
        相关资源
        最近更新 更多