private List <Member> Djikstra(List <Member> initMembers, int starterNum, int dinnerNum, int dessertNum, int numnerOfMembersPerDateAss1) { List <Node> OPEN = new List <Node>(); List <Node> CLOSE = new List <Node>(); int groupsizeStarter = starterNum % numnerOfMembersPerDateAss1 == 0 ? 2 : (int)Math.Floor((double)((dinnerNum + dessertNum) / starterNum)); int groupsizeDinner = dinnerNum % numnerOfMembersPerDateAss1 == 0 ? 2 : (int)Math.Floor((double)((starterNum + dessertNum) / dinnerNum)); int groupsizeDessert = dessertNum % numnerOfMembersPerDateAss1 == 0 ? 2 : (int)Math.Floor((double)((dinnerNum + starterNum) / dessertNum)); int highestZ = 0; int z = 0; int id = 0; int goal = initMembers.Count * 2; int backupcost = 500; Node backupNode = new Node(0, 0, z, initMembers, new List <Tuple <int, int> >(), 500); Node currentNode = new Node(0, 0, z, initMembers, new List <Tuple <int, int> >(), 500); OPEN.Add(currentNode); while (true) { if (OPEN.Count > 0 && currentNode.datesFound.Count != goal) { currentNode = getNodeWithLowestCost(OPEN); OPEN.Remove(currentNode); } else if (currentNode.datesFound.Count != goal) { currentNode = getNodeWithLowestCost(CLOSE); Debug.WriteLine("Ops"); currentNode.cost = 10000; } if (OPEN.Count > 8000) { OPEN = new List <Node>(); } List <Member> members = currentNode.members; if (currentNode.datesFound.Count == goal) { Debug.WriteLine("Z: " + currentNode.z); Debug.WriteLine("Allready met: " + currentNode.allreadyMet); Debug.WriteLine("Association error: " + currentNode.associationCost); Debug.WriteLine("Cost: " + currentNode.cost); currentNode.members.ForEach(p => p.allReadyMet.ForEach(l => Debug.WriteLine(p.ID + ": " + l))); return(currentNode.members); } OPEN.Remove(currentNode); int numerOfmembers = members.Count; for (int i = 0; i < numerOfmembers; i++) { List <Member> membersClone = members.Clone(); if (membersClone[i].allDatesFound()) { continue; } List <Tuple <int, int> > dates = new List <Tuple <int, int> >(currentNode.datesFound); int cost = 0; int allreadyMet = 0; int associationcost = 0; for (int j = 0; j < numerOfmembers; j++) { bool allreadyRegistered = currentNode.datesFound.FirstOrDefault(n => n.Item1 == i && n.Item2 == j) != null; if (allreadyRegistered || membersClone[i].allDatesFound()) { continue; } int groupsize = 2; if (membersClone[j].duty == "starter") { groupsize = groupsizeStarter; } else if (membersClone[j].duty == "dinner") { groupsize = groupsizeDinner; } else if (membersClone[j].duty == "dessert") { groupsize = groupsizeDessert; } int release = 0; int whenToIncreaseGroupsize = 2 * numerOfmembers - groupsizeDinner * dinnerNum - groupsizeDessert * dessertNum - groupsizeStarter * starterNum; if (whenToIncreaseGroupsize == 0) { groupsize = (goal - dates.Count) <= (numerOfmembers % (groupsize + 1)) * 2 ? groupsize + 1 : groupsize; } else { groupsize = (goal - dates.Count) <= whenToIncreaseGroupsize + release ? groupsize + 1 : groupsize; } bool possibleMatch = findMatch(membersClone[i], membersClone[j], groupsize); if (!possibleMatch) { continue; } Tuple <int, int> date = new Tuple <int, int>(i, j); dates.Add(date); int[] errorAndCost = calculateCost(membersClone[i], membersClone[j], goal, (goal - dates.Count), associationcost); cost = cost + errorAndCost[0]; allreadyMet = allreadyMet + errorAndCost[3]; associationcost = associationcost + errorAndCost[2]; registerDate(membersClone[i], membersClone[j], membersClone); } int datecount = dates.Count; Node currentNeighbour = new Node(i, datecount, id, membersClone, dates, cost + associationcost); currentNeighbour.allreadyMet = currentNode.allreadyMet + allreadyMet; currentNeighbour.associationCost = currentNode.associationCost + associationcost; if (cost < currentNode.cost) { OPEN.Insert(0, currentNeighbour); //Debug.WriteLine("Cost: " + cost + ", Z: " + datecount); id++; } else if (datecount >= highestZ && cost < backupcost) { if (datecount > highestZ) { //CLOSE = new List<Node>(); highestZ = datecount; } CLOSE.Add(currentNeighbour); backupcost = cost; } } } }