2D 평면에서 가장 긴 경로


14

임의의 고유 한 2 차원 정수 직교 좌표 세트가 제공됩니다. 예 : [(0,0), (0,1), (1,0)]

좌표가 한 번만 "방문"될 수 있다는 제한을두고이 좌표 세트에서 가능한 가장 긴 경로를 찾으십시오. (그리고 시작한 좌표로 "돌아 오지"않습니다).

중대한:

좌표 나 그 주위를 "통과"할 수 없습니다. 예를 들어, 마지막 음표 예 (직사각형)에서는 C 방문 하지 않고 D에서 A로 이동할 수 없습니다 (이는 재 방문이어서 찾은 길이를 무효화 할 수 있음). 이것은 @FryAmTheEggman에 의해 지적되었습니다.

함수 입력 : 2 차원 데카르트 좌표 배열
함수 출력 : 최대 길이 만
수상자 : 최단 코드 승리, 보류 금지 없음 (가장 공간 효율적이지 않음)


원점 삼각형

1 : 위에 표시된이 경우 좌표가 두 번 방문되지 않은 가장 긴 경로는 A-> B-> O (또는 OBA 또는 BAO)이며 경로 길이는 sqrt (2) + 1 = 2.414입니다.




광장

2 : 위에 표시된이 경우 두 번 "방문"된 좌표가없는 가장 긴 경로는 ABOC (및 분명히 COBA, OCAB 등)이며 표시된 단위 사각형의 경우 sqrt (2) + sqrt (2) +로 계산됩니다. 1 = 3.828.


참고 : 다음은 이전의 두 예제만큼 간단하지 않은 추가 테스트 사례입니다. 이것은 6 좌표로 형성된 직사각형입니다.

여기에 이미지 설명을 입력하십시오

여기서, 긴 경로는 : A -> E -> C -> O -> D -> 8.7147이고 B,
(최대 가능한 대각선 걸어 이송없는 가장자리)


여기의 매우 비슷한 질문은 다른 점수이기는하지만.
Geobits

@Geobits Agreed,하지만 거기에 문제 설명을 통해 "매우"라고 말하지 않았습니다. 그리고 그 문제에 대해, 최소 / 최대 경로 문제는 본질적으로 일반적인 그래프 용의자의 풍미입니다. 바이트 절약 솔루션에 관심이 있습니다.
BluePill

@Fatalize Done. 8.7147입니다.
BluePill

그건 그렇고 : PPCG에 오신 것을 환영합니다!
Fatalize

@Fatalize 감사합니다! (실제로 나는 이곳에서 잠시 동안 관찰자로 활동했으며, 오늘부터 활동을 시작했습니다. :)
BluePill

답변:


3

Pyth, 105 (103) 100 92 86 바이트

V.pQK0FktlNJ.a[@Nk@Nhk)FdlNI&!qdk&!qdhkq+.a[@Nk@Nd).a[@Nd@Nhk)J=K.n5B)=K+KJ)IgKZ=ZK))Z

              Z = 0 - value of longest path
              Q = eval(input())

V.pQ         for N in permutations(Q):
  K0           K = 0 - value of current path
  FktlN        for k in len(N) - 1:
    J.a          set J = distance of
    [@Nk                 Q[k] and Q[k+1]
    @Nhk)    
    FdlN         for d in len(N):
I&                 if d != k && d != (k + 1)
!qdk
&!qdhk
q+                and if sum of
.a                   distance Q[k] and Q[d]
 [@Nk                
 @Nd)                
.a                   distance Q[d] and Q[k+1]
 [@Nd
 @Nhk)
J                    are equal to J then
  =K.n5              set K to -Infinity
  B                  and break loop
                     ( it means that we passed over point )
  )                   end of two if statements
=K+KJ                  K+=J add distance to our length
)                      end of for
IgKZ                   if K >= Z - if we found same or better path
  =ZK                  Z = K       set it to out max variable
))                     end of two for statements
Z                      output value of longest path 

여기 사용해보십시오!


2

수학, 139 바이트

Max[Tr@BlockMap[If[1##&@@(Im[#/#2]&@@@Outer[#/Abs@#&[#-#2]&,l~Complement~#,#])==0,-∞,Abs[{1,-1}.#]]&,#,2,1]&/@Permutations[l=#+I#2&@@@#]]&

테스트 사례

%[{{0,0},{0,1},{1,0},{1,1},{2,0},{2,1}}]
(* 3 Sqrt[2]+2 Sqrt[5] *)

%//N
(* 8.71478 *)

1

341 322 318 바이트

sub f{@g=map{$_<10?"0$_":$_}0..$#_;$"=',';@l=grep{"@g"eq join$",sort/../g}glob"{@g}"x(@i=@_);map{@c=/../g;$s=0;$v=1;for$k(1..$#c){$s+=$D=d($k-1,$k);$_!=$k&&$_!=$k-1&&$D==d($_,$k)+d($_,$k-1)and$v=0 for 0..$#c}$m=$s if$m<$s&&$v}@l;$m}sub d{@a=@{$i[$c[$_[0]]]};@b=@{$i[$c[$_[1]]]};sqrt(($a[0]-$b[0])**2+($a[1]-$b[1])**2)}

이 코드는 최대 100 점을 지원합니다. 가능한 모든 점 순열을 생성하므로 100 점은 최소 3.7 × 10 134 yottabytes의 메모리를 필요로합니다 (12 점은 1.8Gb를 사용함).

댓글 :

sub f {
    @g = map { $_<10 ? "0$_" : $_ } 0..$#_; # generate fixed-width path indices
    $" = ',';                               # set $LIST_SEPARATOR to comma for glob
    @l = grep {                             # only iterate paths with unique points
        "@g" eq join $", sort /../g         # compare sorted indices with unique indices
    } glob "{@g}" x (@i=@_);                # produce all permutations of path indices
                                            # and save @_ in @i for sub d
    map {
        @c = /../g;                         # unpack the path indices
        $s=0;                               # total path length
        $v=1;                               # validity flag
        for $k (1..$#c) {                   # iterate path
            $s +=                           # sum path length
                $D = d( $k-1, $k );         # line distance 

              $_!=$k && $_!=$k-1            # except for the current line,
              && $D == d( $_, $k )          # if the point is on the line,
                     + d( $_, $k-1 )
              and $v = 0                    # then reset it's validity
            for 0 .. $#c                    # iterate path again to check all points
        }
        $m=$s if $m<$s && $v                # update maximum path length
    } @l;
    $m                                      # return the max
}

sub d {                                     
    @a = @{ $i[$c[$_[0]]] };                # resolve the index $_[0] to the first coord
    @b = @{ $i[$c[$_[1]]] };                # idem for $_[1]
    sqrt( ($a[0] - $b[0])**2       
        + ($a[1] - $b[1])**2 )      
}

테스트 사례 :

print f( [0,1], [0,0], [1,0] ), $/;        $m=0; # reset max for next call
print f( [0,0], [0,1], [1,0], [1,1] ), $/; $m=0;
print f( [0,0], [0,1], [0,2] ), $/;        $m=0;
print f( [0,0], [0,1], [0,2], 
         [1,0], [1,1], [1,2]),$/;          $m=0;
  • 322 바이트 : 재설정하지 않고 19를 저장 $"하고 일부 인라인
  • 318 바이트 : 최대 nr 좌표를 100으로 줄이면 4가 절약됩니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.