2016-08-16 2 views
2

그래프에서 연결된 모든 구성 요소를 트래버스해야합니다. 그래프의 경로가 이런 배열에 저장된다 : 여기각 배열에 포함 된 요소로 배열 배열 정렬

var paths = [ 
    [5,6], 
    [1,2], 
    [4,7,5,6], 
    [6] 
] 

내가 paths[2]=[4,7,5,6] 차례로 paths[3]=[6]로부터 의존 paths[0]=[5,6]로부터 의존 참조.

자, 내가 어떤 재귀 적으로 다른 하나에 포함되어 있는지 확인하기 위해 모든 경로를 순회 할 필요가 먼저 다른 해결하기 위해 도울 수있는, 즉 내가 어떤 배열이 다른 배열에 포함되어 있는지 확인해야합니다 :

예 :

process [6] 
process [5,6] 
process [4,7,5,6] 
process [1,2] 

인해 요소의 많은 양의, 내가 재귀를 사용하지 않으 것입니다. 다른 모든 배열에 포함 된 한 배열의 요소로이 배열 목록을 정렬하는 방법이 있습니까? 그래서 반복 할 때 처리 할 수 ​​있습니까?

편집 : 나는이로 구성된 각 경로에 가중치를 할당함으로써 해결 될 수 있다고 생각 다음 :이 노드가 다른 경로에 포함되는 횟수를 곱한 각 경로에 포함 된 노드의 합, 다음 경로를 정렬 길이 오름차순 및 체중 내림차순 -하지만 이것은 단지 내 추측입니다 ...

+0

'많은 양의 요소 때문에 재귀를 사용하지 않는 것이 좋습니다 .' 함수가 최대 스택 크기에 도달한다는 것이 염려되면 주위에 방법이 있습니다. 그것은 일종의 "자신 만의 TCO를 굴려 라."하지만 매우 효과적 일 수 있습니다. [여기는 좋은 기사입니다] (http://www.integralist.co.uk/posts/js-recursion.html).여하튼,'[5, 6]'은'[6]'을 포함하고 있다고 생각하는 것이 맞습니까? 본질적으로, 더 큰 배열들만 작은 배열을 포함 할 것이고, [5,6]는 _ [4,7,5,6]의 일부를 포함하지 않는다. – vlaz

+0

@ Vld : 나는 어제 당신이 언급 한 기사를 읽었으며, 나는 그것을 소화하는 길에 여전히 있음을 인정해야한다 ... 요점 : 그들은 또한 길이가 같을 수도 있고, 길이로 정렬하는 것도 첫 번째 시도였다. 슬프게도 더 복잡한 그래프에서 성공하지 못했습니다. – deblocker

+0

귀하의 경우 현명한 비교 작업을 쌍으로 만들지 않겠습니까? 'n '이 경로의 수인 경우''O (n * n)'시간이 걸릴 것입니다 (경로 길이가 어떤 최대 길이'k'보다 작다고 가정하십시오) –

답변

2

만약 내가 올바르게 이해하고, 당신은 의존성 정렬 후 있습니다. 그렇다면이 일을 성취 할 수있는 방법은 다음과 같습니다. 이것은 내가 생각해 낼 수있는 한 가지 방법이지만 간단한 해결책이있을 수도 있습니다.

우리는 서로 의존하는 연속 된 항목들의 그룹을 형성해야만합니다 (예 : [6], [5,6][4,7,5,6]). 그런 다음 종속성에 따라 정렬합니다. 항목이 서로 관련되지 않기 때문에 (예 : [1,2][6], [5,6][4,7,5,6]의 정렬 된 그룹 앞이나 뒤에 올 수 있기 때문에 별도의 그룹간에 정렬하는 것은 필요하지 않음)

var paths = [ 
 
      [5,6], 
 
      [1,2], 
 
      [4,7,5,6], 
 
      [6] 
 
      ], 
 
     lut = paths.reduce((table,path,i) => (path.forEach(n => table[n] = table[n] ? table[n].concat([[i,path.length]]) 
 
                          .sort((a,b) => a[1]-b[1]) 
 
                        : [[i,path.length]]), 
 
              table),{}), 
 
    sorted = Object.keys(lut).sort((a,b) => lut[b].length - lut[a].length) 
 
          .reduce((si,k) => (lut[k].forEach(e => !si.includes(e[0]) && si.push(e[0])),si) ,[]) 
 
          .map(idx => paths[idx]); 
 
console.log(sorted);

이 좋아 우리는 첫 번째 개체 (lut)를 같은 룩업 테이블에서이 특정한 경우에 그것은 그래서 우리는 지금 6가 그 경로를 알고

{ '1': [ [ 1, 2 ] ], 
    '2': [ [ 1, 2 ] ], 
    '4': [ [ 2, 4 ] ], 
    '5': [ [ 0, 2 ], [ 2, 4 ] ], 
    '6': [ [ 3, 1 ], [ 0, 2 ], [ 2, 4 ] ], 
    '7': [ [ 2, 4 ] ] 
} 

처럼 형성 가장 의존적 인 사람. '6': [ [ 3, 1 ], [ 0, 2 ], [ 2, 4 ] ],paths[3]에 있음을 의미합니다. paths[0]에는 단일 종속이 있고 paths[2]에는 3 명의 종속이 있습니다. 그래서 우리는 부양 가족 수 (.sort((a,b) => a[1]-b[1]))에 따라 분류했습니다. 일단 테이블을 만들면 원하는 인덱스 매핑을 제공하기 만하면됩니다. .reduce((si,k) => (lut[k].forEach(e => !si.includes(e[0]) && si.push(e[0])),si) ,[]) 라인이 조금 재미 있습니다. 그것이하는 일은 각 경로가 그것의 배열을 "if"배열로 밀어 넣는 것입니다. 그래서 우리는 가장 의존적 인 것부터 시작합니다 (6). 우리는 3, 0, 2를 밀었습니다. 그래서 5의 차례가 올 때 우리는 같은 인덱스를 다시 누르지 않을 것입니다.

+0

예! 문제가 뭔지 알 것 같아, 그게 사실이야? 이 주장에 대해 좀 더 많은 지식을 공유 할 수 있다면 매우 유용 할 것입니다. '7': 4는 어떻게 생겼어? 이것은 너무 진보 된 코드의 도움을 받아서도 실현할 수없는 요점입니다. – deblocker

+0

@deblocker 어제이 스 니펫을 게시 한 후 일부 불능이 있음을 깨닫고이를 수정하려고했습니다. 나중에 나는 더 효율적인 것을 게시하려고 노력할 것이다. – Redu