Попытка "пересечь" два массива, используя подмножество первого массива и поддерживая порядок второго массива, где это возможно - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь сгенерировать новый дочерний массив из двух родительских массивов (кроссовер), используя следующий процесс.

parentArr1 = [0,1,2,3,4,5,6,7,8,9]
parentArr2 = [9,8,7,6,5,4,3,2,1,0]
parent1Subset = [2,3,4,5]
childArr   = [9,8,2,3,4,5,7,6,1,0]

Правила кроссовера, которые я определяю:

  1. Извлеките непрерывное подмножество из parentArr1 и вставьте его в новый childArr в той же позиции, из которой он был извлечен.
  2. Заполните оставшиеся позиции в childArr элементами из parentArr2 и сохранитепорядок элементов в parentArr2 вокруг подмножества.
  3. Не должно быть дубликатов.

Вот еще один пример:

parentArr1 = [0,1,2,3,4,5,6,7,8,9]
parentArr2 = [9,8,7,6,5,4,3,2,1,0]
parent1Subset = [7,8,9]
childArr   = [6,5,4,3,2,1,0,7,8,9]

Я имелмногочисленные неудачные попытки сделать это.Вот попытка, которая пришла ближе всего.

const parentArr1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const parentArr2 = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
let parent1Subset = [2, 3, 4, 5];
let childArr = crossOver(parentArr1, parentArr2, parent1Subset);
// Expected ouput: 9, 8, 2, 3, 4, 5, 7, 6, 1, 0

function crossOver(pArr1, pArr2, pArr1Subset) {
    let _childArr = pArr1Subset.slice(); // suggestion from @r3wt
    for (let i = 0; i < pArr1.length; i++) {
        for (let j = 0; j < (pArr1.length - _childArr.length); j++) {
            if (!_childArr.includes(pArr2[i])) {
                _childArr.splice(i, 0, pArr2[i]);
            }
        }
    }
    return _childArr;
}
console.log("childArr: " + childArr);
// childArr: 9, 8, 7, 6, 2, 3, 4, 5, 1, 0

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Надеюсь, это должно быть достаточно просто, чтобы следовать:

    const parentArr1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    const parentArr2 = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
    let parent1Subset = [2, 3, 4, 5];
    
    // First get the start index
    const startIndex = parentArr1.indexOf(parent1Subset[0]);
    
    // Get the start of the childArr
    const childArr = parentArr2.filter(n => parent1Subset.indexOf(n) < 0);
    
    // Splice in the subset
    childArr.splice(startIndex, 0, ...parent1Subset);
    
    console.log(childArr); // [9, 8, 2, 3, 4, 5, 7, 6, 1, 0]
0 голосов
/ 26 октября 2018

Вы можете использовать другой индексатор для массива 2 и проверить, находится ли фактическое значение в массиве пересечения.

function crossover(p1, p2, sub) {
    var j = 0;
    return p1.map(i => {
        if (sub.includes(i)) {
            return i;
        }
        while (sub.includes(p2[j])) ++j;
        return p2[j++];
    });
}

console.log(crossover([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], [2, 3, 4, 5]).join(' '));
console.log(crossover([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [9, 8, 7, 6, 5, 4, 3, 2, 1, 0], [7, 8, 9]).join(' '));
...