这是一个纯粹的设计问题。
我想把一个不错的教育“游戏”Brain移植到Java。在这个游戏中,你设计了由三个元素组成的神经网络:神经元,节点和突触。神经元用于对其输入信号进行某种处理以产生期望的输出;它可以与其他神经元/节点连接(连接是单向的和加权的)。我们可以考虑节点可以作为连接点-它们也可以连接到其他神经元/节点(这些连接也是单向的和加权的),但是我们的权重不能改变输入连接的权重。突触是这两种元素之间的联系。总之:神经元和节点有输入和输出(对其他神经元/节点),它们进行一些输入->输出处理。
问:现在,您将如何设计这个类的结构?这是我迄今“制作”的素描:设计截图
因为“连接两个连接(即神经元/节点)”操作有三项职责(添加突触、将输出添加到连接A、添加输入以加入B),所以我决定将其作为静态方法放在控制器类中。当然,我可以避免元素之间的双向关系:我不需要跟踪输出,只是输入,但是还有一些其他的限制。每个连接只能有8个I/O,所以每次添加连接时,我都必须遍历所有的突触,以查看是否还存在添加它的位置。在这种情况下(这个游戏)你不会有太多的连接,所以它不会影响性能,但我想知道如何处理这种情况在一般情况下。
因为这是这个项目的整个逻辑的基础,所以我想把它做好。热烈欢迎各界人士提出建议;)
发布于 2013-06-10 05:26:25
类设计中的双向关联是可能的,但它们总是要付出高昂的代价,你应该知道,而且必须愿意付出代价。
一般来说,我喜欢避免双向关联,唯一的例外是性能。正如您已经提到的,在不知道其他方向的情况下,您可能必须遍历所有其他对象以找到正确的对象(或者在您的情况下计算它们)。这可能是昂贵的,但它也可以通过其他方式,而不是建立双向关系(f.ex )。具有缓存的关联类)。
因为你很可能会得到数以百计的突触,在它们上循环来检查某些东西是否是可连接的是不好的,所以我认为你的双向关联可能是一个有效的选择。这取决于你对这场游戏到底是什么意思。
不会有太多人脉。
如果你能负担得起这个循环,那么我建议你这样做。如果您确实保持双向关系,您将不得不非常小心地保持您的模型一致。每次您触摸这些关联之一时,都必须确保以原子方式更新整个模型,使其再次保持一致。
很难确保所有涉及的对象/关联都正确地反映了每一个修改,但是一旦添加了并发性,它就会变得更加丑陋,因为您永远不希望另一个线程看到模型处于中间状态,在中间状态中只添加/删除了一个方向。
即使你使用像Hibernate这样的工具来支持双向关系,你也会得到其他的权衡。例如,如果将Hibernate与急切的获取相结合,那么无论何时只要调用一个join,您很可能最终都会从数据库读取整个神经网络。这都是要付出的代价的一部分。
还要注意的是,省略双向关系并添加一些帮助类来跟踪输入/输出的数量并不是个好主意。首先,您将一致更新模型的责任划分为主模型之外的内容,其次,需要添加任何一种方法来保持事物的一致性。您可能会接受糟糕的循环性能,或者您可以通过一些缓存的查找来合理地改进它,这些查找更容易更新,并且不一定是完整的。
概括地说:双向关系是可能的,但只有当你不能以一种可行的方式解决它们的缺位时,才应该考虑。
https://softwareengineering.stackexchange.com/questions/200949
复制相似问题