0

3D リスト (3 つのネストされたリスト) があり、リスト内の各アイテムについて、隣接するアイテムを見つける必要があります。現在、隣接するアイテムごとに配列を作成し、それを各アイテムに格納しています。これはかなりリソースを集中的に使用するので、少し単純化しようとしています。

私はこのアプローチの使用を検討していました:

for (int i = 0; i < 8; i++)
{
    switch (i)
    {
        case (0):
            mapCell neighbor = myMap.Depth[z].Rows[x].Columns[y - 1];
        case (1):
            mapCell neighbor = myMap.Depth[z].Rows[x].Columns[y + 1];
        case (2):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y];
        case (3):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y];
        case (4):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y + 1];
        case (5):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y - 1];
        case (6):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y + 1];
        case (7):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y - 1];
    }

    // do some stuff with the neighbor here
}

これは、パフォーマンスの点で私が現在持っているものよりもはるかに優れていますが、これを達成するためのより簡単な方法があるかどうか疑問に思っています? 少し面倒なようで、1行でこれを行う方法があるように感じますが、数学を理解することはできません.

編集:申し訳ありませんが、重要な詳細をいくつか省略している可能性があります。「neighbor」変数で動作するコードは、非常に長く、解決に役立たないため、省略されています。「隣人」変数のリストを維持する必要はありません (これは私が現在行っていることであり、あまりにも多くのメモリ (約 400 メガバイト) を使用します) を使用します。隣接する 8 つの項目を一度に 1 つずつ操作してから、次のノードに移動します. 上記のコードはそれらを通過するために機能しますが、これを達成するための最も最適化された方法とは思えません.

4

1 に答える 1

1

3D データ構造の特定の深さで 2D 配列の隣人を実際に見つけているようです。つまり、隣接する深さの隣人を無視しています。

あなたのアプローチはおそらくかなり高性能です。SOに関する同様の質問へのこの回答など、タイピングが少なくて済むより洗練された方法を見つけることができますが、それがより高速になるとは思えません。

明らかに、8 つの隣接要素を持たないエッジでアイテムを処理するために、コードにいくつかのチェックを含める必要もあります。

private void DoSomethingWithNeighbours(int x, int y, int z)
{
    foreach (var neighbout in this.GetNeighbours(x, y, z)
    {
        // ...
    }
}

private IEnumerable<Item> GetNeighbours(int x, int y, int z)
{
    if (x > 0)
    {
        if (y > 0)
        {
            yield return myMap.Depth[z].Rows[x - 1].Columns[y - 1];
        }

        yield return myMap.Depth[z].Rows[x - 1].Columns[y];

        if (y < ColumnCount - 1)
        {
            yield return myMap.Depth[z].Rows[x - 1].Columns[y + 1];
        }
    }

    if (y > 0)
    {
        yield return myMap.Depth[z].Rows[x].Columns[y - 1];
    }

    if (y < ColumnCount - 1)
    {
        yield return myMap.Depth[z].Rows[x].Columns[y + 1];
    }

    if (x < RowCount - 1)
    {
        if (y > 0)
        {
            yield return myMap.Depth[z].Rows[x + 1].Columns[y - 1];
        }

        yield return myMap.Depth[z].Rows[x + 1].Columns[y];

        if (y < ColumnCount - 1)
        {
            yield return myMap.Depth[z].Rows[x + 1].Columns[y + 1];
        }
    }
}

または、パフォーマンス コストがごくわずかで、より簡潔な次の代替案を使用します。

private IEnumerable<int> GetNeighbours2(int x, int y, int z)
{
    for (int i = x - 1; i <= x + 1; ++i)
    {
        for (int j = y - 1; j <= y + 1; ++j)
        {
            if (i >= 0 && i < Rows && j >= 0 && j < Cols && !(i == x && j == y))
            {
                yield return myMap.Depth[z].Rows[i].Columns[j];
            }
        }
    }
}
于 2013-01-16T01:34:27.823 に答える