给定一组点 as 和一条线 ax+by+c = 0。我们需要在给定线上找到一个点,该点与给定点集的距离之和最小。
例子:
In above figure optimum location of point of x - y - 3 = 0 line
is (2, -1), whose total distance with other points is 20.77,
which is minimum obtainable total distance.
如果我们在无限距离的给定线上取一点,那么总距离成本将是无限的,现在当我们将该点在线上移向给定点时,总距离成本开始减少,一段时间后,它再次开始增加,达到无限线的另一个无限末端,因此距离成本曲线看起来像 U 型曲线,我们必须找到该 U 型曲线的底部值。
由于 U 曲线不是单调递增或递减的,我们不能使用二分搜索来寻找最底部的点,这里我们将使用三元搜索来寻找最底部的点,三元搜索在每次迭代时会跳过三分之一的搜索空间,您可以阅读更多关于三元搜索在这里。
所以解决方案如下,我们从低和高分别初始化为一些最小值和最大值开始,然后我们开始迭代,在每次迭代中我们计算两个中值,mid1和mid2,它们代表搜索中的1/3和2/3位置空间,我们计算所有点与 mid1 和 mid2 的总距离,并通过比较这些距离成本更新低或高,这个迭代一直持续到低和高变得近似相等。
C++
// C/C++ program to find optimum location and total cost
#include
using namespace std;
#define sq(x) ((x) * (x))
#define EPS 1e-6
#define N 5
// structure defining a point
struct point {
int x, y;
point() {}
point(int x, int y)
: x(x)
, y(y)
{
}
};
// structure defining a line of ax + by + c = 0 form
struct line {
int a, b, c;
line(int a, int b, int c)
: a(a)
, b(b)
, c(c)
{
}
};
// method to get distance of point (x, y) from point p
double dist(double x, double y, point p)
{
return sqrt(sq(x - p.x) + sq(y - p.y));
}
/* Utility method to compute total distance all points
when choose point on given line has x-coordinate
value as X */
double compute(point p[], int n, line l, double X)
{
double res = 0;
// calculating Y of choosen point by line equation
double Y = -1 * (l.c + l.a * X) / l.b;
for (int i = 0; i < n; i++)
res += dist(X, Y, p[i]);
return res;
}
// Utility method to find minimum total distance
double findOptimumCostUtil(point p[], int n, line l)
{
double low = -1e6;
double high = 1e6;
// loop until difference between low and high
// become less than EPS
while ((high - low) > EPS) {
// mid1 and mid2 are representative x co-ordiantes
// of search space
double mid1 = low + (high - low) / 3;
double mid2 = high - (high - low) / 3;
//
double dist1 = compute(p, n, l, mid1);
double dist2 = compute(p, n, l, mid2);
// if mid2 point gives more total distance,
// skip third part
if (dist1 < dist2)
high = mid2;
// if mid1 point gives more total distance,
// skip first part
else
low = mid1;
}
// compute optimum distance cost by sending average
// of low and high as X
return compute(p, n, l, (low + high) / 2);
}
// method to find optimum cost
double findOptimumCost(int points[N][2], line l)
{
point p[N];
// converting 2D array input to point array
for (int i = 0; i < N; i++)
p[i] = point(points[i][0], points[i][1]);
return findOptimumCostUtil(p, N, l);
}
// Driver code to test above method
int main()
{
line l(1, -1, -3);
int points[N][2] = {
{ -3, -2 }, { -1, 0 }, { -1, 2 }, { 1, 2 }, { 3, 4 }
};
cout << findOptimumCost(points, l) << endl;
return 0;
}
Java
// A Java program to find optimum location
// and total cost
class GFG {
static double sq(double x) { return ((x) * (x)); }
static int EPS = (int)(1e-6) + 1;
static int N = 5;
// structure defining a point
static class point {
int x, y;
point() {}
public point(int x, int y)
{
this.x = x;
this.y = y;
}
};
// structure defining a line of ax + by + c = 0 form
static class line {
int a, b, c;
public line(int a, int b, int c)
{
this.a = a;
this.b = b;
this.c = c;
}
};
// method to get distance of point (x, y) from point p
static double dist(double x, double y, point p)
{
return Math.sqrt(sq(x - p.x) + sq(y - p.y));
}
/* Utility method to compute total distance all points
when choose point on given line has x-coordinate
value as X */
static double compute(point p[], int n, line l,
double X)
{
double res = 0;
// calculating Y of choosen point by line equation
double Y = -1 * (l.c + l.a * X) / l.b;
for (int i = 0; i < n; i++)
res += dist(X, Y, p[i]);
return res;
}
// Utility method to find minimum total distance
static double findOptimumCostUtil(point p[], int n,
line l)
{
double low = -1e6;
double high = 1e6;
// loop until difference between low and high
// become less than EPS
while ((high - low) > EPS) {
// mid1 and mid2 are representative x
// co-ordiantes of search space
double mid1 = low + (high - low) / 3;
double mid2 = high - (high - low) / 3;
double dist1 = compute(p, n, l, mid1);
double dist2 = compute(p, n, l, mid2);
// if mid2 point gives more total distance,
// skip third part
if (dist1 < dist2)
high = mid2;
// if mid1 point gives more total distance,
// skip first part
else
low = mid1;
}
// compute optimum distance cost by sending average
// of low and high as X
return compute(p, n, l, (low + high) / 2);
}
// method to find optimum cost
static double findOptimumCost(int points[][], line l)
{
point[] p = new point[N];
// converting 2D array input to point array
for (int i = 0; i < N; i++)
p[i] = new point(points[i][0], points[i][1]);
return findOptimumCostUtil(p, N, l);
}
// Driver Code
public static void main(String[] args)
{
line l = new line(1, -1, -3);
int points[][] = { { -3, -2 },
{ -1, 0 },
{ -1, 2 },
{ 1, 2 },
{ 3, 4 } };
System.out.println(findOptimumCost(points, l));
}
}
// This code is contributed by Rajput-Ji
Python3
# A Python3 program to find optimum location
# and total cost
import math
class Optimum_distance:
# Class defining a point
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
# Class defining a line of ax + by + c = 0 form
class Line:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
# Method to get distance of point
# (x, y) from point p
def dist(self, x, y, p):
return math.sqrt((x - p.x) ** 2 +
(y - p.y) ** 2)
# Utility method to compute total distance
# all points when choose point on given
# line has x-coordinate value as X
def compute(self, p, n, l, x):
res = 0
y = -1 * (l.a*x + l.c) / l.b
# Calculating Y of choosen point
# by line equation
for i in range(n):
res += self.dist(x, y, p[i])
return res
# Utility method to find minimum total distance
def find_Optimum_cost_untill(self, p, n, l):
low = -1e6
high = 1e6
eps = 1e-6 + 1
# Loop until difference between low
# and high become less than EPS
while((high - low) > eps):
# mid1 and mid2 are representative x
# co-ordiantes of search space
mid1 = low + (high - low) / 3
mid2 = high - (high - low) / 3
dist1 = self.compute(p, n, l, mid1)
dist2 = self.compute(p, n, l, mid2)
# If mid2 point gives more total
# distance, skip third part
if (dist1 < dist2):
high = mid2
# If mid1 point gives more total
# distance, skip first part
else:
low = mid1
# Compute optimum distance cost by
# sending average of low and high as X
return self.compute(p, n, l, (low + high) / 2)
# Method to find optimum cost
def find_Optimum_cost(self, p, l):
n = len(p)
p_arr = [None] * n
# Converting 2D array input to point array
for i in range(n):
p_obj = self.Point(p[i][0], p[i][1])
p_arr[i] = p_obj
return self.find_Optimum_cost_untill(p_arr, n, l)
# Driver Code
if __name__ == "__main__":
obj = Optimum_distance()
l = obj.Line(1, -1, -3)
p = [ [ -3, -2 ], [ -1, 0 ],
[ -1, 2 ], [ 1, 2 ],
[ 3, 4 ] ]
print(obj.find_Optimum_cost(p, l))
# This code is contributed by Sulu_mufi
C#
// C# program to find optimum location
// and total cost
using System;
class GFG {
static double sq(double x) { return ((x) * (x)); }
static int EPS = (int)(1e-6) + 1;
static int N = 5;
// structure defining a point
public class point {
public int x, y;
public point() {}
public point(int x, int y)
{
this.x = x;
this.y = y;
}
};
// structure defining a line
// of ax + by + c = 0 form
public class line {
public int a, b, c;
public line(int a, int b, int c)
{
this.a = a;
this.b = b;
this.c = c;
}
};
// method to get distance of
// point (x, y) from point p
static double dist(double x, double y, point p)
{
return Math.Sqrt(sq(x - p.x) + sq(y - p.y));
}
/* Utility method to compute total distance
of all points when choose point on
given line has x-coordinate value as X */
static double compute(point[] p, int n, line l,
double X)
{
double res = 0;
// calculating Y of choosen point
// by line equation
double Y = -1 * (l.c + l.a * X) / l.b;
for (int i = 0; i < n; i++)
res += dist(X, Y, p[i]);
return res;
}
// Utility method to find minimum total distance
static double findOptimumCostUtil(point[] p, int n,
line l)
{
double low = -1e6;
double high = 1e6;
// loop until difference between
// low and high become less than EPS
while ((high - low) > EPS) {
// mid1 and mid2 are representative
// x co-ordiantes of search space
double mid1 = low + (high - low) / 3;
double mid2 = high - (high - low) / 3;
double dist1 = compute(p, n, l, mid1);
double dist2 = compute(p, n, l, mid2);
// if mid2 point gives more total distance,
// skip third part
if (dist1 < dist2)
high = mid2;
// if mid1 point gives more total distance,
// skip first part
else
low = mid1;
}
// compute optimum distance cost by
// sending average of low and high as X
return compute(p, n, l, (low + high) / 2);
}
// method to find optimum cost
static double findOptimumCost(int[, ] points, line l)
{
point[] p = new point[N];
// converting 2D array input to point array
for (int i = 0; i < N; i++)
p[i] = new point(points[i, 0], points[i, 1]);
return findOptimumCostUtil(p, N, l);
}
// Driver Code
public static void Main(String[] args)
{
line l = new line(1, -1, -3);
int[, ] points = { { -3, -2 },
{ -1, 0 },
{ -1, 2 },
{ 1, 2 },
{ 3, 4 } };
Console.WriteLine(findOptimumCost(points, l));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出
20.7652
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。