Otomatik organize / akıllı envanter sistemi?


11

Geçen hafta Unity3D ile bir envanter sistemi üzerinde çalışıyordum. İlk başta Design3'teki adamlardan yardım aldım ama yolu ayırıncaya kadar çok uzun değildi, çünkü kodlarını yapma şeklini gerçekten sevmedim, OOP kokusu yoktu.

Daha ileri adımlar attım - öğeler birden fazla yuva, gelişmiş yerleşim sistemi (öğeler en iyi uyumu bulmak için ellerinden geleni yapıyor), yerel fare sistemi (fare aktif torba alanında sıkışıyor) vb.

İşte işimin bir demosu .

Oyunumuzda olmasını istediğimiz şey, otomatik sıralama değil, otomatik düzenleme özelliğidir. Bu özelliği istiyoruz çünkü envanterimiz 'gerçek zamanlı' olacak - oyunu duraklatacağınız ve envanterinizde bir şeyler yapacağınız Resident Evil 1,2,3 vb. Şimdi kendinizi zombilerle çevrili yapışkan bir durumda hayal edin ve mermileriniz yok, etrafınıza bakın, yakınlarda yerde mermiler olduğunu görüyorsunuz, bu yüzden onlar için gidip onları almaya çalışıyorsunuz, ama onlar yok uygun değil! envanterinize bakın ve bazı öğeleri yeniden düzenlerseniz, uygun olacağını öğrenin! - şimdi oyuncu - bu durumda yeniden düzenlemek için zaman yok çünkü zombilerle çevrili ve durmak ve envanteri yer açmak için organize ederse ölecek (gerçek zamanlı envanteri hatırlayın, duraklama yok) - t Otomatik olarak gerçekleşmesi iyi olur mu? - Evet!

(Bunun Dungeon kuşatması veya başka bir oyunda uygulandığına inanıyorum, bu yüzden yapılabilir)

bu resme bir göz atın örneğin:

Otomatik sıralama ne işe yarar

Evet, sorunu otomatik olarak sıralarsanız alanlarınızı alırsınız, ancak kötüdür, çünkü: 1- Pahalı: Bu alanları boşaltmak için bir çeşit işleme gerek yoktur, ilk resimde kırmızı öğeyi en solda, otomatik sıralamadan aldığınız boşlukların aynısını elde edersiniz. 2- Oyuncu için can sıkıcı: "F, eşyalarımı yeniden sipariş etmenizi kim söyledi?"

Bunun için "nasıl kod yazmak" için sormuyorum, ben sadece bazı rehberlik, nereye bakmak, hangi algoritmalar dahil soruyorum? Bu, grafikler ve en kısa yollarla ilgili bir şey mi? Umarım kolej çalışmalarına devam etmeyi başaramadım: / Ama öyle olsa bile, sadece söyle bana ve ilgili şeyleri öğreneceğim.

Birden fazla çözüm olabileceğine dikkat edin. Sanırım ilk yapmam gereken durumun 'çözülebilir' olup olmadığını anlamak - bir durumun çözülebilir olup olmadığını nasıl belirleyeceğimi bilirsem, o zaman 'çözebilirim'. Sadece 'çözülebilir' kılan koşulları bilmem gerekiyor. Ve bunun için bir algoritma / veri yapısı olması gerektiğine inanıyorum.

Bir 1x3 öğeyi sığdırmaya çalışmanın birden fazla çözümü için bir resim:

resim açıklamasını buraya girin

Oklar çözümlerden sadece birini gösterir, ancak bakarsanız birden fazla bulacaksınız. Nihayetinde otomatik sıralama yapmıyorum ama bir çözüm bulup uyguluyorum.

Üzerinde zaman geçirirsem, bunu çözmenin bir yolunu bulacağım, ama en iyi yol bu olmayacak, eliniz yerine ayaklarınızla bir araba tekerleği tutmak gibi! XD Ya da diziler gerektiren bir sorunu çözmeye çalışmak gibi, ama onların varlığının henüz farkında değilsiniz! Peki buna doğru yaklaşım nedir?

Yorumdan Güncellemeler

