C#实现倒油算法

原题如下:12(a桶 满的 有12斤油)斤桶里 取出6斤油 有 另外有8斤(b桶)和5斤(c桶)两个空桶  让程序输出取出这6斤油的步骤

现在实现的算法可以配参数(定义有几个桶,初始有多少油,要得到多少油,都可以配),并且找出任意(多条线路或者找不到)满足条件的倒油线路图:

运行效果:

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

namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
//在此自定义相关初始信息
Oil.初始油量 = "12,0,0";
Oil.桶的容量
= "12,8,5";
Oil.需求油量
= "6";

Oil oil
= new Oil();
Status SuperStatus
= oil.GetStartState();
oil.status.Add(SuperStatus);
oil.执行(SuperStatus);

if (oil.Endstatus.Count == 0)
{
Console.WriteLine(
"无法倒出指定质量大小的油。");
}
else
{
Console.WriteLine(
"共找到" + oil.Endstatus.Count.ToString()+"条倒油线路:");
}
for (int i = 0; i < oil.Endstatus.Count; i++)
{
Console.WriteLine(oil.翻译路线(oil.Endstatus[i]));
}
}
}

class Oil
{
public static string 桶的容量;
public static string 初始油量;
public static string 需求油量;

//自动记录桶的总数
int count;

public Oil()
{

count
= 桶的容量.Split(',').Count();
capacity
= new int[count];
for (int i=0;i<count;i++)
{
capacity[i]
= Convert.ToInt32(桶的容量.Split(',')[i]);
}
}

public int[] capacity; //new int[] { 12, 8, 5 };
public List<Status> status = new List<Status>();
public List<Status> Endstatus = new List<Status>();

Status 倒油(Status state,
int a, int b)
{
//排除不可倒的情况
if (state.OilState[a] == 0return null;
if (state.OilState[b] == capacity[b]) return null;


//倒油操作
//先定义成功倒油后的新状态
Status newStatus = new Status();
newStatus.OilState
= new int[count];
state.OilState.CopyTo(newStatus.OilState,
0);
newStatus.Father
= state;

if (state.OilState[a] > capacity[b] - state.OilState[b])
{
newStatus.OilState[a]
-= capacity[b] - state.OilState[b];
newStatus.OilState[b]
= capacity[b];
}
else
{
newStatus.OilState[a]
= 0;
newStatus.OilState[b]
+= state.OilState[a];
}

//判断倒油后的新状态是否在状态列表中存在
bool IsExist = false;
foreach (var s in status)
{
bool mark = true;
for (int i = 0; i < newStatus.OilState.Count(); i++)
{
if (newStatus.OilState[i] != s.OilState[i]) mark = false;
}
if (mark)
{
IsExist
= true;
break;
}
}

if (IsExist)
{
return null;
}
else
{
status.Add(newStatus);
return newStatus;
}
}

public void 执行(Status SuperStatus)
{
//如果找到一条路线
if (SuperStatus.OilState.Contains(Convert.ToInt32(需求油量)))
{
Endstatus.Add(SuperStatus);
ArrangeStatus();

执行(GetStartState());
return;
}


for (int a = 0; a < count; a++)
{
for (int b = 0; b < count; b++)
{
if (b != a)
{
Status newStatus
= 倒油(SuperStatus, a, b);
if (newStatus != null)
{
执行(newStatus);
}
}
}
}
}

public string 翻译路线(Status endState)
{
string theWay = string.Empty;
Status s
= endState;
while (s != null)
{
string wayNode = string.Empty;
foreach (var a in s.OilState)
{
wayNode
+= a.ToString() + " ";
}
if (theWay == string.Empty) theWay += wayNode;
else theWay = wayNode.Trim() + "" + theWay;

s
= s.Father;
}
return theWay;
}

/// <summary>
/// 整理状态表,为寻求新路线做准备
/// </summary>
public void ArrangeStatus()
{
status.Clear();
for (int i = 0; i < Endstatus.Count; i++)
{
Status s
= Endstatus[i];
while (s != null)
{
status.Add(s);
s
= s.Father;
}
}
}

/// <summary>
/// 获取开始状态
/// </summary>
/// <returns></returns>
public Status GetStartState()
{
Status status
= new Status();
status.Father
= null;
status.OilState
= new int[count];
for (int i = 0; i < count; i++)
{
status.OilState[i]
= Convert.ToInt32(初始油量.Split(',')[i]);
}
return status;
}
}

/// <summary>
/// 记录各桶当前所装油量的状态信息
/// </summary>
class Status
{
public int[] OilState;
public Status Father;
}

}
原文地址:https://www.cnblogs.com/wwwzzg168/p/3572044.html