读书人

这种算法有人写过吗?解决办法

发布时间: 2013-07-09 09:50:47 作者: rapoo

这种算法有人写过吗?
问题是这样的:
有这样一种任务关系:A->C,B->C,C->E,D->E,F
每个字母代表一个任务,每个任务可能有前置任务,如C的前置任务是A和B,即完成A和B才能开始C,C和D完成才能开始E,A和B和F没有前置任务,可以立即开始,F是一个单独的任务,没有前置也没有后续。

目标:
求一种算法,可以按依赖关系执行每个任务,不允许重复执行。(遍历的循环次数越少越好)

假设任务定义为:
string [] task={A,B,C,D,E,F}
关系定义为:
string [] link {{A,C},{B,C},{C,E},{D,F}}//{A,C}为一条连线,表示A->C。F没有连线。

想了1天,没写出来,希望各位能头脑风暴一下帮我想想!先谢谢了!
[解决办法]
根据关系定义生成树,遍历节点,有子节点就继续往下找,没子节点就执行,然后删除该子节点,父节点继续找子节点,循环递归,直到所有树的所有节点都被没了。
[解决办法]
http://bbs.csdn.net/topics/390444459
[解决办法]
工作流合并也并不复杂,有些所谓的“算法”太繁琐了。

比如说一开始可以执行A,也需要并发执行B,也执行F,那么就并发吧。毕竟它们没有前置条件。

当然你可以加锁,使得一次只能有一个任务被执行。从而并发模型下的任务,其实仍然是“排队”进入管理区被执行的。只不过,在并发的思路下,到底是先执行A还是先执行B还是先执行F,这个完全不去计较。是这个意义上的并发。

然后凡是汇聚节点,其节点处理的前提条件是能够搜索到“所有前置节点都处于完成状态了”,才能执行。因此A或者B哪一个先执行完毕了,并不会让C执行,而是丢弃此路径。但是最后一个执行完毕的(B或者A)会让C执行。

一个任务一旦没有后续节点了,也就丢弃次路径。因此节点E和节点F执行完毕了,因为没有适配的后续节点,丢弃后续路径,也就彻底结束了这两个工作流。
[解决办法]

引用:
Quote: 引用:

根据关系定义生成树,遍历节点,有子节点就继续往下找,没子节点就执行,然后删除该子节点,父节点继续找子节点,循环递归,直到所有树的所有节点都被没了。

这种二叉树的遍历算法很复杂啊,能否给点伪代码?

简单的写了个

class Program
{

class taskNode
{
public bool isWorkCompleted { get; set; }
public string taskname { get; set; }
public List<taskNode> Children { get; set; }

public taskNode(string name)
{
taskname = name;
Children = new List<taskNode>();
}

public void Work()
{
if (Children.Count() > 0)
{
foreach (taskNode child in Children)
{


if (!child.isWorkCompleted)
child.Work();
}
Console.WriteLine("{0} is working!", this.taskname);
this.isWorkCompleted = true;
}
else
{
Console.WriteLine("{0} is working!", this.taskname);
this.isWorkCompleted = true;
}
}
}

static void Main(string[] args)
{
Program program = new Program();
program.start();
}

void start()
{
string[] task = { "A", "B", "C", "D", "E", "F" };
string[] link = { "A,C", "B,C", "C,E", "D,E", "F" };
Dictionary<string, taskNode> taskDic = task.Select(x => new taskNode(x)).ToDictionary(x => x.taskname, x => x);
List<taskNode> taskList = CreateTaskList(taskDic, link);
startTask(taskList);
}

List<taskNode> CreateTaskList(Dictionary<string, taskNode> tasklist, string[] link)
{
int count = link.Count();
if (count > 0)
{
for (int i = 0; i < count; i++)
{


string[] tasknames = link[i].Split(',');
if (tasknames.Count() > 1)
{
tasklist[tasknames[1]].Children.Add(tasklist[tasknames[0]]);
}
}
}
return tasklist.Values.ToList();
}

void startTask(List<taskNode> taskList)
{
while (taskList.Count > 0)
{
if (taskList[0].isWorkCompleted)
{
taskList.RemoveAt(0);
}
else
{
taskList[0].Work();
taskList.RemoveAt(0);
}
}
Console.ReadKey();
}
}

读书人网 >C#

热点推荐