public void Execute() { #region QueryHandle QueryHandler <T_SLOT, T_SLOT_INFOS, T_BRAIN> Q = new QueryHandler <T_SLOT, T_SLOT_INFOS, T_BRAIN>() { m_brain = m_brain, m_inputSlotInfos = m_inputSlotInfos, m_inputSlotCoordinateMap = m_inputSlotCoordinateMap, m_socketCount = m_socketCount, m_socketOffsets = m_socketOffsets, m_socketsMirrors = m_socketsMirrors, m_socketsMirrorsIndices = m_socketsMirrorsIndices, m_moduleCount = m_moduleCount, m_modulesWeights = m_modulesWeights, m_modulesHeaders = m_modulesHeaders, m_modulesNeighbors = m_modulesNeighbors, m_results = m_results, m_nullPairLookup = m_nullPairLookup }; #endregion int sCount = m_inputSlotInfos.Length, nCount = m_modulesNeighbors.Length, count, index, result; Antropy _a; SortAntropy antropyComparer = default; NativeList <Neighbor> contents = new NativeList <Neighbor>(m_socketCount, Allocator.Temp); NativeList <int> candidates = new NativeList <int>(m_modulesNeighbors.Length, Allocator.Temp), slotSocketIndices = new NativeList <int>(m_socketCount, Allocator.Temp), slotIndices = new NativeList <int>(m_socketCount, Allocator.Temp); NativeList <float> weights = new NativeList <float>(m_moduleCount, Allocator.Temp); NativeList <Antropy> open = new NativeList <Antropy>(sCount, Allocator.Temp); #region compute initial antropy for (int slotIndex = 0; slotIndex < sCount; slotIndex++) { if (m_results[slotIndex] < 0 && Q.TryGetCandidates( slotIndex, ref contents, ref candidates, ref weights, out count)) { _a = new Antropy() { coord = m_inputSlotInfos[slotIndex].coord, index = slotIndex, candidates = count, progress = Q.GetNeighborsResolutionRatio(slotIndex) }; if (open.Length != 0) { if (antropyComparer.Compare(_a, open[0]) >= 0) { open[0] = _a; } } else { open.Add(_a); } } } if (open.Length != 0) { open.Sort(antropyComparer); } else { open.Add(new Antropy() { index = 0, candidates = m_moduleCount }); } // ISSUE : When resolving candidates, some header gets selected because a neighboring socket is UNSET, and thus ignored // while the header only accepts NULL for that socket. #endregion #region collapse int increment = 0; float ratio; while (open.Length > 0) { _a = open.Pop(); index = _a.index; m_debug[index] = increment / (float)sCount; // Collapse if (Q.TryGetCandidates( index, ref contents, ref candidates, ref weights, out count)) { result = candidates[Common.NRandom.GetRandomWeightedIndex(ref weights, NextFloat())]; } else { // Uh oh, no candidate found ! result = SlotContent.UNSOLVABLE; } m_results[index] = result; // Recalculate antropy of neighboring slots that are currently unset if (Q.TryGetMatchingNeighbors( index, SlotContent.UNSET, ref slotSocketIndices, ref slotIndices, out count)) { for (int s = 0; s < count; s++) { index = slotIndices[s]; if (Q.TryGetCandidates( index, ref contents, ref candidates, ref weights, out int antropy)) { ratio = Q.GetNeighborsResolutionRatio(index); UpdateAntropy(ref index, ref antropy, ref ratio, ref open); } } } // Sort open slots which antropy is computed open.Sort(antropyComparer); increment++; } #endregion open.Release(); contents.Release(); candidates.Release(); slotSocketIndices.Release(); slotIndices.Release(); weights.Release(); }
public void Execute() { #region QueryHandle QueryHandler <T_SLOT, T_SLOT_INFOS, T_BRAIN> Q = new QueryHandler <T_SLOT, T_SLOT_INFOS, T_BRAIN>() { m_brain = m_brain, m_inputSlotInfos = m_inputSlotInfos, m_inputSlotCoordinateMap = m_inputSlotCoordinateMap, m_socketCount = m_socketCount, m_socketOffsets = m_socketOffsets, m_socketsMirrors = m_socketsMirrors, m_socketsMirrorsIndices = m_socketsMirrorsIndices, m_moduleCount = m_moduleCount, m_modulesWeights = m_modulesWeights, m_modulesHeaders = m_modulesHeaders, m_modulesNeighbors = m_modulesNeighbors, m_results = m_results, m_nullPairLookup = m_nullPairLookup }; #endregion NativeList <Neighbor> contents = new NativeList <Neighbor>(m_socketCount, Allocator.Temp); NativeList <int> candidates = new NativeList <int>(m_modulesNeighbors.Length, Allocator.Temp), unsolvables = new NativeList <int>(10, Allocator.Temp); NativeList <float> weights = new NativeList <float>(m_moduleCount, Allocator.Temp); int cCount, result; for (int slotIndex = 0, count = m_inputSlotInfos.Length; slotIndex < count; slotIndex++) { if (m_results[slotIndex] >= 0) { continue; } if (Q.TryGetCandidates( slotIndex, ref contents, ref candidates, ref weights, out cCount)) { result = candidates[NRandom.GetRandomWeightedIndex(ref weights, NextFloat())]; } else { result = SlotContent.UNSOLVABLE; unsolvables.Add(slotIndex); } m_results[slotIndex] = result; } // Second pass if necessary if (unsolvables.Length != 0) { int index = 0; for (int u = 0, uCount = unsolvables.Length; u < uCount; u++) { index = unsolvables[u]; if (Q.TryGetCandidates( index, ref contents, ref candidates, ref weights, out cCount)) { result = candidates[NRandom.GetRandomWeightedIndex(ref weights, NextFloat())]; } else { result = SlotContent.UNSOLVABLE; } m_results[index] = result; } } contents.Release(); candidates.Release(); unsolvables.Release(); weights.Release(); }