Best Meeting Point

Total Accepted: 701 Total Submissions: 1714 Difficulty: Medium

A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid of values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated usingManhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.

For example, given three people living at (0,0)(0,4), and(2,2):

1 - 0 - 0 - 0 - 1
|   |   |   |   |
0 - 0 - 0 - 0 - 0
|   |   |   |   |
0 - 0 - 1 - 0 - 0

The point (0,2) is an ideal meeting point, as the total travel distance of 2+2+2=6 is minimal. So return 6.

分析:http://massivealgorithms.blogspot.com/2015/10/leetcode-best-meeting-point-segmentfault.html

首先, Manhattan Distance 的合为 sum(distance(p1, p2)) = sum( |p2.x - p1.x| + |p2.y - p1.y|)= sum(|p2.x - p1.x|)+sum(|p2.y - p1.y|). 也就是说, 可以分别计算x和y的合, 然后加起来.
其次, 我们需要把2d的grid变成1d, 这里的窍门是, 我们可以证明, 所求的点, 就在其中某点的x或者y的坐标轴上. 所以, 而这点, 必然是1d下的median.  http://math.stackexchange.com/questions/113270/the-median-minimizes-the-sum-of-absolute-deviations

Suppose we have a set S of real numbers that ∑s∈S|s−x|is minimal if x is equal to themedian.

所以, 我们需要count一下x轴上有多少个1的投影, 和y轴上有多少个1的投影. 就可以找到这个median. 这里我们不需要sorting, 因为投影本身就是已排序的.
最后, 我们得到一个1d的array, 我们需要计算以上公式,即各点到median的值的合, 这里需要用two pointers, 因为array本身已经是排序过后的了, 所以我们只需要求两头的元素的差值的合, 就是他们到median的合.
Image result for median

6是median,那么 (6-2)+(6-4) + (6-5) + (7-6) + (8-6) + (9-6) = 4 + 2+ 1+ 1+ 2+ 3 = 13 = (9-2) + (8-4) + (7-5)

public class Solution {
    public int minTotalDistance(int[][] grid) {
        List<Integer> xPoints = new ArrayList<>();
        List<Integer> yPoints = new ArrayList<>();

        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == 1) {
                    xPoints.add(i);
                    yPoints.add(j);
                }
            }
        }

        return getMP(xPoints) + getMP(yPoints);
    }

    private int getMP(List<Integer> points) {
        Collections.sort(points);
        int i = 0, j = points.size() - 1;
        int res = 0;
        while (i < j) {
            res += points.get(j--) - points.get(i++);
        }
        return res;
    }
}

 

转载于:https://www.cnblogs.com/beiyeqingteng/p/5739020.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
import randomimport multiprocessing# 定义目标函数,这里以一个简单的二维函数为例def target_func(x, y): return x ** 2 + y ** 2# 定义爬山算法,这里使用随机爬山算法def hill_climbing(start_point): current_point = start_point current_value = target_func(*current_point) while True: next_points = [(current_point[0] + random.uniform(-1, 1), current_point[1] + random.uniform(-1, 1)) for _ in range(10)] next_values = [target_func(*p) for p in next_points] next_point, next_value = min(zip(next_points, next_values), key=lambda x: x[1]) if next_value < current_value: current_point = next_point current_value = next_value else: break return current_point, current_value# 定义并行爬山函数def parallel_hill_climbing(num_workers, num_iterations, start_points): global_best_point, global_best_value = None, float('inf') pool = multiprocessing.Pool(num_workers) for i in range(num_iterations): results = pool.map(hill_climbing, start_points) best_point, best_value = min(results, key=lambda x: x[1]) if best_value < global_best_value: global_best_point, global_best_value = best_point, best_value start_points = [global_best_point] * len(start_points) return global_best_point, global_best_value# 测试代码if __name__ == '__main__': num_workers = 4 num_iterations = 10 start_points = [(random.uniform(-10, 10), random.uniform(-10, 10)) for _ in range(num_workers)] best_point, best_value = parallel_hill_climbing(num_workers, num_iterations, start_points) print(f'Best point: {best_point}, best value: {best_value}')
最新发布
05-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值