변장 순열


17

주어진 n 차원 벡터 v 실제 항목으로, 가장 가까운 치환 찾을 p(1,2,...,n) 받는 대하여 l1 -distance.

세부

  • 더 편리 경우의 순열 사용할 수 있습니다 (0,1,...,n1) 대신. 가장 가까운 순열이 여러 개인 경우 하나 또는 다른 방법으로 모두를 출력 할 수 있습니다.
  • 두 벡터 사이 의 l1 거리 u,v
    d(u,v)=i|uivi|.
  • 원하는 경우 입력이 정수로만 구성된다고 가정 할 수 있습니다.

[0.5  1] -> [1 2], [2 1]
c*[1 1 ... 1] -> any permutation
[1 4 2 6 2] -> [1 4 3 5 2], [1 4 2 5 3]
[1 3 5 4 1] -> [2 3 5 4 1], [1 3 5 4 2]
[7 7 3 2 5 6 4 2] -> [8 7 3 2 5 6 4 1], [8 7 3 1 5 6 4 2], [7 8 3 2 5 6 4 1], [7 8 3 1 5 6 4 2]
[-2 4 5 7 -1 9 3] -> [1 4 5 6 2 7 3], [2 4 5 6 1 7 3], [1 4 5 7 2 6 3], [2 4 5 7 1 6 3]
[0 4 2 10 -1 10 5] -> [1 4 2 6 3 7 5], [1 4 3 6 2 7 5], [2 4 3 6 1 7 5], [3 4 2 6 1 7 5], [1 4 2 7 3 6 5], [1 4 3 7 2 6 5], [2 4 3 7 1 6 5], [3 4 2 7 1 6 5]

더 많은 예제를 생성하기위한 Octave 스크립트 .


의 모든 요소 v가보다 큼을 보증 0합니까? 아니면 적어도 그렇지 0않습니까?
얽히고 설킨

1
아니요, 항목은 v정수일 수 있습니다. (몇 가지 예를 더 추가했습니다.)
flawr

그것들이 실수 일 수 있다면 [1.6 2]중요한 테스트 사례입니다 (욕심 많은 알고리즘 / 사전 정렬은 잘못된 대답을 제공합니다).
histocrat

2
변장에 중복? 그러나 그것이 동일한 작업인지 (현재 xnor에 의해 입증 된) 확실하지 않기 때문에 그것이 닫혀 있어야한다는 것을 확신하지 못합니다.
Arnauld

1
(사실, 그것은 동일한 작업이 아니지만 연결된 도전의 모든 솔루션은 이것의 해결책입니다.)
Arnauld

답변:


13

파이썬 2 , 60 바이트

def f(l):z=zip(l,range(len(l)));print map(sorted(z).index,z)

온라인으로 사용해보십시오!

제로 인덱싱을 사용합니다.

간단한 아이디어를 가진 빠른 알고리즘. 우리가 대신 입력리스트의 순서를 무작위로 바꾸어 넣해야하는 경우에 가까운 그것을 만들기 위해 (1,2,...,) 아래의 입증 가능한 한, 우리는 그저 그것을해야한다. 우리가 대신 치환하는 것 이후 (1,2,...,) , 우리의 내 문제처럼, 입력 목록과 같은 방법을 지시하는 순열을 선택순서화를 모방(반복이있을 수 있습니다 입력 제외). (편집 : 마일은Dennis가동일한 대답을하는이 동일한과제를지적했습니다.)

제 : 리스트의 순열 까지의 거리를 최소화한다 (1,2,...,) 이고 정렬.

증명 : 다른 순열 고려 ' 의를 . 우리는이보다 더 좋을 수 없다 증명 할게요 분류.

두 지수 픽업 나는,제이 있는지 ' 즉, 아웃 - 오브 - 오더 갖는 경우 나는<제이 하지만 나는'>제이' . 우리는 그들을 교환하는 것은까지의 거리 증가 할 수 있음을 보여 (1,2,...,) . swap은이 두 요소의 기여를 다음과 같이 변경합니다.

|나는'나는|+|제이'제이||나는'제이|+|제이'나는|.

이것이 증가 할 수 없다는 것을 보여주는 깔끔한 방법이 있습니다. 여러 줄에 걸어 두 사람에서 진행 한 고려 나는'나는 과에서 다른 제이' 에게 제이 . 그들이 걷는 총 거리는 왼쪽의 표현입니다. 이후 나는<제이 하지만 나는'>제이' , 그들이 그들의 각층 동안 일부 지점에서 교차 호출해야 수단 수직선에 높은 사람 전환 . 그러나 그들이 p에 도달하면그런 다음 목적지를 바꾸고 동일한 총 거리를 걸을 수있었습니다. 그런 다음 를 웨이 포인트로 사용하는 대신 처음부터 교체 대상으로 걸어가는 것이 더 나빠질 수는 없습니다 . 이는 오른쪽의 총 거리를 제공합니다.

