자동 구성 / 스마트 인벤토리 시스템?


11

지난 주에 Unity3D로 인벤토리 시스템을 작업했습니다. 처음에 Design3의 직원들로부터 도움을 받았지만 경로를 나눌 때까지 너무 길지 않았습니다. 코드를 작성하는 방식이 마음에 들지 않았기 때문에 OOP 냄새가 전혀 없었습니다.

아이템을 두 개 이상 가져 가거나, 고급 배치 시스템 (항목이 가장 잘 맞는 것을 찾으려고 노력합니다), 로컬 마우스 시스템 (마우스가 활성 백 영역에 갇히게 됨) 등을 수행했습니다.

여기 내 작품 의 데모 가 있습니다.

우리가 게임에서 갖고 싶은 것은 자동 정렬 기능이 아니라 자동 구성 기능입니다. 우리는 인벤토리가 게임을 일시 중지하고 인벤토리에서 작업을 수행하는 Resident Evil 1,2,3과는 달리 '실시간'에 있기 때문에이 기능을 원합니다. 이제 좀비로 둘러싸인 끈적 끈적한 상황에서 자신을 상상해보십시오. 탄알이없고, 주변을 둘러보고, 주변에 총알이 있음을 알 수 있습니다. 맞지 않아! 재고를보고 일부 품목을 재구성하면 적합 할 것임을 알 수 있습니다! -이제 플레이어-그 상황에서 좀비로 둘러싸여 있기 때문에 재구성 할 시간이 없으며 공간을 확보하기 위해 인벤토리를 중지하고 구성하면 죽을 것입니다 (실시간으로 인벤토리를 기억하고 일시 중지하지 마십시오)- t 자동으로 발생하는 것이 좋습니까? - 예!

(이것은 Dungeon siege와 같은 일부 게임에서 구현되었다고 생각하므로 가능합니다.)

예를 들어이 사진을 살펴보십시오.

자동 정렬 기능

예, 따라서 문제를 자동 정렬하면 공간이 생겨나지 만 다음과 같은 이유로 나빠질 수 있습니다. 맨 왼쪽으로 이동하면 자동 정렬에서 얻은 것과 동일한 공간이 생깁니다. 2- 그것은 플레이어에게 성가신 일입니다. "F가 당신에게 내 물건을 다시 주문하라고 했나요?"

나는 이것을 위해 "코드를 작성하는 방법"을 요구하지 않고, 어떤 지침이 필요한지, 어디를보아야하는지, 어떤 알고리즘이 관련되어 있는가? 이것은 그래프 및 최단 경로와 관련이 있습니까? 나는 대학 공부를 계속하지 못했으면 좋겠다 : / 그러나 그것이 맞더라도 말해 주시면 관련된 것들을 배울 것입니다.

하나 이상의 솔루션이있을 수 있습니다. 그래서 내가해야 할 첫 번째 일은 상황이 '해결 가능'인지 알아내는 것입니다. 상황이 해결할 수 있는지 여부를 결정하는 방법을 알고 있다면 '해결'할 수 있습니다. 나는 그것을 '해결 가능'하게 만드는 조건을 알아야합니다. 그리고 나는 이것을 위해 알고리즘 / 데이터 구조가 있어야한다고 생각합니다.

다음은 1x3 항목을 맞추는 여러 솔루션에 대한 그림입니다.

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

화살표는 솔루션 중 하나만 표시하지만, 보시면 둘 이상을 찾을 수 있습니다. 이것이 궁극적으로 자동 정렬이 아니라 해결책을 찾아 적용하는 것입니다.

내가 그것에 시간을 보내면 그것을 해결할 수있는 방법을 생각해 낼 것이지만 최선의 방법은 아닐 것입니다. 손 대신에 차 바퀴를 쥐고있는 것과 같습니다! XD 또는 배열이 필요한 문제를 해결하려고하는 것과 같지만 아직 존재하지 않는 것을 알고 있습니다! 그렇다면 올바른 접근 방법은 무엇입니까?

해설에서 업데이트

