自动组织/智能库存系统?


11

在过去的一周中,我一直在使用Unity3D开发清单系统。最初,我在Design3的工作人员那里得到了帮助,但是直到我们分离路径才花了很短的时间,因为我真的不喜欢他们编写代码的方式,它完全没有OOP的味道。

我向前迈出了进一步的一步-物品占用多个插槽,先进的放置系统(物品会尽力找到最合适的位置),本地鼠标系统(鼠标被困在活动行李袋中)等。

这是我工作的演示

我们希望在游戏中拥有一种自动组织功能-而不是自动排序。我们需要此功能,因为我们的库存将是“实时”的-不同于《生化危机1,2,3》等,您可以在其中暂停游戏并在库存中执行操作。现在想象一下,您的自我处于僵尸包围的稠密情况下,没有子弹,环顾四周,发现地面上附近有子弹,因此您去追捕它们并尝试将其捡起,但是它们却没有不适合!您查看您的库存,发现如果您重新组织一些物品,它将很合适!-现在的玩家-在那种情况下没有时间重组,因为他被僵尸包围了,如果他停下来并组织库存以腾出空间(实时记住库存,没有暂停),他会死掉的- 自动执行该操作会很好吗?-是的!

(我相信这已经在《地牢围攻》之类的某些游戏中实现了,因此请确保它是可行的)

例如看这张照片:

自动分类是做什么的

是的,因此,如果您对问题进行自动排序,则会得到空格,但是这很糟糕,因为:1-昂贵:不需要完全排序操作即可释放这些空格,在第一张图片中,只需将红色项目滑到底部到最左边,您会得到与自动排序相同的空间。2-播放器很烦人:“ F告诉你重新订购我的东西吗?”

我不是在问“如何编写代码”,我只是在问一些指导,在哪里看,涉及什么算法?这和图和最短路径有关吗?我希望不要因为我没有设法继续我的大学学习而已:/即使是这样,只要告诉我,我就会学到相关的知识。

请注意,可能有不止一种解决方案。因此,我想我要做的第一件事就是弄清楚情况是否“可以解决”-如果我知道如何确定情况是否可以解决,那么我可以“解决”它。我只需要知道使其“可解决”的条件即可。而且我相信必须有一些算法/数据结构。

这是一张试图容纳1x3物品的多种解决方案的照片:

在此处输入图片说明

箭头仅显示一种解决方案,但是如果您看到的话,会发现多个解决方案。这就是我最终不自动排序而是找到解决方案并应用它的原因。

请注意,如果我花时间在上面,我会想出一种解决方法,但这并不是最好的方法,就像用脚而不是手握住车轮一样!XD或就像尝试解决需要数组的问题一样,但是您还不知道它们的存在!那么什么是正确的方法呢?

评论更新

@Stephen我真的不是Alogs中的专家,您提到了“背包”和@BlueRaja-Danny Pflughoeft提到了2D装箱算法。他们之间有某种联系/相同吗?-我仍然对应该如何处理感到困惑。

是的,我已经在使用“启发式”,但是我真的不知道我是:D它找到第一个可用的插槽,然后查看该项目是否适合该插槽。

我不知道是否可以根据商品的“体积”(我称为nSlotsRequired = nRowsReq * nColsRec)订购商品,因为例如您有一个2x2和1x4的商品,它们的体积相同,但是形状不同,对接下来的其余项目的处理方式会产生不同的影响。所以...:/

我看了这个视频,我真的很喜欢完整的打包想法,但是我想知道如何处理它,因为库存是2D的。我什至不能确定垃圾箱的包装是这里的关键,因为,确实可以有一个以上的袋子,但是在我们的游戏中,它只能是一个袋子。因此,仅需在“一个”袋子中放入物品即可。因此,该视频中的示例(管道和总线)与我的问题并不完全匹配。还看了一些关于背包的事情,我没有看到“价值”与我的物品/库存有何关系,但我猜“重量”与体积大是一样的,不确定。


7
这是2D装箱,即NP完成。因此,任何能告诉您是否可以容纳所有物品的算法都是无效的(在最坏的情况下)。不过,您可以找到一些非常好的近似算法。
BlueRaja-Danny Pflughoeft13年

这就是为什么我决定(现在比较普遍)而不是使用每个项目一个插槽的类型的库存模型的原因。我希望我能为您提供解决方案,我放弃了这个问题...
Ryno