따라서, 두 개의 비 순차 요소들을 정렬 ' 로 그 거리를 수 (1,2,...,) 보다 작거나 동일. 이 과정을 반복하면 결국 이 정렬됩니다 . 그래서, 정렬 적어도 좋은으로 ' 의 선택을위한 ' 하는 수단을 최적으로 또는 최적의 공동.

참고의 전용 속성 (1,2,...,) 우리가 같은 알고리즘은 어떤 고정 된 목록의 거리를 최소화하기 위해 주어진리스트의 순서를 무작위로 바꾸어 넣 위해 일하는 것이 그래서, 분류 점이다 사용했다고.

코드에서 유일한 목적은 z=zip(l,range(len(l)))입력 요소를 구별, 즉 관계를 피하면서 동일하지 않은 요소를 동일하게 비교하는 것입니다. 반복이 없다고 보장 된 입력을 제거하면이 입력을 제거하고 가질 수 있습니다 lambda l:map(sorted(l).index,l).


훌륭한 통찰력
요나

주문 을 찾기 위해 이것을 단순화했습니다 .
마일

@miles 정말 재밌 네요. 답변을 썼는데도 그 도전에 대해 완전히 잊어 버렸습니다. Dennis는 골프를 도와 준 정확한 Python 답변 을 받았습니다 .
xnor

그 "시각적 증거"는 깔끔합니다. 나는 같은 생각을 가지고 있지만 그것을 증명하기 위해 그 공식의 각 경우를 배치해야했습니다. 부수적으로, 써드 파티 라이브러리를 사용하여 파이썬에서 순위를 얻는 몇 가지 대안 이이 게시물에 나와 있습니다.
Joel

5

05AB1E , 7 바이트

āœΣαO}н

온라인으로 사용해보십시오!


설명

ā              # get the numbers 1 to len(input) + 1
 œ             # Permutations of this
  Σ  }         # Sort by ...
   α           # Absolute difference
    O          # Sum these
      н        # And get the first one 
               # implicitly print

1
내가 이것에 놀랄 때마다 05AB1E 무엇을 할 수 없습니까?
랜덤 녀석

5
@Therandomguy 05AB1E에서는 할 수없는 일이 많지 않지만 정규식 기반의 도전; 매트릭스 기반 도전 (이것은 일부 새로운 내장 후에 개선되었지만); 허수의 부족; 날짜 / 시간 관련 과제; 그러나 어렵지만 일반적으로 여전히 수행 할 수 있습니다. 두 가지 예를 들면 다음과 같습니다 . 근무일 카운트 다운 (다음 날로 이동하여 요일을 수동으로 수행함); Quine은 2 진으로 자체 출력합니다 (UTF-8 변환은 수동으로 수행됨).
Kevin Cruijssen

@Grimy는 :) 이제 수정되어야합니다
데이터 만료

3

펄 6 , 44 바이트

{permutations(+$_).min((*[]Z-$_)>>.abs.sum)}

온라인으로 사용해보십시오!

Anonymous codeblock that returns the first minimum permutation with 0 indexing.

Explanation:

{                                          }   # Anonymous code block
 permutations(+$_)                             # From the permutations with the same length
                  .min(                   )    # Find the minimum by
                                      .sum       # The sum of
                                >>.abs           # The absolute values of
                       (*[]Z-$_)                 # The zip subtraction with the input

I think I might also be able to get rid of the .sum and sort by just the list of absolute values, but I'm not sure this is actually corret, though it passes my current test cases.


1
그것은 나의 두뇌도 깨뜨리고 있었다. 가장 간단한 반례는 [0.6 1](우리가 0 인덱싱되었다고 가정)이며, 첫 번째 값 [1,0]을 최적화하면 1.4의 점수 를 얻지 만 전체 벡터를 최적화하면 1은 점수의 두 번째 위치에서 더 가치가 있습니다 0.6의.
histocrat


2

젤리 , 5 바이트

Œ¿œ?J

정수 목록을 생성하는 숫자 목록을 허용하는 모나드 링크.

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오.

어떻게?

Œ¿œ?J - Link: list of numbers, X
Œ¿    - Index of X in a lexicographically sorted list of
         all permutations of X's items
    J - range of length of X
  œ?  - Permutation at the index given on the left of the
         items given on the right

NB L(길이)는 정수가 주어진 J이후에 작동 합니다. 오른쪽에서 암시 적 으로 작동 할 범위 를 만들지 만 명시 적입니다.œ?n[1..n]J


2

루비 , 63 60 바이트

->v{[*1..v.size].permutation.max_by{|p|eval [p,0]*'*%p+'%v}}

온라인으로 사용해보십시오!

여기에는 다른 답변에도 도움이되는 수학 트릭이 있습니다. 차이의 절대 값의 합계를 최소화하는 대신 제품의 합계를 최대화 합니다. 왜 작동합니까?

합계 (x-y) squared를 최소화하는 것은 합계를 최소화하는 것과 다릅니다|x-y| 않지만 항상 유효한 답을 제공합니다. 작은 것보다 큰 차이를 줄이는 것을 우선시하는 반면 실제 과제는 둘 사이에 무관심합니다.