@Stephen 저는 Alogs의 전문가가 아닙니다 .'knapsack '과 @BlueRaja를 언급했습니다. Danny Pflughoeft는 2D 빈 포장 고를 언급했습니다. 그들은 어떻게 든 관련이 있습니까? -어떻게 접근해야할지 아직도 혼란 스러워요.

그리고 그렇습니다. 나는 이미 "휴리스틱"을 사용하고 있지만 실제로 내가 다음과 같은 것을 알지 못했습니다.

"bulkness"(nSlotsRequired = nRowsReq * nColsRec라고 함)를 기준으로 항목을 주문하면 작동하는지 알 수 없습니다. 예를 들어 2x2 및 1x4 항목이 있기 때문에 부피가 동일하지만 모양이 다르고 모양이 다릅니다. 다음에 나머지 항목이 어떻게 진행되는지에 대한 다른 효과. SO ... : /

나는 비디오를 보았고 , 전체 포장 아이디어를 정말로 좋아했지만 인벤토리가 2D이므로 어떻게 해야할지 궁금합니다. 빈 포장이 핵심이라고 확신하지 못합니다. 왜냐하면 하나 이상의 가방을 가질 수 있다는 것이 사실이지만, 우리 게임에서는 단지 하나의 가방이 될 것입니다. 따라서 '1'백에 품목을 넣는 것 이상의 문제입니다. 따라서 그 vid (파이프 및 버스)의 예제는 실제로 내 문제와 일치하지 않습니다. 또한이 배낭에 관한 몇 가지 물건을 보았습니다. '값'이 내 항목 / 재고와 어떻게 관련되어 있는지 알지 못했지만 '무게'는 부피와 같은 것 같습니다.


7
이것은 2D bin-packing으로 NP-Complete입니다. 따라서 모든 항목을 넣을 수 있는지 알려주는 알고리즘은 비효율적입니다 (최악의 경우). 그래도 꽤 좋은 근사 알고리즘을 찾을 수 있습니다.
BlueRaja-대니 Pflughoeft

이것이 바로 내가 요즘 (더 일반적인) 품목 당 하나의 슬롯 당 유형 재고 모델을 결정한 이유입니다. 나는 당신을위한 해결책을
원했고,

@ BlueRaja-DannyPflughoeft 아이템이 특정 모양으로 제한된 경우 간단하고 효율적인 알고리즘을 사용할 수 있는지 궁금합니다.
congusbongus

모양을 제한하면 복잡성이 줄어들지 않고 생각하기가 쉬워 지므로 복잡성이 해결되었다고 생각할 수 있습니다.
Patrick Hughes

@VeXe 죄송합니다. 귀하의 질문에 대한 업데이트가 누락되었습니다. 빈 포장과 배낭은 동일하지 않습니다. 그러나 둘 다 포장 문제입니다. 귀하의 경우 '값'은 인벤토리 개체의 모양과 크기입니다.
Stephen

답변:


8

이것은 배낭 문제의 변형입니다. Danny Pflughoeft가 언급 한 것처럼 NP-Complete입니다. 내가 올바르게 기억한다면 선형 시간으로 해결할 수 없다는 것을 의미합니다.

그러나 여러 단계로이 문제를 해결할 수 있습니다. 기본적으로 정렬 문제입니다.

각 항목의 '불량'을 계산하는 것으로 시작하겠습니다. 여러 가지 방법으로 계산할 수 있습니다.

  • 부피 = 최대 (길이, 너비);

  • 부피 = 길이 * 너비

  • 부피 = sqrt (길이 * 너비)

그런 다음 가장 높은 점수를받은 항목을 먼저 인벤토리에 넣습니다. 그들은 나중에 나머지 공간에 맞지 않을 것이므로. 작은 아이템은 항상 맞습니다.

배치 전략에 휴리스틱 (교육적인 추측을위한 멋진 이름 ;-))이 필요합니다. 왼쪽 상단에서 첫 번째 빈 슬롯에 항목을 맞추는 것과 같은 것.

디아블로 II 인벤토리 정렬 전략은 다소 비슷하게 작동한다고 생각합니다. 칼과 창과 같은 물건은 왼쪽 상단에, 옷과 갑옷, 버클러 등으로 끝납니다.

