繁体   English   中英

优化力向图

[英]Optimising a force directed graph

我已经在C#for Unity中基于EpForceDirectedGraph.cs图形编写了一个强制导向的图形实现,但是它只能处理多达1000个节点,低于我所需要的约4000个节点。 我已经看了好几天的代码,但似乎还是看不到能加快它的速度! 看看,任何帮助将不胜感激! 我将这些函数在400个节点上运行85次,以生成正确的图形,这意味着施加力函数在启动过程中正在运行27,000,000次!

请注意,我将WebGL用作构建目标,因此多线程和SIMD可能无济于事,但是我欢迎这些工具的建议。

这些是主要的应用程序功能:

    * @Description     applied coulombs law to determine the push force between 2 points as well as*
    *                  the attraction to center and updating of the velocity and acceleration      *
    *                                                                                              *
    * @parameters      iTimeStep - the time since last frame                                       *
    ************************************************************************************************/
    protected override void applyNodeLaws(float iTimeStep)
    {
        for (int i = 0; i < graph.nodes.Count; i++)
        {
            //applies coulomb's law to each node 
            Point3D point1 = GetPoint(graph.nodes[i]);
            for (int j = 0; j < graph.nodes.Count; j++)
            {
                Point3D point2 = GetPoint(graph.nodes[j]);
                if (point1 != point2)
                {
                    Vector3 d = point1.position - point2.position;
                    float distance = d.magnitude + 0.1f;
                    Vector3 direction = d.normalized;

                    point1.ApplyForce((direction * Repulsion) / (distance * 0.5f));
                    point2.ApplyForce((direction * Repulsion) / (distance * -0.5f));

                }
            }
            //Applies centre attraction
            Vector3 centreDirection = point1.position * -1.0f;
            float displacement = centreDirection.magnitude;
            centreDirection = centreDirection.normalized;
            point1.ApplyForce(centreDirection * (Stiffness * displacement * 0.4f));

            //converts acceleration to velocity
            point1.velocity += (point1.acceleration * iTimeStep);
            point1.velocity *= Damping;
            point1.acceleration = Vector3.zero;
            //applies velocity to position
            point1.position += (point1.velocity * iTimeStep);


        }
    }

   /************************************************************************************************
    * @Description     applied hookes law to determine the spring force between 2 points           *
    ************************************************************************************************/
    protected override void applyHookesLaw()
    {
        for (int i = 0; i < graph.edges.Count; i++)
        {
            Spring3D spring = GetSpring(graph.edges[i]);
            Vector3 d = spring.point2.position - spring.point1.position;
            float displacement = spring.Length - d.magnitude;
            Vector3 direction = d.normalized;

            spring.point1.ApplyForce(direction * (spring.K * displacement * -0.5f));
            spring.point2.ApplyForce(direction * (spring.K * displacement * 0.5f));
        }
    }

最后,我们决定将所有处理工作转移到基于外部AWS的Heroku服务器上。 标注超时时间为40秒,我们可以完成数百万个计算,通常最多需要30分钟才能生成!

我们还实施了基于Octree的节点系统,使我们能够实时运行它!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM