gpt4 book ai didi

c# - 基于项目权重合并多个列表的高效方法

转载 作者:太空狗 更新时间:2023-10-30 01:36:31 25 4
gpt4 key购买 nike

我正在编写一个国际象棋引擎,我需要一种有效的方法来将多个列表合并为一个按最小值排序的单个列表。

每个列表本质上都是一组已经按照完美攻击顺序排列的棋子。例如,我在 a2 上有一个白皇后,在 b3 上有一个白主教,在 f1 上有一个白车,在 f2 上有一个白车。现在假设我在 f7 上有一个黑棋子,然后所有四个白棋子从两个不同的离散方向——东北(皇后和象)和北(车)汇聚在 f7 方格上。

这两个组的顺序如下:

A 组 1st - Bishop (b3);第二名 - 女王 (a2)
B组) 第一 - 新车 (f2);第二 - 车 (f1)

现在使用下面的积分系统,我希望两个列表按以下顺序(从最低值到最高值)合并为一个列表:Bishop (b3)、Rook (f2)、Rook (f1) 最后是 Queen (a2).

皇后 = 900 分
车 = 500 分
主教 = 375 分
骑士 = 350 点
兵 = 100 分

部分代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SO_22015528
{
public enum eRayDirection
{
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest
}

public enum ePieceType
{
Empty = 0,
Pawn = 1,
Knight = 2,
Bishop = 3,
Rook = 4,
Queen = 5,
King = 6
}

public struct BoardPosition : IComparable<BoardPosition>
{
public int File;
public int Rank;
public int Square;

public BoardPosition( int square )
{
Square = square;
File = square % 7;
Rank = 8 - ( square >> 3 );
}

public static Boolean operator >( BoardPosition b1, BoardPosition b2 )
{
return ( b1.Rank > b2.Rank ) || ( b1.Rank == b2.Rank && b1.File < b2.File );
}

public static Boolean operator <( BoardPosition b1, BoardPosition b2 )
{
return ( b1.Rank < b2.Rank ) || ( b1.Rank == b2.Rank && b1.File > b2.File );
}

public int CompareTo( BoardPosition obj )
{
if ( this < obj ) return 1;
else if ( this > obj ) return -1;
else return 0;
}
}

public class ChessPiece
{
public int Value { get; set; }
public ePieceType Type { get; set; }
public int Square { get; set; }
public BoardPosition XY
{
get
{
return new BoardPosition( this.Square );
}
}
public ChessPiece( ePieceType type, int value, int square )
{
Value = value;
Type = type;
Square = square;
}
}

public class Constraint
{
public ChessPiece Piece { get; set; }
public eRayDirection Ray { get; set; }
public Constraint( ChessPiece piece, eRayDirection ray )
{
Piece = piece;
Ray = ray;
}
public override string ToString()
{
return String.Format( "{0} {1} {2}", Piece.Square, Piece.Type, Ray );
}
}

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SO_22015528
{
class Program
{
static void Main( string[] args )
{
// test code
ChessPiece a2 = new ChessPiece( ePieceType.Queen, 900, 48 );
ChessPiece b3 = new ChessPiece( ePieceType.Bishop, 375, 41 );
ChessPiece f1 = new ChessPiece( ePieceType.Rook, 500, 61 );
ChessPiece f2 = new ChessPiece( ePieceType.Rook, 500, 53 );

// This just simulates pieces that attack on the f7 square.
List<Constraint> f7 = new List<Constraint>();
f7.Add( new Constraint( b3, eRayDirection.NorthEast ) );
f7.Add( new Constraint( a2, eRayDirection.NorthEast ) );
f7.Add( new Constraint( f1, eRayDirection.North ) );
f7.Add( new Constraint( f2, eRayDirection.North ) );

// Get all positive ray directions ( use to simplify LINQ orderby )
List<eRayDirection> positiveRayDirections = new List<eRayDirection>();
positiveRayDirections.Add( eRayDirection.North );
positiveRayDirections.Add( eRayDirection.NorthEast );
positiveRayDirections.Add( eRayDirection.NorthWest );
positiveRayDirections.Add( eRayDirection.West );

var groups = f7
.GroupBy( g => g.Ray )
.Select( a =>
new
{
Key = a.Key,
Results = positiveRayDirections.Contains( a.Key ) ? a.OrderBy( x => x.Piece.XY ).ToList() : a.OrderByDescending( x => x.Piece.XY ).ToList()
} ).ToList();

// The groups object returns two discrete groups here;
// NorthEast containing 2 entries (Bishop & Queen) and North
// also containing to entries (Rook x 2).
List<Constraint> attackOrder = new List<Constraint>();

List<Int32> groupIndicies = new List<Int32>( groups.Count() );
for ( int n = 0; n < groups.Count(); n++ )
groupIndicies.Add( 0 );

while ( true )
{
Int32 value = Int32.MaxValue;
Int32 groupIndex = -1;

for ( int n = 0; n < groups.Count(); n++ )
{
var g = groups[ n ];
int gIndex = groupIndicies[ n ];

if ( gIndex < g.Results.Count && g.Results[ gIndex ].Piece.Value < value )
{
value = g.Results[ gIndex ].Piece.Value;
groupIndex = n;
}
}

if ( groupIndex < 0 )
break;

attackOrder.Add( groups[ groupIndex ].Results[ groupIndicies[ groupIndex ] ] );

groupIndicies[ groupIndex ]++;

}

foreach ( var ao in attackOrder )
Console.WriteLine( ao.ToString() );

Console.ReadKey();
}
}
}

我认为最后一点效率不高,如果有人能找到更简单的方法,我将不胜感激。

最佳答案

使用快速排序对每个列表单独排序,然后通过插入到最终列表中进行排序。

Order the lists individually.
Create the empty Final list.

do
{
consider the first item in each of the sorted lists and find the highest ranking candidate.
remove the item from its sorted list and add it to the final list.
}
until all of the sorted lists are empty.

关于c# - 基于项目权重合并多个列表的高效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22015528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com