나는 당신이 정말로 이것을 시도하고 알고리즘이 충분히 작동 할 때까지 알고리즘 (다른 부피 계산, 다른 휴리스틱)을 조정할 필요가 있다고 생각합니다.


1
NP- 완료는 다항식보다 복잡도가 높은 일련의 문제입니다. 상대적으로 작은 재고 (1,000 개 미만의 항목)의 경우 지수 알고리즘조차도 매우 빠르게 작동합니다.이 알고리즘의 한 단계는 시간이 거의 걸리지 않기 때문입니다. > 한 - 그럼에도 불구하고 당신의 아이디어를 사용하여 충분한 및 동적 프로그래밍 알고리즘을 구현하는 것보다 쉬울한다
MartinTeeVarga

공감에 대한 thx. 예, 인벤토리는 잠재적으로 무한하지 않아야하므로 지수 알고리즘이 제대로 작동해야합니다 ^^
Stephen

@ sm4 : 천 (천)은 일반적으로 NP-Complete 문제에 대한 막대한 숫자입니다. 이 문제는 O (2 ^ n)입니다. 심지어 2 ^ 64조차도 계산할 수 없습니다!
BlueRaja-대니 Pflughoeft

3

하하, @ 도움을 주신 모든 분들, 감사합니다. 나는 마침내 그것을 해결했다. 기본적으로 내가 한 일은 다음과 같습니다.

IEnumerator AddItem_Sorted (Item item)
  1. 사소한 조건 : 항목에 맞는 최소 nRequiredSlots가 있는지 확인하십시오.
  2. 우리는 모든 가방을 비울 것입니다-항목을 자리 표시 자 (목록 또는 무언가)에 넣습니다.
  3. 원하는 아이템을 매우 마지막 슬롯 / 장소에 추가하여 수평 모양인지 확인하십시오.
  4. 첫 번째 맞춤 감소 알고리즘을 사용하여 나머지 항목을 추가합니다.
  5. 추가하는 동안, 우리는 동적 프로그래밍 (memoisation)을 사용하여 우리가 추가 할 인덱스 (다음 사용 가능한 슬롯의 인덱스)를 기억할 것입니다
  6. 모든 추가 작업이 성공하면 원하는 항목을 맞추고 큰 것에서 작은 것까지 가방을 정렬했습니다.
  7. 모든 품목을 추가 할 수없는 경우 이는 해결할 수있는 상황이 아니므로 가방을 이전 상태로 가져와야 함을 의미합니다.
  8. 그렇게하는 한 가지 방법은 (내 마음의 표면에서 나왔음)이 전체 작업 전에 백의 상태를 복사하는 것입니다. 그리고 실패 할 경우 ' 가방을 비우면 각 항목의 위치를 ​​기억하여 op가 실패하면 이전 항목에서 AddItem (item, index)을 사용하여 다시 가져옵니다. :)
  9. 이 전체 프로세스에는 시간이 걸릴 수 있으므로 내 멋진 수확량을 사용하여 별도의 프레임에서 부하를 나눌 수 있습니다. :)
  10. 완료 ! \ m / (@ ~ 9 : 00)

최신 정보:

  1. 추가 된 모든 항목의 색인을 저장하는 배열을 만들었습니다. 그러면 내가 갈 필요가없는 점유 슬롯을 찾을 필요가 없습니다.

  2. 마지막 슬롯에 추가 할 필요가 없습니다. 실제로는 때로는 그렇게 작동하지 않을 수 있습니다. 필요한 항목을 다른 항목에 추가하고 정렬했습니다.

비디오에서 볼 수 있듯이 약간의 최적화가 필요하며 정렬이 완벽하지는 않습니다. 전체 빈 포장을 사용하고 싶지만 이미 성능이 욕심입니다. 다시 한 번 감사드립니다 :)


천만에요! :) 빈 포장에 대해 언급 한 BlueRaja-Danny Pflughoeft, 부피 아이디어에 대한 @Stephen, 동적 프로그래밍 강의에 대한 Richard Buckland 및 모든 강의에 대해 감사드립니다.
vexe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.