首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何基于关系矩阵实现逻辑

如何基于关系矩阵实现逻辑
EN

Stack Overflow用户
提问于 2012-04-28 03:28:55
回答 2查看 544关注 0票数 1

假设我有一个对称的关系矩阵,如下所示:

除了每个“结果”都是一小段代码。

我的场景是:我有一堆相互“碰撞”的Entity对象。每个实体都有一个枚举值( CollisionType )。在设计中,存在一个关系矩阵,它描述了当不同的CollisionTypes彼此相遇时实体的行为。

我想知道:我如何表示关系,并在它上面实现逻辑,以一种干净和高性能的方式,很容易添加新的CollisionTypes?在我看来,它看起来有点像2D Switch语句。

示例(差)解决方案:

代码语言:javascript
复制
void CollideEntities( Entity e1, Entity e2 ) {
    CollisionType t1 = e1.GetCollisionType();
    CollisionType t2 = e2.GetCollisionType();

    // perform basic logic based on t1 & t2
    if ( (t1 == COL_SOLID && t2 == COL_SQUISHY) || (t1 == COL_SQUISHY && t2 == COL_SOLID) ) {
        // do stuff..
    } else if ( (t1 == COL_SOLID && t2 == COL_DAMAGE) || (t1 == COL_DAMAGE && t2 == COL_SOLID) ) {
        // do other stuff..
    } // and so on...

}

许多潜在的解决方案对我来说是显而易见的,但没有一个给我留下特别干净或高效的印象,也没有一个容易添加新的类型到...

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-28 04:00:00

试试这个:

代码语言:javascript
复制
#include <vector>
#include <iostream>

class Symmetric_matrix {
  private:
    size_t size1;
    // The next should be <bool> rather than <int>,
    // but the writer's compiler objects.
    std::vector<int> outcomes;
  public:
    size_t size() const { return size1; }
    int &operator()(const size_t i, const size_t j) {
        const size_t a = i <= j ? i : j;
        const size_t b = i <= j ? j : i;
        return outcomes[(b*(b-1))/2 + a];
    }
    Symmetric_matrix(const size_t size0)
      : size1(size0), outcomes((size()*(size()-1))/2, false) {}
};

// Here is a test driver.
int main() {
    Symmetric_matrix sm(5);
    sm(0, 1) = true;
    sm(0, 3) = true;
    sm(1, 3) = true;
    sm(2, 3) = true;
    sm(3, 4) = true;
    std::cout << "buyer-approver      : " << sm(0, 2) << "\n";
    std::cout << "approver-buyer      : " << sm(2, 0) << "\n";
    std::cout << "approver-requisition: " << sm(2, 3) << "\n";
    std::cout << "requisition-approver: " << sm(3, 2) << "\n";
    return 0;
}

你的问题很有趣。正如您所观察到的,只需要存储矩阵的上三角形或下三角形,而不是两者都存储。

但你会问,(b*(b-1))/2是关于什么的?答:它来自一个奇怪的算术事实:0+1+2+ ... + (b-1) == (b*(b-1))/2 (试试)。

当然,我的示例代码可以做一些改进。首先,由于某些原因(需要建议),我的代码在使用std::vector<bool>时失败,所以我使用了std::vector<int>作为变通方法。另一方面,它不包括对case i == j的正确处理。然而,它所做的是传达基本技术。您可以自行决定填写详细信息。

(更新:后来我想到了std::vector<bool>失败的原因。它失败是因为std::vector<bool>是以位数组的形式实现的,而单个位不能是左值,因为它没有自己的地址。使用巧妙的编码,通过让operator()()返回某种特殊定义类型的操纵器,可以在不更改main()的情况下巧妙地解决问题,但是如果我们想使用set(),那么定义和使用<bool>成员函数可能是最简单的。)

票数 1
EN

Stack Overflow用户

发布于 2012-04-28 03:33:38

我不会那样做的。我有一个Map,键将在其中查找包含所需行为的Command对象。

另一种可能是访问者模式(也称为“双重调度”)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10356708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档