给大家出一道题,在DataTable中存储了这样一张表:
数组序号 数组值
1 1,2,3,4,6,10,12
2 1,4,5
3 3,4,5,6,7,11现在要从1,2,3数组中随机抽取不重复的数值,要求每个数组中抽取3个,要确保尽可能每个数组中都能抽取到3个,且所有抽取出的数值不重复,并且抽取到的数值个数尽可能的多,请大家设计算法。这个是示例数据,题目本意是,在每个数组中任意存储了一堆不重复的数值,然后从每个数组中随机抽取不重复的数值,每个数组抽取N个,要尽可能每个数组中都能抽取到N个,且所有抽取出的数值不重复,而且要求抽取出的数值个数尽可能的多。(要考虑到的问题是:1.有些数组中存储的数值个数可能小于等于N;2.不同的数组存储的数值可能有重复)转自其他论坛,看到挺有趣,拿来共享一下,大家一起出谋划策。
数组序号 数组值
1 1,2,3,4,6,10,12
2 1,4,5
3 3,4,5,6,7,11现在要从1,2,3数组中随机抽取不重复的数值,要求每个数组中抽取3个,要确保尽可能每个数组中都能抽取到3个,且所有抽取出的数值不重复,并且抽取到的数值个数尽可能的多,请大家设计算法。这个是示例数据,题目本意是,在每个数组中任意存储了一堆不重复的数值,然后从每个数组中随机抽取不重复的数值,每个数组抽取N个,要尽可能每个数组中都能抽取到N个,且所有抽取出的数值不重复,而且要求抽取出的数值个数尽可能的多。(要考虑到的问题是:1.有些数组中存储的数值个数可能小于等于N;2.不同的数组存储的数值可能有重复)转自其他论坛,看到挺有趣,拿来共享一下,大家一起出谋划策。
int m = 3;//每组尽可能抽 m 个 List<List<int>> list = new List<List<int>>();
// ... 初始化数据 List<int> result = new List<int>();
Random rand = new Random(); for (int i = 0; i < list.Count; i++)
{
int count = 0;
while (count < m)
{
int value = list[i][rand.Next(list[i].Count)];
if (!result.Contains(value))
{
result.Add(value);
count++;
} list[i].Remove(value);//移除,下次随机抽就不会抽到
}
}
int m = 3;//每组尽可能抽 m 个 List<List<int>> list = new List<List<int>>();
// ... 初始化数据 List<int> result = new List<int>();
Random rand = new Random(); for (int i = 0; i < list.Count; i++)
{
int count = 0;
while (count < m)
{
int value = list[i][rand.Next(list[i].Count)];
if (!result.Contains(value))
{
result.Add(value);
count++;
} list[i].Remove(value);//移除,下次随机抽就不会抽到 if (list[i].Count == 0)
break;
}
}
为了尽量保证每个数组都能抽取N个,需要从元素最少的数组开始。
算法:
声明一个新的空间 aList 用于存放结果。
Start:;
对这些数组进行排序,排序标准是数组的长度,也就是数组中元素的个数。
从元素最少的数组开始。
到当前数组;
如果元素的数量少于N,则全部提取。否则随机选择N个数。将结果放到 aList 中未使用的空间;
在剩下的所有数组中执行下列算法:如果某个元素已存在于 aList 当中,则将它从当前数组删除。
如果已完成所有数组的运算,
则 goto Trim;
否则 goto Start;
Trim:;
将aList 中未使用的空间加以清除
数组1有7条容量为1的边,分别流向元素1,2,3,4,6,10,12,
数组2有3条容量为1的边,分别流向元素1,4,5
数组3有6条容量为1的边,分别流向元素3,4,5,6,7,11元素1,2,3,4,5,6,7,10,11,12个有一条容量为1的边流向共同的汇T,最多可选择的元素个数,就是源S => 汇T的最大流。LZ可以想象成一股水流,从S流到T,最大的流量是多少,就能够选取多少个元素。最普通的解法就是先用贪心,确定一个匹配方案,然后不断的在残流中,寻找增广路径,直到找不到新的增广路径,就表明已经是最大流了。(无法再压入更多的流量,就表明已经饱和了),程序就不写了,大概是这个意思。