算法导论(一)Peak Finding

算法导论(一)Peak Finding

问题描述
有一个一维的向量,对于向量的中间位置元素来说,如果数值大于等于两边相邻位置元素的数值,则被认为是一个peak,对于向量边界位置元素来说,则只需大于等于一边相邻位置元素的数值就好。需要输出给定向量的一个peak。
如果条件是大于则可能不存在peak
算法
1.最直接的算法:从左到右遍历,时间复杂度为 θ ( n ) \theta(n) θ(n)
2.利用分治思维的算法:

if a[n/2]<a[n/2-1]
find a peak from a[1] to a[n/2-1]
else if a[n/2]<a[n/2+1]
find a peak from a[n/2+1] to a[n]
else
n/2 position is a peak

时间复杂度为 θ \theta θ(log2n)
问题描述
有一个二维的向量,如果某位置数值大于等于四邻域位置元素(边界只有三个或两个可比较的值)的数值,则被认为是一个peak。需要输出给定向量的一个peak。
算法
1.贪心Ascent算法
时间复杂度为 θ ( n 2 ) \theta(n^2) θ(n2)
2.利用分治思维的算法:

min = 0;max = m;
Pick a column j = (min+max)/2;
while true
	find the position(i, j) of the maximum of column j
	if (i,j-1)>(i,j)
		max = j;
		pick colum j = (min+max)/2;
	else if (i, j+1)>(i,j)
		min = j;
		pick colum j = (min+max)/2;
	else
		return (i,j);

时间复杂度为 θ \theta θ(nlog2m),其中n表示行数,m表示列数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的用 Pygame 实现 A* 算法的示例代码: ```python import pygame import math from queue import PriorityQueue WIDTH = 800 WIN = pygame.display.set_mode((WIDTH, WIDTH)) pygame.display.set_caption("A* Path Finding Algorithm") RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) YELLOW = (255, 255, 0) WHITE = (255, 255, 255) BLACK = (0, 0, 0) PURPLE = (128, 0, 128) ORANGE = (255, 165, 0) GREY = (128, 128, 128) TURQUOISE = (64, 224, 208) class Node: def __init__(self, row, col, width, total_rows): self.row = row self.col = col self.x = row * width self.y = col * width self.color = WHITE self.neighbors = [] self.width = width self.total_rows = total_rows def get_pos(self): return self.row, self.col def is_closed(self): return self.color == RED def is_open(self): return self.color == GREEN def is_barrier(self): return self.color == BLACK def is_start(self): return self.color == ORANGE def is_end(self): return self.color == TURQUOISE def reset(self): self.color = WHITE def make_start(self): self.color = ORANGE def make_closed(self): self.color = RED def make_open(self): self.color = GREEN def make_barrier(self): self.color = BLACK def make_end(self): self.color = TURQUOISE def make_path(self): self.color = PURPLE def draw(self, win): pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.width)) def update_neighbors(self, grid): self.neighbors = [] if self.row < self.total_rows - 1 and not grid[self.row + 1][self.col].is_barrier(): # DOWN self.neighbors.append(grid[self.row + 1][self.col]) if self.row > 0 and not grid[self.row - 1][self.col].is_barrier(): # UP self.neighbors.append(grid[self.row - 1][self.col]) if self.col < self.total_rows - 1 and not grid[self.row][self.col + 1].is_barrier(): # RIGHT self.neighbors.append(grid[self.row][self.col + 1]) if self.col > 0 and not grid[self.row][self.col - 1].is_barrier(): # LEFT self.neighbors.append(grid[self.row][self.col - 1]) def __lt__(self, other): return False def h(p1, p2): x1, y1 = p1 x2, y2 = p2 return abs(x1 - x2) + abs(y1 - y2) def reconstruct_path(came_from, current, draw): while current in came_from: current = came_from[current] current.make_path() draw() def algorithm(draw, grid, start, end): count = 0 open_set = PriorityQueue() open_set.put((0, count, start)) came_from = {} g_score = {node: float("inf") for row in grid for node in row} g_score[start] = 0 f_score = {node: float("inf") for row in grid for node in row} f_score[start] = h(start.get_pos(), end.get_pos()) open_set_hash = {start} while not open_set.empty(): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() current = open_set.get()[2] open_set_hash.remove(current) if current == end: reconstruct_path(came_from, end, draw) end.make_end() return True for neighbor in current.neighbors: temp_g_score = g_score[current] + 1 if temp_g_score < g_score[neighbor]: came_from[neighbor] = current g_score[neighbor] = temp_g_score f_score[neighbor] = temp_g_score + h(neighbor.get_pos(), end.get_pos()) if neighbor not in open_set_hash: count += 1 open_set.put((f_score[neighbor], count, neighbor)) open_set_hash.add(neighbor) neighbor.make_open() draw() if current != start: current.make_closed() return False def make_grid(rows, width): grid = [] gap = width // rows for i in range(rows): grid.append([]) for j in range(rows): node = Node(i, j, gap, rows) grid[i].append(node) return grid def draw_grid(win, rows, width): gap = width // rows for i in range(rows): pygame.draw.line(win, GREY, (0, i * gap), (width, i * gap)) for j in range(rows): pygame.draw.line(win, GREY, (j * gap, 0), (j * gap, width)) def draw(win, grid, rows, width): win.fill(WHITE) for row in grid: for node in row: node.draw(win) draw_grid(win, rows, width) pygame.display.update() def get_clicked_pos(pos, rows, width): gap = width // rows y, x = pos row = y // gap col = x // gap return row, col def main(win, width): ROWS = 50 grid = make_grid(ROWS, width) start = None end = None run = True started = False while run: draw(win, grid, ROWS, width) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if started: continue if pygame.mouse.get_pressed()[0]: # LEFT pos = pygame.mouse.get_pos() row, col = get_clicked_pos(pos, ROWS, width) node = grid[row][col] if not start and node != end: start = node start.make_start() elif not end and node != start: end = node end.make_end() elif node != end and node != start: node.make_barrier() elif pygame.mouse.get_pressed()[2]: # RIGHT pos = pygame.mouse.get_pos() row, col = get_clicked_pos(pos, ROWS, width) node = grid[row][col] node.reset() if node == start: start = None elif node == end: end = None if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE and not started: for row in grid: for node in row: node.update_neighbors(grid) algorithm(lambda: draw(win, grid, ROWS, width), grid, start, end) if event.key == pygame.K_c: start = None end = None grid = make_grid(ROWS, width) pygame.quit() main(WIN, WIDTH) ``` 这个示例代码实现了一个可视化的 A* 算法,可以通过左键点击来添加起点、终点和障碍物,然后通过按下空格键运行算法来查找最短路径。路径将用紫色标记出来。右键点击可以删除节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值