キャッシュされたパスのリストをA *アルゴリズムに実装しようとしています。現在、キャッシュされたパスは次のようなリストに保存されています。
readonly List<CachedPath> _cachedPaths = new List<CachedPath>();
このリストに対して実行される操作は次のとおりです。
FirstOrDefaultは、特定の条件を満たす要素を取得します
var cached = _cachedPaths.FirstOrDefault(p => p.From == from && p.To == target && p.Actor == self);
削除して要素
_cachedPaths.Remove(cached);
追加
_cachedPaths.Add(new CachedPath {
From = from,
To = target,
Actor = self,
Result = pb,
Tick = _world.WorldTick
});
注:クラスCachedPathのGetHashCodeとEqualsは、From、To、およびActorによってのみオーバーライドされるため、これらの同じ属性を持つ2つのインスタンスは、同じハッシュと同等性を持ちます。
'HashSet'でのクイックルックアップ(含む)、挿入、および削除がO(1)(私が間違っていない場合))であることを考えると、これらの操作を行うために 'HashSet'を使用することを検討しました。唯一の問題はFirstOrDefaultです。これを取得するには、コレクション全体を列挙する必要がありました。
この問題を考慮して、From、To、およびActorのハッシュでインデックス付けされた辞書の使用も検討しました。
Dictionary<int, CachedPath> cachedPath
繰り返しますが、私が間違っていない場合、DictionaryはO(1)の挿入、削除、およびKeyによる取得も提供します。これにより、DictionaryはHashSet + = O(1)要素検索機能。
私は何かが足りないのですか?より多くの操作をサポートするという意味で、DictionaryはHashSetよりも優れていますか?
前もって感謝します。
Dictionary
はHashSet
よりも優れているのではなく、ただ違うだけです。
HashSet
を使用します。Dictionary
を使用しますHashSet
は値が関連付けられていないDictionary
と考えることができます(実際、HashSet
は舞台裏でDictionary
を使用して実装されることがあります)が、このように考える必要はありません。2つをまったく異なるものとして考えることもうまくいきます。
あなたの場合、次のようにアクターごとに辞書を作成することで、パフォーマンスを向上させることができる可能性があります。
Dictionary<ActorType,List<CachedPath>> _cachedPathsByActor
このようにして、線形検索はアクターに基づいてサブリストをすばやく選択し、ターゲットごとに線形検索します。
var cached = _cachedPathsByActor[self].FirstOrDefault(p => p.From == from && p.To == target);
または、3つの項目すべてを考慮する等価比較子を作成し、キーと値の両方としてDictionary
を使用してCachedPath
を使用し、そのカスタム IEqualityComparer<T>
キー比較者として:
class CachedPathEqualityComparer : IEqualityComparer<CachedPath> {
public bool Equals(CachedPath a, CachedPath b) {
return a.Actor == b.Actor
&& a.From == b.From
&& a.To == b.To;
}
public int GetHashCode(CachedPath p) {
return 31*31*p.Actor.GetHashCode()+31*p.From.GetHashCode()+p.To.GetHashCode();
}
}
...
var _cachedPaths = new Dictionary<CachedPath,CachedPath>(new CachedPathEqualityComparer());
...
CachedPath cached;
if (_cachedPaths.TryGetValue(self, out cached)) {
...
}
ただし、このアプローチでは、辞書にFrom
、To
、およびActor
が同一のアイテムが最大で1つあることを前提としています。
ハッシュセットは、追加を実行するときに例外をスローしません。代わりに、追加の成功を反映するブール値を返します。
また、ハッシュセットはkeyValueペアを必要としません。ハッシュセットを使用して、一意の値のコレクションを保証します。