@ BlueRaja-DannyPflughoeft我想知道是否将简单/高效的算法限制在某些形状上?
congusbongus

限制形状并不会降低复杂性,而只是使思考变得更容易,所以您认为复杂性已经得到了解决,afaik。
Patrick Hughes

@VeXe对不起,我错过了您的问题的最新消息。箱包装和背包不一样。但是两者都是包装问题。您的情况下的“价值”是库存对象的形状和大小。
斯蒂芬

Answers:


8

这是背包问题的一种变体。正如Danny Pflughoeft提到的那样,它是NP-Complete。意思是,如果我没记错的话,它不能在线性时间内解决。

但是您可以尝试分几个步骤解决此问题。这基本上是一个排序问题。

我将从计算每个项目的“优势”开始:这可以通过几种方式计算:

  • 蓬松度= max(长度,宽度);

  • 蓬松度=长*宽

  • 蓬松度= sqrt(长*宽)

然后开始将得分最高的项目放到库存中。由于它们很可能以后将无法容纳到剩余空间中。小物品将永远适合。

您需要一种启发式的方法(一种容易理解的名称;-)来制定您的放置策略。诸如尝试从左上角的第一个空闲插槽中放入物品之类的东西。

我认为《暗黑破坏神II》的库存分类策略的运作方式有些相似。诸如剑和长矛之类的东西最终会出现在左上角,然后是衣服和盔甲,然后是袖扣等等。

我认为您真的需要尝试一下并调整算法(不同的体积计算,不同的启发式算法),直到它足够合理为止。


1
NP-完全是一组问题,其复杂度高于多项式。对于相对较小的库存(我会说少于千种物品),即使是指数算法也可以非常快速地工作,因为这种算法的一步只需很少的时间。然而使用你的想法应该是足够好并且比实现动态编程算法更容易- > +1
MartinTeeVarga

赞成。是的,清单应该不应该是无限的,因此指数算法应该可以正常工作^^
Stephen

@ sm4:NP完全问题通常是一千。请记住,这些问题都是O(2 ^ n)-即使只有2 ^ 64在计算上也是不可行的!
BlueRaja-Danny Pflughoeft 2014年

3

哈哈,@帮助的所有人,谢谢。我终于解决了。这基本上是我做的:

IEnumerator AddItem_Sorted (Item item)
  1. 琐碎的条件:检查是否有最小nRequiredSlots项适合放置,如果有,请继续...
  2. 我们将清空所有袋子-将物品放入占位符(列表或其他内容)
  3. 将所需的物品添加到可以容纳的最后一个插槽/位置,确保其水平放置
  4. 使用首次拟合递减算法,我们将添加其余项
  5. 在添加过程中,我们将使用动态编程(记忆化)来记住要添加的索引(下一个可用插槽的索引)
  6. 如果所有添加都成功,那么我们就可以满足想要的物品的需求,并以某种方式对袋子进行分类-从大件到小件
  7. 如果我们不能添加所有项目,则意味着这不是可解决的情况,因此我们必须将包装袋恢复到之前的状态
  8. 一种实现方法(从我的脑海中浮出水面)是在整个操作之前复制袋子的状态,然后,如果失败,我们将在恢复过程中恢复到先前的状态,甚至更好。清空”,我们会记住每个项目的位置,以便在操作失败的情况下,使用AddItem(item,index)-将它们取回之前的位置:)
  9. 这整个过程可能会花费一些时间,所以我们可以使用可爱的yield来将负载分配到单独的帧中:)
  10. 完成!\ m /(@〜9:00)

更新:

  1. 我创建了一个数组,用于存储所有添加项的索引,这样一来,我就不必去寻找占用的插槽让我自由释放-大大提高了性能。

  2. 无需在最后一个插槽中添加,实际上有时可能无法以这种方式工作,我已将所需项目添加到其他项目中,并与其他项目进行了排序。

正如您从视频中看到的那样,它需要进行一些优化,排序并不完美,我想使用完整的装箱打包,但是它已经是性能贪婪的了。我愿意接受任何优化建议,再次感谢:)


别客气!:)我要感谢BlueRaja-Danny Pflughoeft提到垃圾箱包装,@Stephen提出了笨重的想法,Richard Buckland提出了动态编程的讲座,以及所有讲座。
vexe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.