现在的位置: 首页 > 综合 > 正文

庞果英雄会——建立信号基站

2013年08月12日 ⁄ 综合 ⁄ 共 3349字 ⁄ 字号 评论关闭

庞果英雄会——建立信号基站

一、题目分析

分析题目可知,所求解是一个二维空间中的某点。可以参照一维空间中的三分法查找找到最优值。

如下图:最优点一下位于谷底处:

仿照三分法,在空间中找到四个点,依次为0,1,2,3:

计算这个四点的距离值,找出最大值和最小值:

假设红色点是最小值点,绿色为最大值点,可以推断最优点一定在红色点附近,那么就可以将搜索空间缩小,即按黑色箭头指示方向缩小空间,然后重复此过程,直到满足精度要求。

在搜索空间过程中要注意到如果最小值点与最大值点挨着的情况下,按上面的过程缩小空间可能会将最优点去除(第一次就是没有考虑这种情况失败了,修改后通过~_~),所以要判断最小值点与最大值点关系,然后选择缩小空间的方向,如图:

只能向一个方向缩小空间。

二、通过代码

#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

#ifdef WIN32
typedef __int64 ll;
#else
typedef long long ll;
#endif

double max(double x, double y)
{
	return x > y ? x : y;
}

double cal(double px, double py, int n, const int *x, const int *y)
{
	double res = 0;

	for(int i = 0; i < n; ++i)
	{
		res += max(fabs(px - x[i]), fabs(py - y[i]));
	}

	return res;
}

int cmp(double *smallest, int *code, double *distance)
{
	int index = 0;
	*smallest = distance[0];
	*code = 0;
	for(int i = 1; i < 4; ++i)
	{
		if(distance[index] < distance[i])
		{
			index = i;
		}
		if(*smallest > distance[i])
		{
			*smallest = distance[i];
			*code = i;
		}
	}

	return index;
}

bool isFinish(double *distance)
{
	bool res = false;

	double sum = 0;
	double delta = 0;
	for(int i = 0; i < 4; ++i)
	{
		sum += distance[i];
	}
	sum /= 4;

	for(int i = 0; i < 4; ++i)
	{
		delta += fabs(sum - distance[i]);
	}

	if(delta / 4 < 1e-4)
	{
		res = true;
	}

	return res;
}

double bestDistance(int n, const int *x,const int *y) 
{
	double xl_down, yl_down;
	double xl_up, yl_up;
	double xr_down, yr_down;
	double xr_up, yr_up;
	double res = 1000000000000000000;
	double cur = 1000000000;

	double xtmp[4];
	double ytmp[4];

	xl_down = -1000000000;
	yl_down = -1000000000;

	xl_up = -1000000000;
	yl_up = 1000000000;

	xr_down = 1000000000;
	yr_down = -1000000000;

	xr_up = 1000000000;
	yr_up = 1000000000;

	double distance[4];
	while(1)
	{
		//上左
		xtmp[0] = xl_up + (xr_up - xl_up) / 3;
		ytmp[0] = yl_up - (yl_up - yl_down) / 3;

		distance[0] = cal(xtmp[0], ytmp[0], n, x, y);

		//上右
		xtmp[1] = xr_up - (xr_up - xl_up) / 3;
		ytmp[1] = yl_up - (yl_up - yl_down) / 3;

		distance[1] = cal(xtmp[1], ytmp[1], n, x, y);

		//下左
		xtmp[2] = xl_down + (xr_down - xl_down) / 3;
		ytmp[2] = yl_down + (yl_up - yl_down) / 3;

		distance[2] = cal(xtmp[2], ytmp[2], n, x, y);

		//下右
		xtmp[3] = xr_down - (xr_down - xl_down) / 3;
		ytmp[3] = yr_down + (yr_up - yr_down) / 3;

		distance[3] = cal(xtmp[3], ytmp[3], n, x, y);

		int s_index;
		int index = cmp(&cur, &s_index, distance);

		if(cur < res)//更新最新的值
		{
			res = cur;
		}

		if(isFinish(distance))//是否达到精度要求
		{
			break;
		}
		switch(index)
		{
		case 0://上左
			if(s_index == 1)
			{
				xl_up = xtmp[0];
				xl_down = xtmp[0];
			}
			else if(s_index == 2)
			{
				yl_up = ytmp[0];
				yr_up = ytmp[0];
			}
			else
			{
				xl_up = xtmp[0];
				yl_up = ytmp[0];

				xl_down = xtmp[0]; 
				yr_up = ytmp[0];
			}
			break;
		case 1://上右
			if(s_index == 0)
			{
				xr_up = xtmp[1];
				xr_down = xtmp[1];
			}
			else if(s_index == 3)
			{
				yr_up = ytmp[1];
				yl_up = ytmp[1];
			}
			else
			{
				xr_up = xtmp[1];
				yr_up = ytmp[1];

				xr_down = xtmp[1];
				yl_up = ytmp[1];
			}
			break;
		case 2://下左
			if(s_index == 0)
			{
				yl_down = ytmp[2];
				yr_down = ytmp[2];
			}
			else if(s_index == 3)
			{
				xl_down = xtmp[2];
				xl_up = xtmp[2];
			}
			else
			{
				xl_down = xtmp[2];
				yl_down = ytmp[2];

				xl_up = xtmp[2];
				yr_down = ytmp[2];
			}
			break;
		case 3://下右
			if(s_index == 1)
			{
				yr_down = ytmp[3];
				yl_down = ytmp[3];
			}
			else if(s_index == 2)
			{
				xr_down = xtmp[3];
				xr_up = xtmp[3];
			}
			else
			{
				xr_down = xtmp[3];
				yr_down = ytmp[3];

				xr_up = xtmp[3];
				yl_down = ytmp[3];
			}
			break;
		default:
			printf("error\n");
		}
	}

	return res;
}


int main()
{
	double res;
	//int n = 4;
 //   int x[] = {1, 2, 0, 1};
 //   int y[] = {4, 3, 1, 1};
	int n = 19; 
	int x[] = {858442934,-161749718,-55910439,347569202,-660170269,-982075453,-860790164,947179323,312298821,-285196111,967545126,-777105315,-630974471,-713895350,745616673,840630174,-597730146,-205693089,24677872};
	int y[] = {449535070,160026431,705809990,121634879,648304545,-392329548,-447666131,-829918127,926665890,943182185,601133076,-848803337,89719473,-586785144,832132969,-111884761,-556530757,65860874,978639057};
	res = bestDistance(n, x, y);
	printf("%f\n", res);
	return 0;
}

抱歉!评论已关闭.