您的位置:首页 > 其它

老魏帮忙发的木棒问题的最大长度优先匹配原则算法

2011-06-22 17:14 483 查看
老魏帮忙发的问题的地址
http://www.cnblogs.com/eastjade/archive/2011/06/22/2086828.html
下面是算法:

定义最木棒的对象

class Item
{
public Item(int length, int count)
{
Length = length;
Count = count;
}

public int Length { get; set; }

public int Count { get; set; }
}


然后定义我们要组装的木棒的长度,这里是21。 定义一个结果类

class Segment
{
public Segment()
{
Items = new List<int>();
}

public List<int> Items { get; set; }

public int Length
{
get { return Items.Sum(); }
}

public void RemoveLast()
{
Items.RemoveAt(Items.Count - 1);
}
}


定义一个MaximumFirstPermutation 类 作为控制类

class MaximumFirstPermutation
{
public MaximumFirstPermutation()
{
Items = new List<Item>();
}

private List<Item> backupItems;

public List<Item> Items { get; private set; }

public int SegmentLength { get; set; }

public Segment[] Segments { get; private set; }

/// <summary>
/// 将结果写入文件
/// </summary>
/// <param name="fileName"></param>
public void WriteToFile(string fileName)
{
StreamWriter writer = new StreamWriter(fileName);

List<int> allItems = new List<int>();

foreach (Segment segment in Segments)
{
writer.WriteLine(string.Concat(segment.Items.Select(i => i + " ")));
allItems.AddRange(segment.Items);
}

writer.WriteLine();
writer.WriteLine("---------------------------");

foreach (Item backupItem in backupItems)
{
Item usedItewm = Items.First(i => i.Length == backupItem.Length);
writer.WriteLine(string.Format("{0}: total {1}, used {2}, remaining {3}", backupItem.Length, backupItem.Count, allItems.Count(i => i == backupItem.Length), backupItem.Count - allItems.Count(i => i == backupItem.Length)));
}

writer.WriteLine();
writer.WriteLine("---------------------------");

writer.WriteLine(string.Format("total length: {0}, used {1}, remaining {2}", backupItems.Sum(i => i.Length * i.Count), allItems.Sum(), backupItems.Sum(i => i.Length * i.Count) - allItems.Sum()));

writer.Close();
}

public void Compute()
{
backupItems = Items.Select(i => new Item(i.Length, i.Count)).ToList();

Items = Items.OrderByDescending(i => i.Length).ToList();
List<Segment> segments = new List<Segment>();

while (true)
{

Segment segment = GetSegment(SegmentLength);

if (segment != null)
{
segments.Add(segment);
}
else
{
break;
}
}

Segments = segments.ToArray();
}

/// <summary>
/// 拼装过程
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
private Segment GetSegment(int length)
{
Segment segment = new Segment();
Item exact = Items.FirstOrDefault(i => i.Count > 0 && i.Length == length);

if (exact != null)
{
exact.Count--;
segment.Items.Add(exact.Length);
return segment;
}

foreach (Item item in Items.Where(i => i.Count > 0 && i.Length < length))
{
int count = 1;

while (true)
{
item.Count -= count;

for (int i = 1; i <= count; i++)
{
segment.Items.Add(item.Length);
}

bool exceeded = segment.Length > length;

if (!exceeded)
{
Segment remainingSegment = GetSegment(length - item.Length);
if (remainingSegment != null)
{
segment.Items.AddRange(remainingSegment.Items);
return segment;
}
}

item.Count += count;

for (int i = 1; i <= count; i++)
{
segment.RemoveLast();
}

if (exceeded)
{
break;
}

count++;
}
}

if (segment.Length != length)
{
return null;
}

return segment;
}
}


program.cs main 函数

MaximumFirstPermutation per = new MaximumFirstPermutation() { SegmentLength = 21 };

per.Items.Add(new Item(1, 100));
per.Items.Add(new Item(2, 200));
per.Items.Add(new Item(3, 90));
per.Items.Add(new Item(4, 14));
per.Items.Add(new Item(5, 25));
per.Items.Add(new Item(6, 6));
per.Items.Add(new Item(7, 20));
per.Items.Add(new Item(8, 35));
per.Items.Add(new Item(9, 15));
per.Items.Add(new Item(10, 21));
per.Items.Add(new Item(11, 22));
per.Items.Add(new Item(12, 9));
per.Items.Add(new Item(13, 16));
per.Items.Add(new Item(14, 35));
per.Items.Add(new Item(15, 39));
per.Items.Add(new Item(16, 41));
per.Items.Add(new Item(17, 29));
per.Items.Add(new Item(18, 26));
per.Items.Add(new Item(19, 18));
per.Items.Add(new Item(20, 20));
per.Items.Add(new Item(21, 35));

per.Compute();
per.WriteToFile(@"e:\r1.txt");


这个样例数据执行出来之后是

total length: 6479, used 6468, remaining 11

total Segment:48
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: