将碰撞的物体合并为一个

时间:2015-10-02 17:09:17

标签: algorithm collision

我正在研究Javascript中的一些物理内容,并且基本上想要将碰撞的主体作为一个来处理。

我得到了一系列发生的碰撞,碰撞包括两个身体,身体A和身体B.

让我们说六次碰撞发生,身体之间发生碰撞:

  1. X和Y
  2. Y和Z
  3. C和D
  4. E和F
  5. F和H
  6. G和H
  7. 现在我想将以某种方式连接的所有实体合并为一个实体。我希望这些合并的主体在列表中。例如,在这种情况下,我想要一个如下所示的列表:

    1. X,Y和Z(因为X与Y碰撞,Z与Z碰撞)
    2. C和D(因为C与D相撞)
    3. E,F,G和H(因为E与F碰撞,F与H碰撞,G与H碰撞)
    4. 现在我非常确定那里有一些我需要的算法,我只是不知道在哪里看,我自己想出来解决这个问题。< / p>

2 个答案:

答案 0 :(得分:1)

你将如何在现实生活中做到这一点?

我想我会阅读每条规则。对于每条规则,我都要连接这两个规则。我最终得到的是一系列blob。然后我可以遍历每个图形以获得每个图形中的节点列表。每个&#34;连接组件&#34;将是一个&#34; blob&#34;。将此算法形式化可能会产生以下结果:

// make the graph of connected components
nodes = map<symbol, pair<symbol, list<symbol>>>
for each (a, b) in rules do
    if nodes[a] is null then nodes[a] = node(a, [b])
    else nodes[a].connections.append(b)

    if nodes[b] is null then nodes[b] = node(b, [a])
    else nodes[b].connections.append(a)
loop

blobs = map<symbol, list<symbol>>
for each (a, b) in rules do

    firstNode = nodes[a]
    // do a DFS/BFS search starting from firstNode to find
    // all nodes in the connected component. whenever you
    // follow a link from a node, remove it from the node's
    // list of links. this prevents ever searching from that
    // node again since we know what component it's in already
    // add each node to the list of symbols in blobs[a]

loop

在第一个循环中,我们读取每个规则一次,然后执行一定量的工作,因此规则数量是O(n)时间。它将为每个规则存储两个连接,因此在规则数量方面存储O(n)。

在第二个循环中,我们查看每个规则,并为每个规则的LHS符号执行DFS或BFS。但请注意,搜索只会遍历任何边缘一次,因此这是规则数量的O(n)时间。我们最终得到一些blob集合,其列表将是不超过规则数量的符号集合,因此它也是O(n)存储。

因此我们有一个O(n)时间,O(n)空间复杂度算法来确定斑点。渐渐地说,我们能做得更好吗?显然,我们需要查看所有n个规则,因此时间复杂度是最佳的。还要注意,对于这个问题的任何解决方案必须说明符号最终属于哪个符号,因此简单地在输出磁带上写下答案需要O(n)空间。所以这也应该是最佳的。

答案 1 :(得分:1)

如果您有一个包含所有对象的ADT(在本例中是一个地图),并且您保留父ID以跟踪对象碰撞,则可以在恒定时间内处理每个碰撞+合并。

// setup
var X = {id: 1, name:'X'};
var Y = {id: 2, name:'Y'};
var Z = {id: 3, name:'Z'};
var C = {id: 4, name:'C'};
var D = {id: 5, name:'D'};
var E = {id: 6, name:'E'};
var F = {id: 7, name:'F'};
var G = {id: 8, name:'G'};
var H = {id: 9, name:'H'};
var all = { 1:X, 2:Y, 3:Z, 4:C, 5:D, 6:E, 7:F, 8:G, 9:H };

// method to merge collided objects together
function collision(obj1, obj2) {
    var p1 = obj1.parent;
    var p2 = obj2.parent;
    if(p1 === undefined && p2 === undefined) {
        obj1.parent = obj1.id;
        obj2.parent = obj1.id;
        obj1.name += obj2.name;
        delete all[obj2.id];
    } else if(p1 !== undefined && p2 === undefined) {
        obj2.parent = obj1.parent;
        all[obj1.parent].name += obj2.name;
        delete all[obj2.id];
    } else if(p1 === undefined && p2 !== undefined) {
        obj1.parent = obj2.parent;
        all[obj2.parent].name += obj1.name;
        delete all[obj1.id];
    } else if(p1 !== undefined && p2 !== undefined && obj1.parent !== obj2.parent) {
        if(all[obj1.parent] !== undefined) {
            all[obj1.parent].name += all[obj2.parent].name;
            delete all[obj2.parent];
        } else if(all[obj2.parent] !== undefined) {
            all[obj2.parent].name += all[obj1.parent].name;
            delete all[obj1.parent];
        }
    }
}

// test
console.log(JSON.stringify(all));
collision(X, Y);
collision(Y, Z);
collision(C, D);
collision(E, F);
collision(F, H);
collision(G, H);
console.log(JSON.stringify(all));
collision(X, E);
console.log(JSON.stringify(all));
  
    

{ “1”:{ “ID”:1, “名称”: “X”}, “2”:{ “ID”:2 “名称为”: “Y”}, “3”:{” ID “:3”,名称为 “:” Z “}”,4 “:{” ID “:4”,名称为 “:” C “},” 5 “:{” ID “:5”,名称 “:” d “},” 6 “:{” ID “:6中,” 名称 “:” E “},” 7 “:{” ID “:7,” 姓名 “:” F “},” 8 “:{”标识 “:8中,” 名称 “:” G “},” 9 “:{” ID “:9”,名称为 “:” H“}}

         

{ “1”:{ “ID”:1, “名称”: “XYZ”, “亲本”:1} “4”:{ “ID”:4 “名称”: “CD”,”父 “:4},” 6 “:{” ID “:6中,” 名称 “:” EFHG”, “亲本”:6}}

         

{ “1”:{ “ID”:1, “名称”: “XYZEFHG”, “亲本”:1} “4”:{ “ID”:4 “名称”: “CD”,”父“:4}}