假设一条线段有 25 个点,这些点可能分布不均(空间上),如下图所示:
我的问题是我们如何在这 25 个点中选择 10 个点,使这 10 个点在空间上尽可能均匀分布。在idea的情况下,选择的点应该是这样的:
编辑: 确实,如果我能说出证明“均匀分布”的标准,这个问题会变得更加优雅。我所知道的是我对选定点的期望:如果我将线段分成 10 个相等的线段。我希望每个小线段上应该有一个点。当然也有可能在一些小的线段中找不到代表点。在这种情况下,我将求助于具有代表点的相邻小线段。下一步我将把选中的相邻段进一步分成两部分:如果每一部分都有代表点,那么空代表点问题就解决了。如果我们无法在其中一个小线段中找到代表点,我们可以将其进一步划分为更小的部分。或者我们可以求助于下一个相邻的线段。
编辑: 使用动态编程,一个可能的解决方案实现如下:
#include <iostream>
#include <vector>
using namespace std;
struct Note
{
int previous_node;
double cost;
};
typedef struct Note Note;
int main()
{
double dis[25] =
{0.0344460805029088, 0.118997681558377, 0.162611735194631,
0.186872604554379, 0.223811939491137, 0.276025076998578,
0.317099480060861, 0.340385726666133, 0.381558457093008,
0.438744359656398, 0.445586200710900, 0.489764395788231,
0.498364051982143, 0.585267750979777, 0.646313010111265,
0.655098003973841, 0.679702676853675, 0.694828622975817,
0.709364830858073, 0.754686681982361, 0.765516788149002,
0.795199901137063, 0.823457828327293, 0.950222048838355, 0.959743958516081};
Note solutions[25];
for(int i=0; i<25; i++)
{
solutions[i].cost = 1000000;
}
solutions[0].cost = 0;
solutions[0].previous_node = 0;
for(int i=0; i<25; i++)
{
for(int j= i-1; j>=0; j--)
{
double tempcost = solutions[j].cost + std::abs(dis[i]-dis[j]-0.1);
if (tempcost<solutions[i].cost)
{
solutions[i].previous_node = j;
solutions[i].cost = tempcost;
}
}
}
vector<int> selected_points_index;
int i= 24;
selected_points_index.push_back(i);
while (solutions[i].previous_node != 0)
{
i = solutions[i].previous_node;
selected_points_index.push_back(i);
}
selected_points_index.push_back(0);
std::reverse(selected_points_index.begin(),selected_points_index.end());
for(int i=0; i<selected_points_index.size(); i++)
cout<<selected_points_index[i]<<endl;
return 0;
}
结果如下图所示,其中选中的点用绿色表示: