程序碎片- 分油问题(bfs)

这个问题是看算法精华版时候看见的,人家的算法看了很头大,自己写一遍后觉得清楚多了

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows.Forms;

 

/*

  * 分油算法:一个桶中有 12 斤油,要求倒出 6 斤,可现在另外只有两个桶,分别可装 8 斤与 5 斤,请问应如何来倒?

  * 补充:这里的 12,6,8,5 都是变量,应该可以自己设置,输出是每一次分油的步骤。

  *

  * bfs 广度优先搜索,把探索到的状态放在临时表里,看是否探索又回到了原来的位置。

  *

  *

  *

*/

 

namespace zboSorting.test.CSDN

{

    public class SeparateOil

    {

        private int targetOil { get ; set ; }

        private List <bottle > bottleList = new List <bottle >();

        private List <status > bottleTotalStatus = new List <status >();

        private bottle bottle1 = new bottle () {currentOil = 12, volumn = 12};

        private bottle bottle2 = new bottle () {currentOil = 0, volumn = 8};

        private bottle bottle3 = new bottle () {currentOil = 0, volumn = 5};

 

        public SeparateOil()

        {

            bottle [] bottleArray = {bottle1, bottle2, bottle3};

            bottleList.AddRange(bottleArray);

             this .targetOil = 6;

            bottleTotalStatus.Add(new status () {oilIn12 = 12, oilIn5 = 0, oilIn8 = 0, inSearch = true });

        }

 

        public void run()

        {

            List <status > searchStatusList = bottleTotalStatus.FindAll(status => status.inSearch == true );

            while (searchStatusList.Count > 0)

            {

                status fromStatus = searchStatusList[0];

                ResetBottles(fromStatus);

                List <bottle > possibleFromBottle = getPossibleFrom();

                List <bottle > possibleToBottle = getPossibleTo();

                foreach (bottle fromBottle in possibleFromBottle)

                {

                    foreach (bottle toBottle in possibleToBottle)

                    {

                        if (fromBottle != toBottle)

                        {

                            dumpOil(fromBottle, toBottle, fromStatus);

                            ResetBottles(fromStatus);

                        }

                    }

                 }

                fromStatus.inSearch = false ;

                searchStatusList = bottleTotalStatus.FindAll(status => status.inSearch == true );

            }

        }

 

        private void ResetBottles(status fromStatus)

        {

            this .bottle1.currentOil = fromStatus.oilIn12;

            this .bottle2.currentOil = fromStatus.oilIn8;

            this .bottle3.currentOil = fromStatus.oilIn5;

        }

 

        private void dumpOil(bottle fromBottle, bottle toBottle, status fromStatus)

         {

            int canDumpOil = fromBottle.currentOil < (toBottle.volumn - toBottle.currentOil)

                                 ? fromBottle.currentOil

                                 : (toBottle.volumn - toBottle.currentOil);

            fromBottle.currentOil = fromBottle.currentOil - canDumpOil;

            toBottle.currentOil = toBottle.currentOil + canDumpOil;

            status status = new status ()

                                {

                                    fromStatus = fromStatus,

                                    oilIn12 = bottle1.currentOil,

                                    oilIn8 = bottle2.currentOil,

                                    oilIn5 = bottle3.currentOil,

                                    inSearch = true

                                 };

            if (

                bottleTotalStatus.Find(

                    s => (s.oilIn12 == status.oilIn12 && s.oilIn5 == status.oilIn5 && s.oilIn8 == status.oilIn8)) ==

                null )

            {

                if (status.oilIn12 == 6 || status.oilIn8 == 6)

                {

                    Console .WriteLine("find 6" );

                    while (status != null )

                    {

                        Console .WriteLine("A:" + status.oilIn12 + "B:" + status.oilIn8 + "C:" + status.oilIn5);

                        status = status.fromStatus;

                    }

                }

                else

                {

                    bottleTotalStatus.Add(status);

                }

            }

        }

 

        private List <bottle > getPossibleTo()

        {

            List <bottle > possibleTo = new List <bottle >();

            foreach (bottle b in bottleList)

            {

                if (b.currentOil < b.volumn)

                    possibleTo.Add(b);

            }

            return possibleTo;

        }

 

        private List <bottle > getPossibleFrom()

        {

            List <bottle > possibleFrom = new List <bottle >();

            foreach (bottle b in bottleList)

            {

                if (b.currentOil > 0)

                    possibleFrom.Add(b);

            }

            return possibleFrom;

        }

 

        internal class bottle

        {

            public int volumn { get ; set ; }

            public int currentOil { get ; set ; }

        }

 

        internal class status

        {

            public int oilIn12 { get ; set ; }

            public int oilIn8 { get ; set ; }

            public int oilIn5 { get ; set ; }

            public status fromStatus { get ; set ; }

            public bool inSearch = false ;

        }

    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值