0

I have a genObjectList of generic objects and an openList of generic objects which still needs to be used. Some of the generic objects depend on each other. So only generic objects where all of its predecessors were already used could be used. The implementation I use is the following:

var genObjectList = // get the generic objects from somewhere
var openList = new List<GenObject>(genObjectList);
var closedList = new List<GenObject>();
var rand = new Random();

while (openList.Count != 0)
{
                var candidateList =
                    openList.FindAll(
                        t => t.Predecessors.Where(p => genObjectList.Contains(p)).Intersect(closedList).Count() == t.Predecessors.Count(p => genObjectList.Contains(p)));

                var choosenGenObject = candidateList[rand.Next(0, candidateList.Count)];

                openList.Remove(choosenGenObject);
                closedList.Add(choosenGenObject);

    // Do something with the generic object
}

The part to find the candidateList seems to be very inefficient even if the genObjectList contains only 300 entries.

I'm looking for a better implementation to achieve the same behaviour. Any ideas?

Edit: To clarify the misleading use of Task: The question is not about c# tasks and their methods, but on generic objects which have precedence constraints and how to handle them. I edited the post to make this clear.

Edit2: The advise to use topological sorting is the right way. However I'm looking for sth. which could be described as 'non deterministic topological sorting'. With the depth first search implementation from e.g. QuickGraph one always gets the same topological sorting even if it's not unique. I'm looking for an implementation which uses a random number as tie-breaker and thus has the chance to create all topological sorting's.

user2653422
  • 1,095
  • 1
  • 12
  • 18
  • If you want Task B to start after Task A finishes, you should do `var taskC = taskA.ContinueWith(taskB)`, and Task C then includes both tasks, in order. Then you just have a list of tasks to run and a list of running tasks (for no reason?). Another thing you might wanna look into (for general knowledge, really) is `BlockingCollection` - pretty useful for such use cases. – SimpleVar Aug 16 '15 at 16:51
  • @YoryeNathan Thank you for the response. I didn't mean c# tasks and synchronizing them. The question is more about a general way to work with objects which have precedence constraints. Sorry, I should have been more precise in the question. – user2653422 Aug 16 '15 at 17:10
  • Sounds like you want a [topological sort](https://en.wikipedia.org/wiki/Topological_sorting) aka a partial order sort. See for example [How to sort depended objects by dependency](http://stackoverflow.com/questions/4106862/how-to-sort-depended-objects-by-dependency) – dbc Aug 16 '15 at 17:26
  • You have a tree. So if you make a list of leaf nodes and check leaves and their parents you would reduce the search time. – jdweng Aug 16 '15 at 18:05
  • @dbc I edited my question. The topological sorting is the right way, but I'm looking for an implementation which uses a random tie-breaker. – user2653422 Aug 17 '15 at 07:08
  • I don't know QuickGraph, but it *probably* preserves the incoming relative order of nodes for nodes at the same dependency depth. If that's correct, an extremely simple way to get what you want would be to do a [fisher yates shuffle](http://www.dotnetperls.com/fisher-yates-shuffle) before the topological sort to randomize the input order. – dbc Aug 17 '15 at 20:27

0 Answers0