Leetcode 1515. Best Position for a Service Centre (python)

题目

在这里插入图片描述

解法:gradient descent

还是第一次碰到用梯度下降做的题目。这个题目是没有办法找到精确解的,所以就能想到梯度下降了。这边梯度下降还得调一调参数,固定learning rate不太行,需要learning rate decay。也可以加momentum加快速度

with lr decay

class Solution:
    def getMinDistSum(self, positions: List[List[int]]) -> float:
        n = len(positions)
        if n<=1:
            return 0
        # partial derivative regard x
        def cal_dx(x,y):
            ans = 0
            for i in range(n):
                xi = positions[i][0]
                yi = positions[i][1]
                a = x-xi
                b = ((x-xi)**2+(y-yi)**2)**0.5
                tmp = a/b if b else 0
                ans += tmp
            return ans
        # partial derivative regard y
        def cal_dy(x,y):
            ans = 0
            for i in range(n):
                xi = positions[i][0]
                yi = positions[i][1]
                a = y-yi
                b = ((x-xi)**2+(y-yi)**2)**0.5
                tmp = a/b if b else 0
                ans += tmp
            return ans
        # compute cost
        def cal_cost(x,y):
            ans = 0
            for i in range(n):
                xi = positions[i][0]
                yi = positions[i][1]
                ans += ((x-xi)**2+(y-yi)**2)**0.5
            return ans
        
        # initialize x and y
        x = sum(p[0] for p in positions) / len(positions)
        y = sum(p[1] for p in positions) / len(positions)
        prev_cost = cal_cost(x,y)
        reduced_cost = float('inf')
        
        # perform gradient descent with lr decay
        lr = 10
        decay = 1 - (10 ** -3)
        while abs(reduced_cost)>1e-15:
            dx = cal_dx(x,y)
            dy = cal_dy(x,y)
            x = x-lr*dx
            y = y-lr*dy
            curr_cost = cal_cost(x,y)
            reduced_cost = prev_cost-curr_cost
            prev_cost = curr_cost
            lr *= decay
        return curr_cost

with lr decay and momentum

class Solution:
    def getMinDistSum(self, positions: List[List[int]]) -> float:
        n = len(positions)
        if n<=1:
            return 0
        # partial derivative regard x
        def cal_dx(x,y):
            ans = 0
            for i in range(n):
                xi = positions[i][0]
                yi = positions[i][1]
                a = x-xi
                b = ((x-xi)**2+(y-yi)**2)**0.5
                tmp = a/b if b else 0
                ans += tmp
            return ans
        # partial derivative regard y
        def cal_dy(x,y):
            ans = 0
            for i in range(n):
                xi = positions[i][0]
                yi = positions[i][1]
                a = y-yi
                b = ((x-xi)**2+(y-yi)**2)**0.5
                tmp = a/b if b else 0
                ans += tmp
            return ans
        # compute cost
        def cal_cost(x,y):
            ans = 0
            for i in range(n):
                xi = positions[i][0]
                yi = positions[i][1]
                ans += ((x-xi)**2+(y-yi)**2)**0.5
            return ans
        
        # initialize x and y
        x = sum(p[0] for p in positions) / len(positions)
        y = sum(p[1] for p in positions) / len(positions)
        prev_cost = cal_cost(x,y)
        reduced_cost = float('inf')
        dx = 0
        dy = 0
        
        # perform gradient descent with momentum and lr decay
        lr = 1
        momentum = 0.9
        decay = 0.98
        while abs(reduced_cost)>1e-15:
            dx = cal_dx(x,y) + momentum*dx
            dy = cal_dy(x,y) + momentum*dy
            x = x-lr*dx
            y = y-lr*dy
            curr_cost = cal_cost(x,y)
            reduced_cost = prev_cost-curr_cost
            prev_cost = curr_cost
            lr *= decay
        return curr_cost
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值