최소 이동 횟수와 숫자를 일치시키는 알고리즘


11

이것은 일종의 편집 거리 질문이며 매우 쉽습니다. 나는이 주제에 대해 아주 두뇌 죽었고 지금까지 이해할 수 없습니다.


일련의 숫자가 주어진다면

[3, 1, 1, 1]

최소한의 "이동"을 사용하여 모든 숫자를 어떻게 같은 숫자로 가장 효율적으로 바꿀 수 있습니까? "이동"이란 숫자에서 하나를 추가하거나 제거하는 것을 의미합니다.

위의 예에서 가장 효율적인 이동은 다음과 같습니다.

[1, 1, 1, 1]

이를 위해서는 2 번의 이동이 필요하며 첫 번째 숫자는 두 번 줄어 듭니다.

더 큰 수백 개의 숫자가 주어지면 이것을 찾는 가장 좋은 방법을 알 수 없습니다.

원래 반올림 된 평균 수 (모두 합계를 길이로 나눈 값)를 계산 한 다음 계산 된 평균으로 줄이려고 시도했지만 위의 예에서는 2 개 대신 4 개의 이동이 필요했습니다.

나는 내가 이해할 수 있다고 생각한다.

  1. 평균,
  2. 모드
  3. 중앙값

최소 거리를 선택하여 각각의 거리를 편집하십시오. 그러나 이것이 모든 단일 인스턴스에서 올바른지 확실하지 않습니다. 어떻게 알 수 있습니까?


도메인이 제한되어 있으면 최소에서 최대까지 모든 가능성을 시도 할 수 있습니다. 그렇지 않으면 모드 또는 중앙값을 사용하려고 할 수 있습니다.
Bartosz Przybylski

감사합니다 @Bartek. 수백 또는 수천 개의 숫자를 처리하는 경우 모든 가능성을 시도하는 것이 매우 비효율적입니다. 모드 / 중앙값을 확인하겠습니다. 그러나 이것들은 모든 경우에 결과를 만들어내는 것이 확실합니까? 그게 내 주요 질문입니다. 확실하고 효율적인 알고리즘을 찾고 있습니다.
dthree

숫자가 숫자 세트에 있어야합니까, 아니면 정수일 수 있습니까?
TCSGrad

@TCSGrad 임의의 정수일 수 있지만 분명히 최소 숫자와 최대 숫자 사이에있는 것을 선택하려고합니다. 이 경우 1, 2 또는 3입니다.
dthree

답변:


10

답은 중간 값을 취하는 것입니다. 중앙값의 특성 중 하나는 각 요소까지 의 L1 거리최소화 한다는 것 입니다. (Wikipedia 기사를 이해하려면 확률 분포를 원래 일련의 숫자에 대한 균일 분포로 간주하십시오).

이것은 문제를 해결하는 알고리즘입니다 (원래 dc2에 의해 작성 ).

function median(arr) {
  arr.sort(function(a, b) { return a - b; });
  var half = floor(arr.length/2);
  if ( arr.length % 2 ) {
    return arr[half];
  } else {
    return (arr[half-1] + arr[half]) / 2.0;
  }
}

function minl1(arr) {
  var moves = 0;
  var mdn = median(arr);
  for ( var i = 0; i < arr.length; ++i ) {
    moves += Math.abs(mdn - arr[i]);
  }
  return moves;
}

minl1([3, 1, 1, 1]); // -> 2

그래, 그랬어 재밌는 방법. 중앙값이하는 것처럼 보이지 않지만 이봐. 고마워
dthree

1
증거에 대한 내 대답을 참조하십시오.
Yuval Filmus

@ dc2 : "시도"하여 "확인"할 수 없습니다.
Raphael

1
참고 사항 : 중앙값 O (n) 시간을 계산할 수 있습니다
Bartosz Przybylski

1
@Raphael OP에 대한 언급없이 OP의 코드를 다른 답변에 포함해도됩니까?
thefourtheye

10

TCSGrad가 언급했듯이 정수 , 당신은 정수를 찾고 m 최소화 δ를 ( m ) = N Σ= 1 | m - x i | . δ ( m + 1 ) δ ( m ) 를 계산하는 것이 좋습니다 : δ ( m + 1 ) δ ( m ) =n i = 1 { + 1 m x i엑스1,,엑스미디엄

δ(미디엄)=나는=1|미디엄엑스나는|.
δ(미디엄+1)δ(미디엄) 마찬가지로m이로 진행-+, 수량δ(m+1)-δ(m)
δ(미디엄+1)δ(미디엄)=나는=1{+1미디엄엑스나는1미디엄<엑스나는=#{나는:미디엄엑스나는}#{나는:미디엄<엑스나는}.
미디엄+δ(미디엄+1)δ(미디엄)에서 간다 N . 또한 x 1 , , x n 지점에서만 값을 전환합니다 . 그것의 최적 값을 확인하는 것은 어렵지 않다 m이 되는 최소 포인트이다 δ ( m + 1 ) - δ ( m ) 0 . 이 최소 점은 x i 중 하나 이므로 편집 거리는 min ( δ ( x 1 ) , , δ ( x엑스1,,엑스미디엄δ(미디엄+1)δ(미디엄)0엑스나는 .(δ(엑스1),,δ(엑스))

엑스나는미디엄엑스나는δ(미디엄+1)δ(미디엄)=1δ(미디엄)δ(미디엄1)=1미디엄엑스나는δ엑스나는


당신은 그것을 놓쳤을 수도 있지만,이 답변 (거의) 중앙값이 최적의 선택 임을 증명 합니다.
Yuval Filmus

1
당신의 대답은 우수했고 나는 그것을 찬성했다. 불행히도, 나는 과학적 표기법에 정통하지 않아서 너무 훌륭하여 대부분의 것을 깨뜨릴 수 있습니다. 그건 당신의 문제가 아니라 내 문제입니다.
dthree

5

문제는 LP 문제로 공식화 될 수 있습니다.

[1,2...]

|나는엑스|

엑스

엑스엑스

편집 : 의견에서 지적했듯이 목적 함수는 절대 차이에 대한 합이어야합니다. 표준 LP로 다시 변환하기 위해 LP를 다음과 같이 다시 작성할 수 있습니다.

나는'

대상 :

나는'나는엑스 나는
나는'나는엑스 나는
나는',엑스'0 나는

나는'=|나는엑스| 나는엑스


예를 들어 이것을 올바르게 이해하면 x는 1-3이되고 편집 거리는 1, 2 및 3을 찾은 다음 그에 대해 분을 수행합니까?
dthree

엑스엑스

제약이 필요한 이유는 무엇입니까?
Raphael
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.