장치를 추가하거나 제거 할 때 직사각형 형태를 유지하려면 어떻게해야합니까?


18

행과 열이있는 직사각형 형태의 봇이 있습니다. 봇이 대형에서 추가되거나 제거 될 때 문제가 발생합니다. 이 경우, 봇은 직사각형 구성이 여전히 대략 동일한 종횡비이고 가능한 한 직사각형이되도록 스스로 재 배열해야 합니다. 이것을하는 방법?

몇 가지 아이디어 :

  • 봇을 추가하거나 제거 할 때 새로운 총 봇 수와 원하는 일정한 종횡비를 사용하여 해당 종횡비에 가장 잘 맞는 포메이션의 새로운 너비와 높이를 계산하십시오. 그런 다음 새로운 치수에 맞게 봇을 다시 섞습니다.

  • 봇이 제거되면, 그 뒤에 있던 봇을 그 자리로 옮기고 포메이션이 끝날 때까지 계속하십시오. 그런 다음 어떻게 든 랭크를 봇을 뒤섞음으로써 가능한 한 랭크를냅니다.

  • 완전히 다른 또 다른 아이디어는 분자 구조가 함께 머무르는 방식을 모방하는 것입니다. 가장 가까운 4 개의 봇을 끌어 들여 나머지 봇을 물리 치면 모든 봇을 다른 4 개의 봇으로 둘러싸고 싶어집니다. 역 제곱 법을 사용하여 분리하기에 너무 가까운 모든 봇 (4 개 포함)을 격퇴하십시오. 전체 구조를 형성하려면 추가 힘이 필요합니다. 그러나 이것은 계산 비용이 매우 많이 들립니다.

업데이트 : 그래서 sarahm의 대답을 살펴보면 좋은 치수를 제공하는 좋은 일반 기능을 생각해 냈습니다.

먼저 너비와 높이에 대한 아래의 동시 방정식을 풀고 답을 반올림했습니다.

width/height=aspect ratio of your choice
width*height=number of bots

이것은 봇 수에 대한 종횡비에 가장 가까운 정수 사각형을 제공합니다. 가장 가까운 사각형은 절반의 시간이 너무 길고 절반의 시간이 너무 작을 것입니다 (물론 때때로 옳을 지 모르지만 누가 신경 쓰는가). 사각형이있는 경우에 약간 너무 큰, 아무것도 요구 할 수 있습니다. 후순위는 거의 가득 차서 이상적입니다. 사각형이있는 경우에는 약간의 그 조그마한 작은 오버 플로우가 자신의 순위가 꽤 보이지 않는 거기에 몇 봇으로 순위를 생성에 가야하기 때문에 너무 작은, 당신은 문제를 얻었다. 차이가 경우도 있습니다(폭의 절반보다 큼),이 경우 차이를 작게 만들기 위해 한 순위를 더하거나 뺍니다. 그런 다음 사각형이 너무 작 으면 열을 하나 더 추가하여 조금 더 크게 만드십시오. 이 것을 수행 한 후 보이는 뒷면 순위는 항상 적어도 것 같은 다른 계급 많은 봇있다.

최신 정보

치수를 얻은 후에는 현재 치수와 비교하십시오. 새로운 차원의 경계가 더 클 경우, 모든 순위에 대해 아래 순위에서 봇을 팝하고 해당 순위의 봇 수가 정면과 같을 때까지 현재 순위로 밉니다. 당신이 역 순위에 도달 할 때까지 해당 알고리즘을 계속하십시오. 이 알고리즘을 사용하면 봇이 새로운 차원에 효율적으로 맞출 수 있습니다. 그 후, 나는 단순히 새로운 오래된 것을 백 랭크로 밀어 넣습니다. 새로운 경계가 작은 경우 알고리즘이 약간 다르지만 알아낼 수 있습니다!

다음에는 두 가지 문제가 더 있습니다. 새로운 봇이 반드시 백 랭크에 할당 될 필요는 없지만 추가되는 순간 가장 가까운 위치에 배치되는 삭제 및보다 유연한 추가 방법.


유닛의 최대 봇 수는 얼마입니까? 상대적으로 작은 경우 특정 봇 수에 대해 행에있는 행 수와 열 수를 하드 코드 할 수 있습니다.
Exilyth

3
유효하거나 유효하지 않은 대형 이미지를 게시 할 수 있습니까? 당신이 무엇을 겪고 있는지 이해하는 데 약간의 어려움이 있습니다. 불완전한 행 / 열이 허용됩니까?
MichaelHouse

3
소수에 대해서는 효과가 없다는 것을 알고 있습니까? 예를 들어 7 개의 봇을 사용하는 경우 뒷면에 단일 봇이있는 3x2 장치를 만들어야합니다.
Exilyth

