private void KStoreCalc(int k, List <Store> storeList, List <Item> itemList) { if (k == 1) { OneStoreCalc(storeList, itemList); } else { // The stores are sorted by how many of the first item they have, and then by 2nd, 3rd, and 4th, etc. // Thus a valid solution must contain one of the first store in the list. Once a store in the list has 0 of the first item // the rest will have 0 so it makes no sense to consider them as the first store since the rest of the store can't have that item // either, so no solution will ever be found. This idea can be applied to the second store, etc., although it is more complicated. // So here we compute the last index of the first (up to) 5 items on the list. The last index of the 5th should be the final index. // The last index of the rest might be smaller. I haven't figured out exactly how to use this information for items 2-5 yet since // it gets a little more complicated. // CAC, 2015-06-25 int numToTrack = itemList.Count > 5 ? 5 : itemList.Count; int[] lastnonzeroindex = new int[numToTrack]; for (int item = 0; item < numToTrack; item++) { int j = storeList.Count - 1; while (j >= 0 && storeList[j].getQty(itemList[item].extid) == 0) { j--; } lastnonzeroindex[item] = j; } //Debug.WriteLine("LastNonZero: " + intArrayToString(lastnonzeroindex)); // Need to add one to the second argument since it is exclusive. Parallel.For(0, lastnonzeroindex[0] + 1, store1 => { if (calcWorker.CancellationPending || stopAlgorithmEarly) { return; } // Do the next k stores have enough of the first element? // If not, none of the rest will so quit. CAC, 2015-06-25 int totalQtyFirst = 0; int lastToCheck = Math.Min(storeList.Count - 1, store1 + k); for (int i = store1; i < lastToCheck; i++) { totalQtyFirst += storeList[i].getQty(itemList[0].extid); } if (totalQtyFirst < itemList[0].qty) { return; } int[] start = new int[k]; int[] end = new int[k]; for (int i = 0; i < k; i++) { start[i] = store1 + i; end[i] = storeList.Count - k + i; // The version below doesn't work. We have to use a different method of omitting more // possibilities based on lastnonzeroindex[i] for i>0. Still need to think about this. // I'm leaving it here commented out to remind me that I tried it and realized // that it isn't correct. // CAC, 2015-07-02. //end[i] = (i < numToTrack) ? lastnonzeroindex[i] : storeList.Count - k + i; } end[0] = store1; KSubsetGenerator subs = new KSubsetGenerator(storeList.Count, start, end); while (subs.hasNext()) { if (calcWorker.CancellationPending || stopAlgorithmEarly) { break; } int[] current = subs.next(); Interlocked.Increment(ref longcount); bool fail = false; foreach (Item item in itemList) { int totalQty = 0; for (int i = 0; i < k; i++) { totalQty += storeList[current[i]].getQty(item.extid); } if (totalQty < item.qty) { fail = true; break; } } if (!fail) { List <string> storeNames = new List <string>(); for (int j = 0; j < k; j++) { storeNames.Add(storeList[current[j]].getName()); } addFinalMatch(storeNames); } } Progress(); }); } }
private static void Main() { foreach (List <int> ints in SubsetGenerator.BacktrackingGenerator(new List <int> { 1, 2, 3, 4 }, 0)) { foreach (int i in ints) { Console.Write(i + " "); } Console.WriteLine(); } foreach (IEnumerable <int> enumerable in SubsetGenerator.LexicalGenerator(new List <int> { 4, 3, 2, 1 })) { foreach (int i in enumerable) { Console.Write(i + " "); } Console.WriteLine(); } Console.WriteLine("---------"); foreach (int[] ints in KSubsetGenerator.BacktrackingGenerator(5, 4)) { foreach (int i in ints) { Console.Write(i + " "); } Console.WriteLine(); } KSubsetGenerator.LexicalGenerator(5, 4); Console.WriteLine("---------"); new PermutationGenerator().BacktrackingGeneration(new[] { 1, 2, 3, 4 }.ToArray(), 0, 3); Console.WriteLine("---------"); //foreach (int[] subset in new PermutationGenerator().LexicalGeneration(new[] { 1, 2, 3, 4 })) //{ // foreach (int element in subset) // { // Console.Write(element + " "); // } // Console.WriteLine(); //} var arr = new[] { 1, 2, 3, 4 }; foreach (int i in arr) { Console.Write(i + " "); } Console.WriteLine(); while (!PermutationGenerator.NextPermutation(arr)) { foreach (int i in arr) { Console.Write(i + " "); } Console.WriteLine(); } }