Optimum location of point to minimize total distance
Last Updated : 1 Sep, 2026
Given a set of points points[][] of size 2 * n , where each point is represented as [p, q], and a line L[] represented by the equation ax + by + c = 0.
Find a point on the line L[] such that the sum of its Euclidean distances from all the given points is minimized. Return the minimum possible sum of distances, rounded to 2 decimal places.
Examples:Â
Input: n = 5,L[] = [1, -1, -3], points[][] = [[-3, 2], [-1, 0], [-1, 2], [1, 2], [3, 4]] Output: 20.77 Explanation: In the given 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.
Input: n = 3,L[] = [2, 1, 4], points[][] = [[-1, 2], [1, 3], [2, 4]] Output: 11.20 Explanation:Â The line represented by L[] is 2x + y + 4 = 0. The optimum point on this line is approximately (-2.64, 1.27). The sum of its Euclidean distances from all the given points is approximately 11.20, which is the minimum possible value.
Using Ternary Search - O(n * log(1/ε)) Time and O(1) Space
A straightforward linear search is therefore not suitable because we would have to sample many points along the line, and there is no fixed step size that guarantees finding the exact minimum.
Instead, we can parameterize every point on the line using a single variable t. This converts the original 2D optimization problem into a 1D problem.
If (x0, y0)(x_0, y_0) is any point on the line and (dx, dy)(dx, dy) is a unit direction vector along the line, every point on the line can be written as:
(x, y) = (x_0 + td_x, y_0 + td_y)
For a particular value of t, we calculate the sum of distances from this point to all the given points.
The resulting function is convex (unimodal), meaning it decreases until reaching its minimum and then increases. Therefore, instead of checking every possible t, we can use ternary search to efficiently locate the minimum.
Take the line ax + by + c = 0 and find any point (x0, y0) on it.
Use (b, -a) as the direction vector of the line and normalize it to a unit vector (dirX, dirY).
Project all given points onto the line to determine the search range [low, high] for parameter t.
Since the sum of Euclidean distances is a convex function, apply ternary search on [low, high].
For each iteration, calculate the total distance at mid1 and mid2, and discard the one-third that cannot contain the minimum.
After convergence, take the midpoint of the final range, convert it back to (x, y), and return the minimum sum of distances.
C++
#include<bits/stdc++.h>usingnamespacestd;// Calculate the sum of Euclidean distances from (x, y)// to all the given points.doublegetDistanceSum(vector<vector<int>>&points,doublex,doubley){doublesum=0.0;for(auto&point:points){doubledx=x-point[0];doubledy=y-point[1];sum+=sqrt(dx*dx+dy*dy);}returnsum;}doublefindOptimumCost(vector<int>&L,vector<vector<int>>&points){doublea=L[0];doubleb=L[1];doublec=L[2];// Find any point (x0, y0) lying on the line:// ax + by + c = 0doublex0=0.0,y0=0.0;if(b!=0)y0=-c/b;elsex0=-c/a;// (b, -a) is a direction vector parallel to the line.// Normalize it to get a unit direction vector.doublelen=sqrt(a*a+b*b);doubledirX=b/len;doubledirY=-a/len;// We represent every point on the line as://// (x, y) = (x0 + t * dirX, y0 + t * dirY)//// Find the range of t values corresponding to the// projections of all given points onto the line.doublelow=1e18;doublehigh=-1e18;for(auto&point:points){// Projection of (point - (x0, y0)) onto// the unit direction vector.doublet=(point[0]-x0)*dirX+(point[1]-y0)*dirY;low=min(low,t);high=max(high,t);}// The sum-of-distances function is convex, so// ternary search can be used to find its minimum.doubleeps=1e-7;while(high-low>eps){// Divide the current range into three parts.doublemid1=low+(high-low)/3.0;doublemid2=high-(high-low)/3.0;// Point corresponding to mid1.doublex1=x0+mid1*dirX;doubley1=y0+mid1*dirY;// Point corresponding to mid2.doublex2=x0+mid2*dirX;doubley2=y0+mid2*dirY;// Calculate the total distance at both points.doublecost1=getDistanceSum(points,x1,y1);doublecost2=getDistanceSum(points,x2,y2);// If cost1 is smaller, the minimum lies// in the left two-thirds.if(cost1<cost2){high=mid2;}// Otherwise, the minimum lies in the// right two-thirds.else{low=mid1;}}// Take the middle of the final range as the// approximate optimal value of t.doublet=(low+high)/2.0;// Convert t back to the corresponding point on the line.doublex=x0+t*dirX;doubley=y0+t*dirY;// Return the minimum possible sum of distances.returngetDistanceSum(points,x,y);}intmain(){vector<int>L={1,-1,-3};vector<vector<int>>points={{-3,-2},{-1,0},{-1,2},{1,2},{3,4}};doubleans=findOptimumCost(L,points);cout<<fixed<<setprecision(2)<<ans<<'\n';return0;}
Java
importjava.util.*;classGFG{staticdoublegetDistanceSum(int[][]points,doublex,doubley){doublesum=0.0;for(int[]point:points){doubledx=x-point[0];doubledy=y-point[1];sum+=Math.sqrt(dx*dx+dy*dy);}returnsum;}staticdoublefindOptimumCost(int[]L,int[][]points){doublea=L[0];doubleb=L[1];doublec=L[2];// Find any point (x0, y0) lying on the line:// ax + by + c = 0doublex0=0.0,y0=0.0;if(b!=0)y0=-c/b;elsex0=-c/a;// (b, -a) is a direction vector parallel to the// line. Normalize it to get a unit direction// vector.doublelen=Math.sqrt(a*a+b*b);doubledirX=b/len;doubledirY=-a/len;// We represent every point on the line as://// (x, y) = (x0 + t * dirX, y0 + t * dirY)//// Find the range of t values corresponding to the// projections of all given points onto the line.doublelow=1e18;doublehigh=-1e18;for(int[]point:points){// Projection of (point - (x0, y0)) onto// the unit direction vector.doublet=(point[0]-x0)*dirX+(point[1]-y0)*dirY;low=Math.min(low,t);high=Math.max(high,t);}// The sum-of-distances function is convex, so// ternary search can be used to find its minimum.doubleeps=1e-7;while(high-low>eps){// Divide the current range into three parts.doublemid1=low+(high-low)/3.0;doublemid2=high-(high-low)/3.0;// Point corresponding to mid1.doublex1=x0+mid1*dirX;doubley1=y0+mid1*dirY;// Point corresponding to mid2.doublex2=x0+mid2*dirX;doubley2=y0+mid2*dirY;// Calculate the total distance at both points.doublecost1=getDistanceSum(points,x1,y1);doublecost2=getDistanceSum(points,x2,y2);// If cost1 is smaller, the minimum lies// in the left two-thirds.if(cost1<cost2){high=mid2;}// Otherwise, the minimum lies in the// right two-thirds.else{low=mid1;}}// Take the middle of the final range as the// approximate optimal value of t.doublet=(low+high)/2.0;// Convert t back to the corresponding point on the// line.doublex=x0+t*dirX;doubley=y0+t*dirY;// Return the minimum possible sum of distances.returngetDistanceSum(points,x,y);}publicstaticvoidmain(String[]args){int[]L={1,-1,-3};int[][]points={{-3,-2},{-1,0},{-1,2},{1,2},{3,4}};doubleans=findOptimumCost(L,points);System.out.printf("%.2f%n",ans);}}
Python
importmath# Calculate the sum of Euclidean distances from (x, y)# to all the given points.defgetDistanceSum(points,x,y):sum=0.0forpointinpoints:dx=x-point[0]dy=y-point[1]sum+=math.sqrt(dx*dx+dy*dy)returnsumdeffindOptimumCost(L,points):a=L[0]b=L[1]c=L[2]# Find any point (x0, y0) lying on the line:# ax + by + c = 0x0=0.0y0=0.0ifb!=0:y0=-c/belse:x0=-c/a# (b, -a) is a direction vector parallel to the line.# Normalize it to get a unit direction vector.length=math.sqrt(a*a+b*b)dirX=b/lengthdirY=-a/length# We represent every point on the line as:## (x, y) = (x0 + t * dirX, y0 + t * dirY)## Find the range of t values corresponding to the# projections of all given points onto the line.low=1e18high=-1e18forpointinpoints:# Projection of (point - (x0, y0)) onto# the unit direction vector.t=(point[0]-x0)*dirX+(point[1]-y0)*dirYlow=min(low,t)high=max(high,t)# The sum-of-distances function is convex, so# ternary search can be used to find its minimum.eps=1e-7whilehigh-low>eps:# Divide the current range into three parts.mid1=low+(high-low)/3.0mid2=high-(high-low)/3.0# Point corresponding to mid1.x1=x0+mid1*dirXy1=y0+mid1*dirY# Point corresponding to mid2.x2=x0+mid2*dirXy2=y0+mid2*dirY# Calculate the total distance at both points.cost1=getDistanceSum(points,x1,y1)cost2=getDistanceSum(points,x2,y2)# If cost1 is smaller, the minimum lies# in the left two-thirds.ifcost1<cost2:high=mid2# Otherwise, the minimum lies in the# right two-thirds.else:low=mid1# Take the middle of the final range as the# approximate optimal value of t.t=(low+high)/2.0# Convert t back to the corresponding point on the line.x=x0+t*dirXy=y0+t*dirY# Return the minimum possible sum of distances.returngetDistanceSum(points,x,y)# Driver Codeif__name__=="__main__":L=[1,-1,-3]points=[[-3,-2],[-1,0],[-1,2],[1,2],[3,4]]ans=findOptimumCost(L,points)print(f"{ans:.2f}")
C#
usingSystem;classGFG{staticdoubleGetDistanceSum(int[,]points,doublex,doubley){doublesum=0.0;intn=points.GetLength(0);for(inti=0;i<n;i++){doubledx=x-points[i,0];doubledy=y-points[i,1];sum+=Math.Sqrt(dx*dx+dy*dy);}returnsum;}staticdoublefindOptimumCost(int[]L,int[,]points){doublea=L[0];doubleb=L[1];doublec=L[2];// Find any point (x0, y0) lying on the line:// ax + by + c = 0doublex0=0.0;doubley0=0.0;if(b!=0)y0=-c/b;elsex0=-c/a;// (b, -a) is a direction vector parallel to the// line. Normalize it to get a unit direction// vector.doublelen=Math.Sqrt(a*a+b*b);doubledirX=b/len;doubledirY=-a/len;// We represent every point on the line as://// (x, y) = (x0 + t * dirX, y0 + t * dirY)//// Find the range of t values corresponding to the// projections of all given points onto the line.doublelow=1e18;doublehigh=-1e18;intn=points.GetLength(0);for(inti=0;i<n;i++){// Projection of (point - (x0, y0)) onto// the unit direction vector.doubleproj=(points[i,0]-x0)*dirX+(points[i,1]-y0)*dirY;low=Math.Min(low,proj);high=Math.Max(high,proj);}// The sum-of-distances function is convex, so// ternary search can be used to find its minimum.doubleeps=1e-7;while(high-low>eps){// Divide the current range into three parts.doublemid1=low+(high-low)/3.0;doublemid2=high-(high-low)/3.0;// Point corresponding to mid1.doublex1=x0+mid1*dirX;doubley1=y0+mid1*dirY;// Point corresponding to mid2.doublex2=x0+mid2*dirX;doubley2=y0+mid2*dirY;// Calculate the total distance at both points.doublecost1=GetDistanceSum(points,x1,y1);doublecost2=GetDistanceSum(points,x2,y2);// If cost1 is smaller, the minimum lies// in the left two-thirds.if(cost1<cost2){high=mid2;}// Otherwise, the minimum lies in the// right two-thirds.else{low=mid1;}}// Take the middle of the final range as the// approximate optimal value of t.doublet=(low+high)/2.0;// Convert t back to the corresponding point on the// line.doublex=x0+t*dirX;doubley=y0+t*dirY;// Return the minimum possible sum of distances.returnGetDistanceSum(points,x,y);}publicstaticvoidMain(){int[]L={1,-1,-3};int[,]points={{-3,-2},{-1,0},{-1,2},{1,2},{3,4}};doubleans=findOptimumCost(L,points);Console.WriteLine(ans.ToString("F2"));}}
JavaScript
// Calculate the sum of Euclidean distances from (x, y)// to all the given points.functiongetDistanceSum(points,x,y){letsum=0.0;for(constpointofpoints){constdx=x-point[0];constdy=y-point[1];sum+=Math.sqrt(dx*dx+dy*dy);}returnsum;}functionfindOptimumCost(L,points){consta=L[0];constb=L[1];constc=L[2];// Find any point (x0, y0) lying on the line:// ax + by + c = 0letx0=0.0;lety0=0.0;if(b!==0)y0=-c/b;elsex0=-c/a;// (b, -a) is a direction vector parallel to the line.// Normalize it to get a unit direction vector.constlen=Math.sqrt(a*a+b*b);constdirX=b/len;constdirY=-a/len;// We represent every point on the line as://// (x, y) = (x0 + t * dirX, y0 + t * dirY)//// Find the range of t values corresponding to the// projections of all given points onto the line.letlow=1e18;lethigh=-1e18;for(constpointofpoints){// Projection of (point - (x0, y0)) onto// the unit direction vector.constt=(point[0]-x0)*dirX+(point[1]-y0)*dirY;low=Math.min(low,t);high=Math.max(high,t);}// The sum-of-distances function is convex, so// ternary search can be used to find its minimum.consteps=1e-7;while(high-low>eps){// Divide the current range into three parts.constmid1=low+(high-low)/3.0;constmid2=high-(high-low)/3.0;// Point corresponding to mid1.constx1=x0+mid1*dirX;consty1=y0+mid1*dirY;// Point corresponding to mid2.constx2=x0+mid2*dirX;consty2=y0+mid2*dirY;// Calculate the total distance at both points.constcost1=getDistanceSum(points,x1,y1);constcost2=getDistanceSum(points,x2,y2);// If cost1 is smaller, the minimum lies// in the left two-thirds.if(cost1<cost2){high=mid2;}// Otherwise, the minimum lies in the// right two-thirds.else{low=mid1;}}// Take the middle of the final range as the// approximate optimal value of t.constt=(low+high)/2.0;// Convert t back to the corresponding point on the// line.constx=x0+t*dirX;consty=y0+t*dirY;// Return the minimum possible sum of distances.returngetDistanceSum(points,x,y);}// Driver CodeconstL=[1,-1,-3];constpoints=[[-3,-2],[-1,0],[-1,2],[1,2],[3,4]];constans=findOptimumCost(L,points);console.log(ans.toFixed(2));
Output
20.77
Using Golden Section Search - O(n * log(1/ε)) Time and O(1) Space
Ternary search checks two new points in every iteration, so it calculates the distance sum twice. Golden Section Search improves this by choosing the points using the golden ratio
φ = (√5 - 1) / 2 ≈ 0.618
, so that after shrinking the range, one of the old points can be reused. Thus, in every iteration, we calculate the distance sum for only one new point, making the search more efficient while still finding the minimum of the convex function.
Find a point (x0, y0) on the line and obtain the unit direction vector (dirX, dirY).
Project all given points onto the line to determine the search range [low, high].
Use the golden ratio to divide the range into two points x1 and x2.
Calculate the sum of distances at these two points.
Compare the costs and shrink the interval; reuse the previously calculated cost whenever possible.
Continue until the interval is sufficiently small, then evaluate the middle point to get the minimum cost.
C++
#include<bits/stdc++.h>usingnamespacestd;// Calculate the sum of Euclidean distances from (x, y)// to all the given points.doublegetDistanceSum(vector<vector<int>>&points,doublex,doubley){doublesum=0.0;for(auto&point:points){doubledx=x-point[0];doubledy=y-point[1];sum+=sqrt(dx*dx+dy*dy);}returnsum;}doublefindOptimumCost(vector<int>&L,vector<vector<int>>&points){doublea=L[0];doubleb=L[1];doublec=L[2];// Find any point (x0, y0) lying on the line:// ax + by + c = 0doublex0=0.0,y0=0.0;if(b!=0)y0=-c/b;elsex0=-c/a;// (b, -a) is a direction vector parallel to the line.// Normalize it to get a unit direction vector.doublelen=sqrt(a*a+b*b);doubledirX=b/len;doubledirY=-a/len;// We represent every point on the line as://// (x, y) = (x0 + t * dirX, y0 + t * dirY)//// Find the range of t values corresponding to the// projections of all given points onto the line.doublelow=1e18;doublehigh=-1e18;for(auto&point:points){// Projection of (point - (x0, y0)) onto// the unit direction vector.doublet=(point[0]-x0)*dirX+(point[1]-y0)*dirY;low=min(low,t);high=max(high,t);}// The sum-of-distances function is convex, so// Golden Section Search can be used to find its minimum.// Golden ratio value.doublephi=(sqrt(5.0)-1.0)/2.0;doubleeps=1e-7;// Initial two points using the golden ratio.doublemid1=high-phi*(high-low);doublemid2=low+phi*(high-low);// Calculate the total distance at both points.doublecost1=getDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY);doublecost2=getDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY);while(high-low>eps){// If cost1 is smaller, the minimum lies// in the left part of the range.if(cost1<cost2){high=mid2;// Reuse the previous point and its cost.mid2=mid1;cost2=cost1;// Calculate only one new point.mid1=high-phi*(high-low);cost1=getDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY);}// Otherwise, the minimum lies in the// right part of the range.else{low=mid1;// Reuse the previous point and its cost.mid1=mid2;cost1=cost2;// Calculate only one new point.mid2=low+phi*(high-low);cost2=getDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY);}}// Take the middle of the final range as the// approximate optimal value of t.doublet=(low+high)/2.0;// Convert t back to the corresponding point on the line.doublex=x0+t*dirX;doubley=y0+t*dirY;// Return the minimum possible sum of distances.returngetDistanceSum(points,x,y);}intmain(){vector<int>L={1,-1,-3};vector<vector<int>>points={{-3,-2},{-1,0},{-1,2},{1,2},{3,4}};doubleans=findOptimumCost(L,points);cout<<fixed<<setprecision(2)<<ans<<'\n';return0;}
Java
importjava.util.*;classGFG{staticdoublegetDistanceSum(int[][]points,doublex,doubley){doublesum=0.0;for(int[]point:points){doubledx=x-point[0];doubledy=y-point[1];sum+=Math.sqrt(dx*dx+dy*dy);}returnsum;}staticdoublefindOptimumCost(int[]L,int[][]points){doublea=L[0];doubleb=L[1];doublec=L[2];// Find any point (x0, y0) lying on the line:// ax + by + c = 0doublex0=0.0;doubley0=0.0;if(b!=0)y0=-c/b;elsex0=-c/a;// (b, -a) is a direction vector parallel to the// line. Normalize it to get a unit direction// vector.doublelen=Math.sqrt(a*a+b*b);doubledirX=b/len;doubledirY=-a/len;// We represent every point on the line as://// (x, y) = (x0 + t * dirX, y0 + t * dirY)//// Find the range of t values corresponding to the// projections of all given points onto the line.doublelow=1e18;doublehigh=-1e18;for(int[]point:points){// Projection of (point - (x0, y0)) onto// the unit direction vector.doublet=(point[0]-x0)*dirX+(point[1]-y0)*dirY;low=Math.min(low,t);high=Math.max(high,t);}// The sum-of-distances function is convex, so// Golden Section Search can be used to find its// minimum.// Golden ratio value.doublephi=(Math.sqrt(5.0)-1.0)/2.0;doubleeps=1e-7;// Initial two points using the golden ratio.doublemid1=high-phi*(high-low);doublemid2=low+phi*(high-low);// Calculate the total distance at both points.doublecost1=getDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY);doublecost2=getDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY);while(high-low>eps){// If cost1 is smaller, the minimum lies// in the left part of the range.if(cost1<cost2){high=mid2;// Reuse the previous point and its cost.mid2=mid1;cost2=cost1;// Calculate only one new point.mid1=high-phi*(high-low);cost1=getDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY);}// Otherwise, the minimum lies in the// right part of the range.else{low=mid1;// Reuse the previous point and its cost.mid1=mid2;cost1=cost2;// Calculate only one new point.mid2=low+phi*(high-low);cost2=getDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY);}}// Take the middle of the final range as the// approximate optimal value of t.doublet=(low+high)/2.0;// Convert t back to the corresponding point on the// line.doublex=x0+t*dirX;doubley=y0+t*dirY;// Return the minimum possible sum of distances.returngetDistanceSum(points,x,y);}publicstaticvoidmain(String[]args){int[]L={1,-1,-3};int[][]points={{-3,-2},{-1,0},{-1,2},{1,2},{3,4}};doubleans=findOptimumCost(L,points);System.out.printf("%.2f%n",ans);}}
Python
importmath# Calculate the sum of Euclidean distances from (x, y)# to all the given points.defgetDistanceSum(points,x,y):sum=0.0forpointinpoints:dx=x-point[0]dy=y-point[1]sum+=math.sqrt(dx*dx+dy*dy)returnsumdeffindOptimumCost(L,points):a=L[0]b=L[1]c=L[2]# Find any point (x0, y0) lying on the line:# ax + by + c = 0x0=0.0y0=0.0ifb!=0:y0=-c/belse:x0=-c/a# (b, -a) is a direction vector parallel to the line.# Normalize it to get a unit direction vector.length=math.sqrt(a*a+b*b)dirX=b/lengthdirY=-a/length# We represent every point on the line as:## (x, y) = (x0 + t * dirX, y0 + t * dirY)## Find the range of t values corresponding to the# projections of all given points onto the line.low=1e18high=-1e18forpointinpoints:# Projection of (point - (x0, y0)) onto# the unit direction vector.t=(point[0]-x0)*dirX+(point[1]-y0)*dirYlow=min(low,t)high=max(high,t)# The sum-of-distances function is convex, so# Golden Section Search can be used to find its minimum.# Golden ratio value.phi=(math.sqrt(5.0)-1.0)/2.0eps=1e-7# Initial two points using the golden ratio.mid1=high-phi*(high-low)mid2=low+phi*(high-low)# Calculate the total distance at both points.cost1=getDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY)cost2=getDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY)whilehigh-low>eps:# If cost1 is smaller, the minimum lies# in the left part of the range.ifcost1<cost2:high=mid2# Reuse the previous point and its cost.mid2=mid1cost2=cost1# Calculate only one new point.mid1=high-phi*(high-low)cost1=getDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY)# Otherwise, the minimum lies in the# right part of the range.else:low=mid1# Reuse the previous point and its cost.mid1=mid2cost1=cost2# Calculate only one new point.mid2=low+phi*(high-low)cost2=getDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY)# Take the middle of the final range as the# approximate optimal value of t.t=(low+high)/2.0# Convert t back to the corresponding point on the line.x=x0+t*dirXy=y0+t*dirY# Return the minimum possible sum of distances.returngetDistanceSum(points,x,y)# Driver Codeif__name__=="__main__":L=[1,-1,-3]points=[[-3,-2],[-1,0],[-1,2],[1,2],[3,4]]ans=findOptimumCost(L,points)print(f"{ans:.2f}")
C#
usingSystem;classGFG{staticdoubleGetDistanceSum(int[,]points,doublex,doubley){doublesum=0.0;intn=points.GetLength(0);for(inti=0;i<n;i++){doubledx=x-points[i,0];doubledy=y-points[i,1];sum+=Math.Sqrt(dx*dx+dy*dy);}returnsum;}staticdoublefindOptimumCost(int[]L,int[,]points){doublea=L[0];doubleb=L[1];doublec=L[2];// Find any point (x0, y0) lying on the line:// ax + by + c = 0doublex0=0.0;doubley0=0.0;if(b!=0)y0=-c/b;elsex0=-c/a;// (b, -a) is a direction vector parallel to the// line. Normalize it to get a unit direction// vector.doublelen=Math.Sqrt(a*a+b*b);doubledirX=b/len;doubledirY=-a/len;// We represent every point on the line as://// (x, y) = (x0 + t * dirX, y0 + t * dirY)//// Find the range of t values corresponding to the// projections of all given points onto the line.doublelow=1e18;doublehigh=-1e18;intn=points.GetLength(0);for(inti=0;i<n;i++){// Projection of (point - (x0, y0)) onto// the unit direction vector.doubleproj=(points[i,0]-x0)*dirX+(points[i,1]-y0)*dirY;low=Math.Min(low,proj);high=Math.Max(high,proj);}// The sum-of-distances function is convex, so// Golden Section Search can be used to find its// minimum.// Golden ratio value.doublephi=(Math.Sqrt(5.0)-1.0)/2.0;doubleeps=1e-7;// Initial two points using the golden ratio.doublemid1=high-phi*(high-low);doublemid2=low+phi*(high-low);// Calculate the total distance at both points.doublecost1=GetDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY);doublecost2=GetDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY);while(high-low>eps){// If cost1 is smaller, the minimum lies// in the left part of the range.if(cost1<cost2){high=mid2;// Reuse the previous point and its cost.mid2=mid1;cost2=cost1;// Calculate only one new point.mid1=high-phi*(high-low);cost1=GetDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY);}// Otherwise, the minimum lies in the// right part of the range.else{low=mid1;// Reuse the previous point and its cost.mid1=mid2;cost1=cost2;// Calculate only one new point.mid2=low+phi*(high-low);cost2=GetDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY);}}// Take the middle of the final range as the// approximate optimal value of t.doublet=(low+high)/2.0;// Convert t back to the corresponding point on the// line.doublex=x0+t*dirX;doubley=y0+t*dirY;// Return the minimum possible sum of distances.returnGetDistanceSum(points,x,y);}publicstaticvoidMain(){int[]L={1,-1,-3};int[,]points={{-3,-2},{-1,0},{-1,2},{1,2},{3,4}};doubleans=findOptimumCost(L,points);Console.WriteLine(ans.ToString("F2"));}}
JavaScript
// Calculate the sum of Euclidean distances from (x, y)// to all the given points.functiongetDistanceSum(points,x,y){letsum=0.0;for(constpointofpoints){constdx=x-point[0];constdy=y-point[1];sum+=Math.sqrt(dx*dx+dy*dy);}returnsum;}functionfindOptimumCost(L,points){consta=L[0];constb=L[1];constc=L[2];// Find any point (x0, y0) lying on the line:// ax + by + c = 0letx0=0.0;lety0=0.0;if(b!==0)y0=-c/b;elsex0=-c/a;// (b, -a) is a direction vector parallel to the line.// Normalize it to get a unit direction vector.constlen=Math.sqrt(a*a+b*b);constdirX=b/len;constdirY=-a/len;// We represent every point on the line as://// (x, y) = (x0 + t * dirX, y0 + t * dirY)//// Find the range of t values corresponding to the// projections of all given points onto the line.letlow=1e18;lethigh=-1e18;for(constpointofpoints){// Projection of (point - (x0, y0)) onto// the unit direction vector.constt=(point[0]-x0)*dirX+(point[1]-y0)*dirY;low=Math.min(low,t);high=Math.max(high,t);}// The sum-of-distances function is convex, so// Golden Section Search can be used to find its// minimum.// Golden ratio value.constphi=(Math.sqrt(5.0)-1.0)/2.0;consteps=1e-7;// Initial two points using the golden ratio.letmid1=high-phi*(high-low);letmid2=low+phi*(high-low);// Calculate the total distance at both points.letcost1=getDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY);letcost2=getDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY);while(high-low>eps){// If cost1 is smaller, the minimum lies// in the left part of the range.if(cost1<cost2){high=mid2;// Reuse the previous point and its cost.mid2=mid1;cost2=cost1;// Calculate only one new point.mid1=high-phi*(high-low);cost1=getDistanceSum(points,x0+mid1*dirX,y0+mid1*dirY);}// Otherwise, the minimum lies in the// right part of the range.else{low=mid1;// Reuse the previous point and its cost.mid1=mid2;cost1=cost2;// Calculate only one new point.mid2=low+phi*(high-low);cost2=getDistanceSum(points,x0+mid2*dirX,y0+mid2*dirY);}}// Take the middle of the final range as the// approximate optimal value of t.constt=(low+high)/2.0;// Convert t back to the corresponding point on the// line.constx=x0+t*dirX;consty=y0+t*dirY;// Return the minimum possible sum of distances.returngetDistanceSum(points,x,y);}// Driver CodeconstL=[1,-1,-3];constpoints=[[-3,-2],[-1,0],[-1,2],[1,2],[3,4]];constans=findOptimumCost(L,points);console.log(ans.toFixed(2));