1
그것 참 부끄럽 네. 소수를 완전히 잊었습니다. 그렇다면 다음으로 가장 좋은 것은 ALMOST로 채워진 행과 열만 허용하는 것입니다. 행에있는 하나의 봇은 올바르게 보이지 않지만 행에있는 하나의 봇은 나쁘지 않습니다.
Tiby312

3
소수는 문제를 일으킬 수있는 유일한 숫자는 아닙니다. 팩토링을 통해 대형 크기를 선택하면 합리적으로 길고 마른 대형을 만들 수 있습니다. 예를 들어 14 개의 봇이있는 경우 완벽한 직사각형 구성은 7x2 뿐이며 추가 행이 2 개인 3x4 구성을 사용하는 것이 더 나을 수 있습니다.
Nathan Reed

답변:


16

또 다른 기술은 나폴레옹 대대가 사용했던 것을 모방하는 것입니다 (아마도 그리스 지골까지는 멀어 질 것입니다).

정면은 일반적으로 일정하게 유지되며, 남자가 (등을 제외한 다른 계급에서) 넘어 가면 앞으로 나아간 남자로 대체됩니다. NCO는 각 측면의 극단에 몇 명의 남성을 확보하고, 그렇지 않으면 균등하게 채우기 위해 백 랭크를 뒤섞습니다.

백 랭크가 사전 지정된 밀도 아래로 떨어질 때만 정면도가 줄어 듭니다. 마찬가지로, 백 랭크가 가득 차면 엑스트라는 먼저 양쪽 측면에서 추가 랭크를 채우기 시작한 다음 전면이 증가합니다.

Frontage를 변경할 때 Frontage를 늘리면 봇 파일을 Back 랭크에서 두 측면으로 내보내고 Frontage를 줄일 때는 두 측면에서 Back 랭크로 제출하는 것이 좋습니다.

만약 당신이 "군사적"인상을 찾고 봇 조직이 지골처럼 보이게한다고 추론하는 것이 맞다면, 나는이 순서 재정렬이 그 목적을 달성하기위한 더 좋은 방법이라고 생각합니다.

업데이트 :
백행을 관리하는 간단한 방법 중 하나는 백행 유닛을 각 측면과 중앙에 각각 3 개의 분대로 나누는 것입니다. 프론 티지가 홀수인지 짝수인지, 그리고 백-로우 유닛의 수가 0, 1 또는 2 mod 3과 일치하는지 여부에 따라 정확히 6 가지 경우가 관리됩니다.

위의 개선 사항으로, 채우기가 임계 값 아래로 떨어지면 각
백열 스쿼드의 마지막 단위 간격을 고려하십시오 ( xxx.x .... x.xxx.x .... x). xxx
또는 이것 :
xx.xx..x.xxx.x ... xxxx
더 나은 외관을 위해 조금 더 많은 작업.

업데이트 # 2 :
포메이션 깊이에 대한 추가 생각. 현대 대검과 함께 발리 화재의 영향으로 18 세기 후반과 19 세기 초 깊이가 3-4로 적절 해졌다. (영국 은 전투 후반까지 대중의 신념에 반하여 2 계급에서는 거의 싸운 적이 거의 없었 습니다. 하나는 너무 빨리 사각형을 형성하기에 너무 길었습니다.) 또는 Sarissa가 장착 된 그리스 지골의 경우 10 원하는 인상을주는 깊이를 선택하십시오.

실제 군대는 유닛 취성을 증가시키지 않으면 서 가능한 한 오랫동안 유닛 정면을 유지하려고 노력합니다. Pharsalus의 Caesar는 폼페이우스 부대의 정면과 일치하도록 정면을 늘리기 위해 의도적으로 부대 깊이를 줄였습니다. "우리는 오늘이기거나 죽는다. 폼페이의 사람들은 다른 선택을 할 수있다." (물론 카이사르는 영리하고 신중하게 보장했습니다).


이것은 훨씬 더 우아한 솔루션처럼 들립니다. 소수 또는 종횡비에 대해 전혀 신경 쓸 필요가 없지만 여전히 봇 수가 비정상적으로 적은 행을 피할 수 있습니다. 그리고 확인해야 할 유일한 조건은 백 랭크가 얼마나 가득 찬지입니다!
Tiby312

하지만 기다려 백 랭크에 3 개의 봇만 있고 열 1, 2 및 3에 있다고 가정 해 봅시다. 그리고 저는 5 열에서 누군가를 앞쪽 근처에서 제거합니다. 나는 자리를 잡을 수있는 봇없이 5 번째 열의 두 번째 행에서 마지막 행에 무료 자리를 얻었습니다. 이 자리를 누가 채워야합니까?
Tiby312