그러나 (x-y)*(x-y)= x*x+y*y-2*x*y. 제곱 항은 항상 순열의 합계 어딘가에 표시되므로 결과에 영향을 미치지 않으므로로 단순화 할 수 있습니다 -2*x*y. 2요인 밖으로, 그래서 우리는로 단순화 할 수 있습니다 -x*y. 그런 다음 최소화를 최대화로 변경하면로 단순화 할 수 있습니다 x*y.

직관적으로 이것은 수평 벽 세트와 수직 벽 세트를 사용하여 정사각형 푸티지를 최대화하려는 경우 크기가 서로 다른 벽을 짝을 이루는 것이 가장 좋습니다. 가능한 한 정사각형에 가깝습니다. 3*3 + 4*4 = 25, 동안3*4 + 4*3 = 24 .

편집 : zip 및 sum을 사용하는 대신 형식 문자열을 생성하고 평가하여 3 바이트를 절약했습니다.


2
(xy) 제곱의 합계를 최소화하는 것은 | xy |의 합계를 최소화하는 것과 같지 않지만 항상 유효한 대답을 제공합니다. 왜 그런가요? 없어요와이 그 최소화 |엑스와이| 하지만 (엑스와이)2?
Joel

1

가이아 , 13 바이트

e:l┅f⟪D†Σ⟫∫ₔ(

온라인으로 사용해보십시오!

e:		| eval and dup input
l┅f		| push permutations of [1..length(input)]
⟪   ⟫∫ₔ		| iterate over the permutations, sorting with minimum first
 D†Σ		| the sum of the absolute difference of the paired elements
       (	| and select the first (minimum)

1

자바 스크립트 (ES6), 61 바이트

xnor의 통찰력을 기반으로 합니다 .

a=>[...a].map(g=n=>g[n]=a.sort((a,b)=>a-b).indexOf(n,g[n])+1)

온라인으로 사용해보십시오!

댓글

a =>                    // a[] = input array
  [...a]                // create a copy of a[] (unsorted)
  .map(g = n =>         // let g be in a object; for each value n in the copy of a[]:
    g[n] =              //   update g[n]:
      a.sort(           //     sort a[] ...
        (a, b) => a - b //       ... in ascending order
      ).indexOf(        //     and find the position
        n,              //       of n in this sorted array,
        g[n]            //       starting at g[n] (interpreted as 0 if undefined)
      ) + 1             //     add 1
  )                     // end of map()

자바 스크립트 (ES6)  130  128 바이트

 있어야합니다  확실히 더 직접적인 방법 ...

인덱스가 0입니다.

a=>(m=g=(k,p=[])=>1/a[k]?(h=i=>i>k||g(k+1,b=[...p],b.splice(i,0,k),h(-~i)))``:p.map((v,i)=>k+=(v-=a[i])*v)|k>m||(R=p,m=k))(0)&&R

온라인으로 사용해보십시오! (1 인덱스 출력)

어떻게?

도우미 기능 모든 순열을 계산합니다 (0,...,1), 어디 입력 배열의 암시 적 길이 [].

각 순열에 대해 우리는 다음을 계산합니다.

케이=1+나는=01(나는나는)2
주요한 이유 1 내부 카운터를 재사용한다는 것입니다 몇 바이트를 절약하지만 최종 결과에는 영향을 미치지 않습니다.

우리는 결과적으로 가장 작은 순열을 반환합니다 케이.



1

파이썬 (2) , 149 (126) 112 바이트

Mr. Xcoder 덕분에 -23 바이트

xnor 덕분에 -14 바이트

from itertools import*
f=lambda a:min(permutations(range(len(a))),key=lambda x:sum(abs(a-b)for a,b in zip(x,a)))

온라인으로 사용해보십시오!

(0 ... n-1)의 순열을 사용합니다.


functools더 이상 필요하지 않도록 Python 2로 전환 할 수 있습니다 .
Mr. Xcoder

reduce일반적으로 과잉, 특히 여기에 물건을 추가하는 곳입니다. 당신이 할 수 있다고 생각합니다 sum(abs(p-q)for p,q in zip(x,a)).
xnor

0

순열 패키지없이

파이썬 3 , 238 바이트

def p(a,r,l):
 if r==[]:l+=[a];return
 for i in range(len(r)):
  p(a+[r[i]],r[:i]+r[i+1:],l)
def m(l):
 s=(float("inf"),0);q=[];p([],list(range(len(l))),q)
 for t in q:D=sum(abs(e-f)for e,f in zip(l,t));s=(D,t)if D<s[0]else s
 return s[1]

온라인으로 사용해보십시오!



0

Japt -g , 12 바이트

Êõ á ñÈíaU x

시도 해봐

인덱스가 0 인 경우 처음 2 바이트를 대체하여 m,대신 배열을 해당 인덱스에 매핑합니다.

Êõ á ñÈíaU x     :Implicit input of array U
Ê                :Length
 õ               :Range [0,Ê]
   á             :Permutations
     ñÈ          :Sort by
       í U       :  Interleave with U
        a        :  Reduce each pair by absolute difference
           x     :  Reduce resulting array by addition
                 :Implicit output of first sub-array

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.