从平面列表创建有向图

时间:2015-04-05 14:52:10

标签: c# algorithm graph dependencies

我想创建图表。我的要求是:

我已经共享了用于安排的资源。

 1,2,3,4,5,7,8,9 

每个都可以组合起来创建节点。

所以我可以拥有这样的节点:

 [1,3],[2],[5,7,6,9] //[...] means that is one node (and can be complex)
                     //[...] is one job which have assigned multiple resources

基本上我需要的是安排在共享资源上运行的依赖和作业。所有这些都是同时发生的,这就是为什么我需要这个树能够迭代作业,在几个线程(例如8个线程)中运行空闲作业,等待作业完成并运行它们的dependand作业。

所以我实现了一个算法来从平面列表中创建图形。这些平面列表如下所示:

    var nodes = new List<IDependencyJobNode>()
    {
        new DependandJobNode(new DependandJob(new List<int> { 1 }, ()=>{})),
        new DependandJobNode(new DependandJob(new List<int> { 2 }, ()=>{})),
        new DependandJobNode(new DependandJob(new List<int> { 1, 5, 4, 8 }, ()=>{})),
        new DependandJobNode(new DependandJob(new List<int> { 2, 3, 7, 9 }, ()=>{})),
        new DependandJobNode(new DependandJob(new List<int> { 8, 2 }, ()=>{})),
        new DependandJobNode(new DependandJob(new List<int> { 5, 7 }, ()=>{})),
        new DependandJobNode(new DependandJob(new List<int> { 5, 8 }, ()=>{})),
    }; 

但是我遇到这种情况的问题

  [1]            [2]
   |              |
   v              v
 [1,5,4,8]     [2,3,7,9]
   |      \        |
   v       \ ------v
  [5,7]          [8,2]
     \            /
      \          /
          [5,8]

节点 [5,8] 将遍历2次,一次从 [1] 开始,第二次从 [2] 开始给我四个父母(父母是不必要的重复)

这是我的实施

public class TreeBuilder
{
    private IEnumerable<IDependencyJobNode> jobs;
    public int Depth { get; private set; }
    private int currentLevel;

    public IDependencyJobNode Root{ get; private set; }

    public TreeBuilder(IEnumerable<IDependencyJobNode> jobs)
    {
        this.jobs = jobs;
        this.Depth = 0;
    }

    public void Create(IDependencyJobNode root)
    {

        var depths = new List<int> ();
        for (int i = 0; i < jobs.Count(); ++i) {
            depths.Add(Insert(root, jobs.ElementAt (i), Depth + 1));
        }

        this.Depth = depths.Max ();

        this.Root = root;
    }

    public int Insert(IDependencyJobNode root, IDependencyJobNode job, int depth){
        var insertAsChild = true;
        for(int i = 0; i < root.Childs.Count(); ++i){
            var rootElement = root.Childs.ElementAt (i);
            if (HasCommonGpio (rootElement, job)) {
                depth = Insert (rootElement, job, depth + 1);
                insertAsChild = false;
            }
        }
        if (insertAsChild == true) {
            job.Parents.Add(root);
            root.AddChild (job);
        }
        return depth;
    }

    private static bool HasCommonGpio(IDependencyJobNode root, IDependencyJobNode job)
    {
        for(int i = 0; i < root.Job.UsedGpio.Count (); ++i){
            for (int j = 0; j < job.Job.UsedGpio.Count (); ++j) {
                if (root.Job.UsedGpio.ElementAt (i) == job.Job.UsedGpio.ElementAt (j)) {
                    return true;
                }
            }
        }
        return HasCommonGpio (root.Childs, job);
    }

    private static bool HasCommonGpio(IEnumerable<IDependencyJobNode> roots, IDependencyJobNode job)
    {
        if (roots == null || !roots.Any ()) {
            return false;
        }
        foreach (var root in roots) {
            if (HasCommonGpio (root, job)) {
                return true;
            }
        }
        return false;
    }
}

我无法解决这个问题,是否有任何通用算法如何实现这些图表并处理这些复杂的案例?我不知道如何让它发挥作用,也许有人会分享一些想法?

0 个答案:

没有答案