@Stephen Alogs'ta gerçekten guru değilim, 'sırt çantası' ve @BlueRaja - Danny Pflughoeft bir 2D kutu ambalaj algo'dan bahsettiniz. Bir şekilde ilişkili / aynı mı? - Buna nasıl yaklaşmam gerektiğiyle ilgili hala kafam karıştı.

Ve evet zaten bir "sezgisel" kullanıyorum ama gerçekten olduğumu bilmiyordum: D mevcut ilk yuvayı bulur ve öğenin oraya uyup uymadığına bakın.

Örneğin 2x2 ve 1x4 öğeleri var, çünkü onlar aynı hacimli, ancak farklı şekiller ve sonraki öğelerin geri kalanı üzerinde nasıl farklı bir etkisi. YANİ... :/

Bu videoyu izledim , tam paketleme fikrini gerçekten beğendim, ancak envanter 2D olduğu için nasıl devam edeceğini merak ediyorum. Burada bin ambalajın anahtar olduğundan bile emin değilim, çünkü birden fazla çantaya sahip olabileceğim doğru, ama oyunumuzda sadece bir çanta olacak. Bu yüzden, öğeleri 'bir' torbaya yerleştirmek meselesi ve bundan daha fazlası değil. Yani bu vid'deki örnekler (borular ve otobüsler) benim sorunumla gerçekten uyuşmuyor. Ayrıca bu sırt çantası şey hakkında bazı şeyler izledim, 'değer' öğeler / envanter ile nasıl ilişkili olduğunu görmedim, ama sanırım 'ağırlık' toplulık ile aynı, emin değilim.


7
Bu, NP-Complete olan 2D kutu paketleme. Yani, tüm öğeleri sığdırabileceğinizi söyleyecek herhangi bir algoritma verimsiz olacaktır (en kötü durumda). Yine de bazı oldukça iyi yaklaşım algoritmalarını bulabilirsiniz.
BlueRaja - Danny Pflughoeft

Tam da bu yüzden (bu günlerde daha yaygın olan) öğe başına bir slot türü envanter modeline karar verdim. Keşke senin için bir çözüm
bulsaydım

@ BlueRaja-DannyPflughoeft Öğelerin belirli şekillerle sınırlı olması durumunda basit / etkin bir algoritma olup olmadığını merak ediyorum.
congusbongus

Şekilleri sınırlamak karmaşıklığı azaltmaz, sadece düşünmeyi kolaylaştırır, böylece karmaşıklığın ele alındığını düşünürsünüz, afaik.
Patrick Hughes

@VeXe Üzgünüz Sorunuzdaki güncellemeyi kaçırdım. Kutu ambalajı ve sırt çantası aynı değildir. Ancak her ikisi de paketleme sorunudur. Durumunuzdaki 'değer', envanter nesnelerinizin şekli ve boyutudur.
Stephen

Yanıtlar:


8

Bu sırt çantası sorununun bir çeşididir. Danny Pflughoeft'in bahsettiği gibi NP-Complete. Doğru hatırlıyorsam, doğrusal zamanda çözülemeyeceği anlamına gelir.

Ancak bunu birkaç adımda çözmeye çalışabilirsiniz. Temelde bir sıralama problemi.

Ben her öğenin 'hacim' hesaplayarak başlayacaktı: bu birkaç şekilde hesaplanabilir:

  • hacimlilik = maks (uzunluk, genişlik);

  • hacimlilik = uzunluk * genişlik

  • hacimlilik = sqrt (uzunluk * genişlik)

Ardından en yüksek puanı alan öğeleri envantere koymaya başlayın. Muhtemelen daha sonra kalan alana sığmayacaklardır. Küçük eşyalar her zaman sığacaktır.

Yerleştirme stratejiniz için bir buluşsal yöntem (eğitimli tahmin için süslü bir ad ;-)) gerekir. Sol üstteki ilk boş yuvaya öğeleri sığdırmaya çalışmak gibi bir şey.

Diablo II envanter sıralama stratejisi sanırım biraz benzer çalıştı. Kılıçlar ve mızraklar gibi şeyler sol üstte, sonra kıyafetler ve zırh, sonra kovalayıcı vb.

Bunu gerçekten denemeniz ve yeterince makul olana kadar algoritmayı (farklı hacim hesaplaması, farklı sezgisel) düzeltmeniz gerektiğini düşünüyorum.


1
NP-complete, karmaşıklığı polinomdan daha yüksek bir dizi problemdir. Nispeten küçük bir envanter için (söyleyebileceğim binlerce öğeden az :)) üstel algoritma bile oldukça hızlı çalışır, çünkü bu tür bir algoritmanın bir adımı çok az zaman alır. Yine de fikrinizi kullanmak, dinamik bir programlama algoritması uygulamaktan yeterince iyi ve kolay olmalıdır -> +1
MartinTeeVarga

upvote için teşekkürler. Evet, envanter potansiyel olarak sonsuz olmamalı, bu nedenle üstel algoritmalar iyi çalışmalı ^^
Stephen

@ sm4: Bin kişi NP-Complete problemleri için muazzam bir sayıdır. Unutmayın, bu problemler O (2 ^ n) - sadece 2 ^ 64 bile hesaplamaya olanaksız!
BlueRaja - Danny Pflughoeft

3

Haha, @ Yardımcı olan herkes teşekkürler. Sonunda çözmeyi başardım. Temelde yaptığım şey:

IEnumerator AddItem_Sorted (Item item)
  1. Önemsiz koşul: öğenin sığması için min nRequiredSlots'a sahip olup olmadığımızı kontrol edin, eğer varsa, devam edin ...
  2. tüm çantayı boşaltacağız - eşyaları bir yer tutucuya (listeye falan) koymak
  3. istenen öğeyi sığabileceği ÇOK son yuvaya / yere ekleyin, yatay şekilde olduğundan emin olun
  4. ilk uyum azalan algo kullanarak geri kalan öğelerimizi ekleyeceğiz
  5. ekleme sırasında, eklediğimiz dizini (bir sonraki kullanılabilir alanın dizini) hatırlamak için dinamik programlama (notlama) kullanacağız
  6. tüm ekleme başarıysa, istediğimiz öğeye uymayı başardık ve bir şekilde çantayı sıraladık - büyükten küçük öğelere
  7. tüm öğeleri ekleyemezsek, bu çözülebilir bir durum değildi, bu yüzden çantayı önceki durumuna getirmeliyiz
  8. Bunu yapmanın bir yolu, (aklımın yüzeyinden çıktı), tüm bu karşıtlıktan önce çantanın durumunu kopyalamaktır ve sonra başarısız olursa, önceki duruma ya da daha iyisine, Torbanın boşaltılması durumunda, her öğenin nerede olduğunu ezberleriz, böylece op başarısız olursa, onları geri alırız - AddItem (öğe, dizin) kullanarak önceki dizinlerinde :)
  9. tüm bu süreç zaman alabilir, bu yüzden güzel verimi kullanarak yükü ayrı karelere bölebiliriz :)
  10. YAPILDI ! \ m / (@ ~ 9: 00)

GÜNCELLEME:

  1. Eklenen tüm öğelerin indekslerini saklayan bir dizi yaptım, bu şekilde gidip benim için dolu olan yuvaları aramam gerekmiyor - büyük bir artış.

  2. Son yuvaya eklemeye gerek yok, aslında bazen bu şekilde çalışmayabilir, istenen öğeyi diğer öğelerin geri kalanına ekledim ve onlarla sıraladım.

Videodan da görebileceğiniz gibi, optimize edilmesi biraz gerekiyor, sıralama mükemmel değil, tam kutu ambalajı kullanmak istiyorum, ancak zaten performans açgözlü. Herhangi bir optimizasyon önerisine açığım, tekrar teşekkürler :)


Rica ederim! :) Bin ambalajından bahsettiği için BlueRaja - Danny Pflughoeft'a, büyüklük fikri için @Stephen'e ve dinamik programlama dersi için Richard Buckland'a ve tüm derslere teşekkür etmek istiyorum.
vexe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.