我应该如何使用Javascript解决这种组合场景
How should I solve this combinations scenario with Javascript?
对于一个最少有8支球队、最多有18支球队的锦标赛,我必须确定比赛日历。锦标赛有17轮或比赛日。因此,每支球队在每个比赛日都必须遇到另一支球队。如果少于18支球队,可以重复遭遇,这样一支球队可以与另一支球队进行多次比赛。
这是一个18队锦标赛的例子。这将是不到18支球队的比赛,尤其是9支球队。
所以,我要做排列,然后把它们排列成不同的圆形。我试过:
组合:
function k_combinations(set, k) {
var i, j, combs, head, tailcombs;
if (k > set.length || k <= 0) {
return [];
}
if (k == set.length) {
return [set];
}
if (k == 1) {
combs = [];
for (i = 0; i < set.length; i++) {
combs.push([set[i]]);
}
return combs;
}
combs = [];
for (i = 0; i < set.length - k + 1; i++) {
head = set.slice(i, i+1);
tailcombs = k_combinations(set.slice(i + 1), k - 1);
for (j = 0; j < tailcombs.length; j++) {
combs.push(head.concat(tailcombs[j]));
}
}
return combs;
}
var teams = [ {name: 'Real Madrid'},
{name: 'Las Palmas'},
{name: 'Alavés'},
{name: 'Valencia'},
{name: 'Sevilla'},
{name: 'Betis'},
{name: 'Córdoba'},
{name: 'Deportivo'},
{name: 'Atlético de Madrid'},
{name: 'Levante'},
{name: 'Rayo Vallecano'},
{name: 'Athletic Bilbao'},
{name: 'Osasuna'},
{name: 'Zaragoza'},
{name: 'Villareal'},
{name: 'Racing de Santander'},
{name: 'Espanyol'},
{name: 'Cádiz'},
];
// Compute whole encounters combinations.
var seasonMatches = k_combinations(teams,2);
组合的轮次排列:
var calendar = {};
for (var i = 0; i<17; i++) {
calendar[i+1] = [];
}
var encounters = seasonMatches;
for (var i = 0; i<Object.keys(calendar).length; i++) {
encounters.map(function (match,index) {
if (! _.any(calendar, function (m) {
return m[0].name === match[0].name || m[1].name === match[1].name || m[0].name === match[1].name || m[1].name === match[0].name;
})) {
calendar[i+1].push(match);
}
});
}
我使用lodash来简化上一轮中任何遭遇的存在性检查。
我遇到的问题是,这样我在日历上的每一轮都会遇到同样的遭遇。而且,如果我在季节匹配中添加一个拼接,我会在每轮比赛中添加不同的匹配。
我已经掌握了上面展示的这个例子。我应该如何解决这个问题?
看起来你喜欢努力工作:)有一种更简单的方法(jsbin链接):
var teamsCount = 9;
var matchDays = 17;
var matches = [];
var teams = _.shuffle(_.range(teamsCount));
while(matches.length < matchDays){
var newMatches = _(teams).chunk(2).partition(function(match){
return match.length === 2;
}).value();
matches = matches.concat(newMatches[0]);
if(newMatches[1].length) { // one team was left out, let's make sure it is playing
// we put it first, and add the other teams, shuffled, without that one team
teams = newMatches[1][0].concat(_.shuffle(_.without(_.range(teamsCount), newMatches[1][0][0])));
} else {
teams = _.shuffle(_.range(teamsCount));
}
}
// we might get more then we need
matches = _.take(matches, matchDays);
_.each(matches, function(match, index){
console.log('round ' + index + ': ' + match);
});
说明:由于你没有施加任何其他限制(例如,每支球队都必须相互比赛),所以带着球队,洗牌,一次两次就足够了(=一场比赛)。然后,我们将区块划分为真实的比赛(2个团队阵列)和剩余的比赛(1个团队数组)。
我们将真正的匹配项添加到现有的匹配项中。如果我们有剩余的球队,我们会保留它,并将被打乱的球队(没有剩余的球队)连接起来,然后再次将其分组。我们继续比赛,直到我们有足够的比赛。由于我们可能会得到更多的比赛,所以我们只参加前17场比赛。
JSbin更为复杂,并将比赛转换为球队名称。
我试着查看你的代码,看看你为什么会得到你显示的模式,但它太复杂了,我无法理解,我喜欢用简单的方式做事;-)
相关文章:
- 根据id将json数组组合为一个json数组
- 接受不在列表中的值-引导组合框
- 如何解决Yii中的页面刷新问题
- 测试Angular Service解决错误回调中的promise
- 从客户端获取修改后的对象,并将其与服务器上的原始对象组合
- 组合两个javascript函数
- Telerik rad组合框多列数据绑定
- 组合 2 个 JavaScript .scroll 函数
- 如何解决Access Control Allow Origin错误
- 如何使用jquery组合两个数组
- onChange不足以从Dojo组合框触发查询
- 如何解决这种情况下的非法调用类型错误
- 简单的ES6承诺问题-交换解决和拒绝参数
- Web 解决方案中带有复选框和筛选器的组合框
- DurandalJs:一种通用解决方案,用于将焦点放在组合视图上的第一个输入元素上
- 组合是解决这个难题的办法吗
- 数组组合以解决遍历问题
- JavaScript组合和压缩插件/解决方案
- 如何解决ExtJS 4.1组合框pageSize的bug
- 我应该如何使用Javascript解决这种组合场景