아마도 백 랭크에서 가장 가까운 봇 (즉, 3 열의 봇)이 채워져 봇을 채울 것입니다. 또는 두 번째-마지막 순위의 3 열과 4 열의 봇이 각 단계에서 한 열 위로 올라간 다음 간격을 3 열로 이동 한 다음 3 열의 봇을 앞으로 채우면 시간을 절약 할 수 있습니다 그것. (IMO, 가장 "자연스러운"전략은 아마도이 둘의 휴리스틱 조합 일 것입니다. 아마도 임의성이 발생했을 것입니다.
Ilmari Karonen

1
후면 순위가 너무 적은 회원 (다른 계급의 50 % 미만을 말한다)이 있고, 당신이 정면을 증가하는 경우, 이것이 보장 문제를 해결하기 위해, 또는 후면 순위가 할 가능성이 여전히 증가 후 너무 적은 수의 회원이 그것을 반복 해야하는 정면 또는 무언가?
Tiby312

1
@ Tiby312 : 당신이 그것을 너무 생각하고 있다고 생각합니다. 나중에 다시 조정할 수 있다는 것을 알고 시도해보십시오
Pieter Geerkens

7

유닛이 봇 의 선형 데이터 구조 (예 : 목록 ) 라고 가정합니다 .

먼저 데이터 구조에 봇추가 / 제거하고 장치 의 새로운 봇 수를 결정해야합니다.

그런 다음 https://en.wikipedia.org/wiki/Integer_factorization을 사용하여 새로운 양의 행과 열을 결정해야합니다 .

물론 소수 로 인해 항상 가능한 것은 아닙니다 . 새 단위 크기가 소수 인 경우에는 다음으로 큰 단위 크기를 사용해야합니다.

그런 다음 데이터 구조를 반복하여 행과 열에 봇을 할당하십시오.

봇을 배치하려면 데이터 구조를 반복하여 각 봇에 봇이있는 행과 열에 의해 결정된 양만큼 단위 위치로부터 위치 오프셋을 할당하십시오 (또는 봇 이동의 대상으로 설정).

한 모서리에 중심이 있는 유닛을 만들려면 봇의 위치는 다음과 같습니다.

unitPosition + heading * columnNumber * botSeparationDistance + rightVector * rowNumber * botSeparationDistance

중앙중앙에 있는 유닛을 만들려면 봇의 위치는 다음과 같습니다.

unitPosition + heading * (columnNumber * unitSeparationDistance-0.5 * (numberOfColumns * botSeparationDistance) + rightVector * rowNumber * botSeparationDistance-0.5 * (numberOfRows * botSeparationDistance)

여기서 heading 은 단위가 향하는 방향을 가리키는 벡터이고 rightVectorheading 과 직교하는 벡터 입니다.

botSeparation 거리를 조정하여 봇이 더 멀리 떨어져 있거나 가까이 서도록 할 수 있습니다.

멋진 느낌 이 든다면 rightVector * 0.5 * (numberOfColumns-actualNumberOfBotsInRow)로 마지막 행을 오프셋 하여 형성 중심에 둘 수 있습니다 .


이것은 내가 찾고있는 것에 매우 가깝습니다! 내 유일한 예약은 새 위치를 할당 할 때 한 행의 가장 오른쪽에있는 봇이 새 사각형의 다음 행의 가장 왼쪽에 할당되어 봇이 먼 거리로 이동하고 프로세스가 진행될 수 있다는 것입니다 다른 봇이 자신의 할당 된 새로운 위치에 도달하려고 시도합니다. 봇이 추가되거나 제거 될 때 봇이 멀리 떨어진 목적지에 도착하기 위해 번잡함에 따라 전체 구성이 혼란 스러울 것이라고 걱정합니다.
Tiby312

2
항상 새 위치를 계산 한 다음 선형 반복을 수행하는 대신 가장 가까운 봇을 해당 위치로 이동할 수 있습니다.
Exilyth 07-23-17

제곱 계산으로 끝나지 않고이 작업을 수행하는 방법은 무엇입니까? 이것을 올바르게 이해하고 있다면 각 Bot에 대해 2d 배열의 현재 위치에서 2d 배열의 가장 가까운 위치를 찾아야합니다.
Tiby312

각 반복에서 하나의 단위가 할당되므로 (추가 반복에서 고려할 필요가 없음) 런타임은 O (n!)입니다. 여전히 좋지는 않습니다. 그런 다음 [선택 최적화 구조]를 구축하고 n 범위 쿼리를 수행하는 것도 빠르지 않습니다. 내가 지금 생각할 수있는 유일한 것은 마지막 봇을 뒤쪽으로 옮기거나 마지막 봇을 뒤쪽에서 봇으로 채우는 것입니다.
Exilyth

이건 어때. 새로운 대형이 더 작은 행 크기를 가지고 있다고 가정하십시오. 그런 다음 각 행에 여분의 봇이 있습니다. 해당 봇을 아래로, 하나는 왼쪽으로 할당합니다. 그런 다음 다음 줄에 장소가없는 두 개의 봇이 있습니다. 이 두 가지를 아래로, 하나를 왼쪽으로 할당합니다. 그런 다음 장소없이 3 개의 봇을 얻었습니다. 하단에 여분의 줄이 생길 때까지 계속하십시오. 난 그냥 여기에 공을 뱉어. 나는 그것을 완전히 생각하지는 않았지만 그것이 효과가 있고 빠르다고 들린다.
Tiby312

2

더 큰 값을 작은 사각형으로 그래프에 가능한 위치를 저장합니다.

[4][3][2][1]
[3][3][2][1]
[2][2][2][1]
[1][1][1][1]

로봇이 제거 될 때마다 다른 모든 로봇을 검색하여 가장 작은 값을 가진 노드에서 로봇을 찾습니다. A * 또는 BST 알고리즘을 사용하여 가장 작은 값에서 빈 공간까지의 경로를 찾으십시오. 제거 된 것보다 작은 값을 가진 로봇이 없으면 아무것도하지 않습니다.

또한 사각형의 붕괴 방식을 제어 할 수 있어야합니다. 예를 들어 아래 그래프에서 로봇이 바닥을 떠날 때 측면에서 로봇이 그 자리를 채울 것입니다.

[4.9][3.8][2.7][1.0]
[4.8][3.7][2.6][1.0]
[3.9][3.6][2.5][1.0]
[3.5][3.4][2.4][1.0]
[2.9][2.8][2.3][1.0]
[2.0][2.1][2.2][1.0]
[1.9][1.8][1.7][1.0]
[1.6][1.5][1.4][1.0]

여기에서 3.8에서 하나가 제거되어 2.5에서 하나가 와서 그 자리를 채 웁니다.

[o][x][o][ ]
[o][o][o][ ]
[o][o][r][ ]
[o][o][ ][ ]
[o][o][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]

또 다른 예. 여기에서 2.8이 제거되어 가장 작은 노드 2.2가 그 자리를 채 웁니다.

[o][o][o][ ]
[o][o][o][ ]
[o][o][o][ ]
[o][o][o][ ]
[o][x][r][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]
[ ][ ][ ][ ]

경로 찾기 알고리즘을 사용하여 구멍을 찾기 위해 외부에 절대로 채우지 않는 값이 0 인 노드 링을 원할 것입니다.

[0.0][0.0][0.0][0.0][0.0][0.0]
[0.0][4.9][3.8][2.7][1.0][0.0]
[0.0][4.8][3.7][2.6][1.0][0.0]
[0.0][3.9][3.6][2.5][1.0][0.0]
[0.0][3.5][3.4][2.4][1.0][0.0]
[0.0][2.9][2.8][2.3][1.0][0.0]
[0.0][2.0][2.1][2.2][1.0][0.0]
[0.0][1.9][1.8][1.7][1.0][0.0]
[0.0][1.6][1.5][1.4][1.0][0.0]
[0.0][0.0][0.0][0.0][0.0][0.0]

A *에 대한 유용한 자습서는 여기를 참조하십시오 .


이것은 좋은 생각이지만, 이것을 올바르게 이해하면 완벽한 사각형이 아닌 대형을 만들 수 있습니다. 테두리의 행과 열이 가득 차지 않았을 수 있습니다. 나는 항상 직사각형 테두리를 갖도록 만들 수 있다고 생각했지만 행과 열 수를 변경 하여이 요구 사항을 충족시키기 위해 종횡비를 약간 변경했습니다. 나는 이미 이것을 달성 할 수있는 새로운 너비와 높이를 계산할 수 있지만 봇을 가장 가까운 스팟에 다시 할당하는 복잡한 방법이 있습니다.
Tiby312

@ Tiby312 당신은 어떻게 ... 7 개의 로봇으로 완벽한 사각형을 만들 계획입니까?
ClassicThunder

절대 소수를 잊어 버렸습니다. 죄송합니다. 그러나 여전히 행과 열의 수를 조정하면 봇 수가 비정상적으로 적은 행이나 열을 피할 수 있다고 생각합니다.
Tiby312

@ Tiby312 항상 완벽한 사각형을 만드는 것보다 일관된 종횡비 (즉, 항상 4 : 3 또는 8 : 5)를 목표로하는 것이 좋습니다.
corsiKa
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.