您的位置:首页 > 其它

区间图着色问题

2010-03-11 19:23 459 查看
一、题目

我们可以做出一个区间图,其顶点为已知的活动,其边连接着不兼容的活动。为了使两个不兼容的节点颜色不同,所需的最少颜色数是多少?

二、用贪心算法解决这个问题需要几个步骤。

1、证明问题的最优子结构性质。

如果有一个方案使用了最少的颜色(不包括最后一个颜色),那么去除这个颜色所包含的活动,剩余部分对应的颜色方案也一定使用了最少的颜色。如果不是,那么可以用新的使用更少颜色的方案来替代原方案,则在原问题上产生一个新的最少颜色数的方案,这样的结果和原来的假设矛盾。

同时也可以证明:

如果一个方案使用了最少的颜色(不包括最后一个颜色),那么在其一个颜色所包含的兼容子集中,必定包含使用最多集合的一个方案

证明:

如果集合C是一个使用最多集合的方案,并且它不在最少颜色的方案P中,那么方案就包括了一个比C小的集合B.假设E=C-B 那么可以P-B的集合中在减掉E并且 这个集合也具有最少的颜色数.所以假设成立.

2、设计一个递归解。

这里不知道怎么分析,请高手指教

3、贪心解

从1的分析可知,这个问题就是每次从集合中取出一个最大兼容的集合,所以就可以采用活动先择的方案解决这个问题。

三、活动选择的递归实现

//递归活动选择的贪心解
void activitySelector(list<int>* s, list<int>* f)
{
int sp;
if (s->empty())
{
return;
} else
{
// 取出新集合的上限
sp = *(f->begin());

cout<<*(s->begin())<<" - "<<*(f->begin())<<endl;
// 删除选中元素(贪心算法)
s->erase(s->begin());
f->erase(f->begin());
}

int dis = 0;
list<int>::iterator sit = s->begin();
list<int>::iterator fit = f->begin();

for (; sit != s->end(); )
{
if (*sit < sp)
{
// 删除元素
s->erase(sit);
f->erase(fit);

// 重新定位指针
sit = s->begin();
fit = f->begin();
for (int i = 1; i < dis; i++)
{
sit++;
fit++;
}
} else
{
dis++;
sit++;
fit++;
}
}

if (s->size() > 0)
{
activitySelector(s, f);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: