代码改变世界

根据总用量计算每种包装规格的购买量和总价 后续篇(一)并且使得用户花费最少

2010-03-24 02:51  Virus-BeautyCode  阅读(1884)  评论(0编辑  收藏  举报

  在根据总用量计算每种包装规格的购买量和总价 中讲述了一个开发的场景,首先有一个总共的土地拥有量:total亩,现在有n种可以选择的商品,每一种商品都有每亩的用量:amount/亩,每一种商品都有多个包装规格,每个包装规格有自己的包装量和售价。

  需求就是计算出,在给定土地上面种植那种商品需要的花费最少,也就是可以用最少的钱来买更多的东西种地,满足我种地的最大需求量。

  其实我们还假设了一个前提,就是包装大的单价低,好比100克每包的可能买100元,200克每包的就应该卖180元,肯定会小于两个100克每包的价格,这个也是市场调研的结果,也比较符合市场常规。

  代码中用到了二分搜索法的思路,其实我需要的是一个定位,定位我需要购买的最合算的包装规格,也就是在满足需要的情况下,尽可能购买大包装。

  例如:现在有两个商品,土豆和白菜,土豆有三个规格,100克每包的100元,200克每包的180元,300克每包的240元;白菜有四个规格,100克每包的70元,200克每包的130元,300克每包的200元,400克每包的300元。种白菜每亩要100斤,中土豆每亩尧200斤。我总共有1029亩地,计算一下,是种土豆花费少?还是种白菜花费少?

  有两个点要注意:1)找位置,找到我需要购买的最合算的包装规格的位置,使用了二分搜索2)计算用量和预算。

  计算一种商品最少花费的伪代码如下:

  输入:一个商品的信息,包括包装规格

  输出:需要购买的包装规格几个数,总共的花费

  计算过程:

  {

    while(总量>最小包装规格的量)

    {

      1)找位置,定位包装规格

      2)计算需要购买多少个第一步找到的包装规格

      3)需要购买的个数=总量和包装规格的包装量取整

      4)总量=总量-需要购买的个数*包装规格的包装量

      5)这种商品的预算+=需要购买的个数*包装规格的单价

    }

    if(总量<=最小包装规格的量)

    {

      说明零头就只能买个最小包装了,因为购买不支持散买。

    }

  }

 

  示例代码下载:/Files/virusswb/BeautyCode.ConApp.rar

  代码如下:

 

代码
/*
 * Created by SharpDevelop.
 * User: haier
 * Date: 2010-3-23
 * Time: 22:19
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 
*/
using System;
using System.Collections.Generic;

namespace BeautyCode.ConApp
{
    
/// <summary>
    
/// 种植方案
    
/// </summary>
    public class PlantArea
    {
        
/// <summary>
        
/// 种植面积,单位是亩
        
/// </summary>
        public static decimal PlantAreaAmount=175.25m;
    }
    
/// <summary>
    
/// 商品类型
    
/// </summary>
    public enum ProductType
    {
        
/// <summary>
        
/// 种子
        
/// </summary>
        Seed,
        
/// <summary>
        
/// 肥料
        
/// </summary>
        Fertilizer,
        
/// <summary>
        
/// 农药
        
/// </summary>
        Pesticide
    }
    
    
public enum FertType
    {
        
/// <summary>
        
/// 底肥
        
/// </summary>
        DiF,
        
/// <summary>
        
/// 种肥
        
/// </summary>
        ZhongF,
        
/// <summary>
        
/// 追肥
        
/// </summary>
        ZhuiF
    }
    
public class Unit
    {
        
public Guid ID{set;get;}
        
        
public string CnName{set;get;}
    }
    
public class PkgPrice
    {
        
public Guid PkgID{set;get;}
        
/// <summary>
        
/// 包装量
        
/// </summary>
        public decimal PkgAmount{set;get;}
        
/// <summary>
        
/// 包装单位
        
/// </summary>
        public Unit PkgUnit{set;get;}
        
/// <summary>
        
/// 包装价格
        
/// </summary>
        public decimal Price{set;get;}
        
/// <summary>
        
/// 选中的包装个数
        
/// </summary>
        public int Quantities{set;get;}
    }
    
    
public class Product
    {
        
public virtual Guid ID{set;get;}
        
public virtual string Name{set;get;}
        
public virtual ProductType ProType{set;get;}
        
/// <summary>
        
/// 每亩用量
        
/// </summary>
        public virtual decimal Amount{set;get;}
        
/// <summary>
        
/// 每亩用量单位
        
/// </summary>
        public virtual Unit ProductUnit{set;get;}
        
/// <summary>
        
/// 总用量
        
/// </summary>
        public virtual decimal TotalAmount{set;get;}
        
public Product (ProductType type)
        {
            
this.ProType=type;
        }
        
/// <summary>
        
/// 预算
        
/// </summary>
        public decimal Budget{set;get;}
        
/// <summary>
        
/// 全部包装类型
        
/// </summary>
        public List<PkgPrice > AllPkgPrice{set;get;}
        
/// <summary>
        
/// 选中的包装类型
        
/// </summary>
        public List<PkgPrice > SelectPkgPrice{set;get;}
    }
    
public class Seed:Product 
    {
        
public Seed ():base(ProductType.Seed ){}
        
        
public List<Pesticide > Pesticides{set;get;}
        
public List<DiF > DiFs{set;get;}
        
public List<ZhongF >ZhongFs{set;get;}
        
public List<ZhuiF >ZhuiFs{set;get;}
    }
    
public class Fertilizer:Product 
    {
public FertType FType{set;get;}
        
public Fertilizer (FertType type):base (ProductType.Fertilizer){
        
this.FType=type ;
        }
    }
    
public class DiF:Fertilizer 
    {
        
public DiF ():base (FertType.DiF ){}
    }
    
public class ZhongF:Fertilizer 
    {
        
public ZhongF ():base (FertType .ZhongF ){}
    }
    
public class ZhuiF:Fertilizer 
    {
        
public ZhuiF ():base (FertType.ZhuiF ){}
    }
    
public class Pesticide:Product 
    {
        
public Pesticide ():base(ProductType.Pesticide ){}
    }
    
/// <summary>
    
/// Description of BeiBao.
    
/// </summary>
    public class BeiBao
    {
        
public List<Seed  >Seeds=null;
        
public Seed  Seed=null;
        
public List<Pesticide >Pesticides=null;
        
public Pesticide Pesticide=null;
        
public List<DiF >DiFs=null;
        
public DiF DiF=null;
        
public List<ZhongF >ZhongFs=null;
        
public ZhongF ZhongF=null;
        
public List<ZhuiF >ZhuiFs=null;
        
public ZhuiF ZhuiF=null;
        
public List<PkgPrice > PkgPrices=null;
        
public BeiBao()
        {
            Seeds 
=new List<Seed  >();
            Seed 
=new Seed(){ ID=Guid.NewGuid (),
                Name
="土豆", Amount =120, Budget=0,
                TotalAmount 
=120*PlantArea.PlantAreaAmount };
            PkgPrices 
=new List<PkgPrice>(){
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =100, Price=23},
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =210, Price=58},
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =130, Price=39}};
            Seed .AllPkgPrice 
=PkgPrices ;
            Seed.AllPkgPrice.Sort(
new Comparison<PkgPrice >(comparePkgAmountAsc));
            Seeds.Add(Seed );
            Seed 
=new Seed(){ ID=Guid.NewGuid (),
                Name
="白菜", Amount =150, Budget=0, TotalAmount =150*PlantArea.PlantAreaAmount };
            PkgPrices 
=new List<PkgPrice>(){
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =80, Price=20},
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =180, Price=48},
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =110, Price=34}};
            Seed .AllPkgPrice 
=PkgPrices ;
                Seed.AllPkgPrice.Sort(
new Comparison<PkgPrice >(comparePkgAmountAsc));
            Seeds.Add(Seed );
            Seed 
=new Seed(){ ID=Guid.NewGuid (),
                Name
="萝卜", Amount =100, Budget=0, TotalAmount =100*PlantArea.PlantAreaAmount };
            PkgPrices 
=new List<PkgPrice>(){
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =110, Price=35},
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =250, Price=79},
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =170, Price=49}};
            Seed .AllPkgPrice 
=PkgPrices ;
                Seed.AllPkgPrice.Sort(
new Comparison<PkgPrice >(comparePkgAmountAsc));
            Seeds.Add(Seed );
            Seed 
=new Seed(){ ID=Guid.NewGuid (),
                Name
="大豆", Amount =20, Budget=0, TotalAmount =20*PlantArea.PlantAreaAmount };
            PkgPrices 
=new List<PkgPrice>(){
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =110, Price=35},
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =250, Price=79},
                
new PkgPrice (){ PkgID=Guid.NewGuid (),PkgAmount =170, Price=49}};
            Seed .AllPkgPrice 
=PkgPrices ;
                Seed.AllPkgPrice.Sort(
new Comparison<PkgPrice >(comparePkgAmountAsc));
            Seeds.Add(Seed );
        }
        
        
public Product ComputeOptimized()
        {
            
            
foreach (Product p in this.Seeds  )
            {
                GetTotalBudget ( p);
            }
            Seeds.Sort (
new Comparison<Seed  >(compareProductBudgetAsc ));
            
return Seeds[0];
        }
        
private void  GetTotalBudget(Product p)
        {
            p.SelectPkgPrice
=new List<PkgPrice>();
            
int index=-1;
            
int quantities=0;
            
decimal totalamount=p.TotalAmount;
            
while (totalamount >p.AllPkgPrice [0].PkgAmount )
            {
                index 
=binaryLocalize (p.AllPkgPrice,totalamount,p.AllPkgPrice.Count );
                
if(index !=-1)
                {
                    quantities 
=(int)(totalamount /p.AllPkgPrice [index ].PkgAmount );
                    
//quantities =(int)(totalamount %p.AllPkgPrice [index ].PkgAmount );
                    p.SelectPkgPrice.Add(new PkgPrice (){
                                             PkgID
=p.AllPkgPrice[index].PkgID ,
                                             PkgAmount
=p.AllPkgPrice[index].PkgAmount,
                                             Price
=p.AllPkgPrice[index].Price ,
                                             Quantities
=quantities 
                                         });
                    p.Budget 
+=quantities *p.AllPkgPrice[index].Price ;
                }
                totalamount 
-=quantities *p.AllPkgPrice[index].PkgAmount;
            }
            
if(totalamount !=0)
            {
                quantities 
=1;
                index 
=0;
                p.SelectPkgPrice.Add(
new PkgPrice (){
                                             PkgID
=p.AllPkgPrice[index].PkgID ,
                                             PkgAmount
=p.AllPkgPrice[index].PkgAmount,
                                             Price
=p.AllPkgPrice[index].Price ,
                                             Quantities
=quantities 
                                         });
                    p.Budget 
+=quantities *p.AllPkgPrice[index].Price ;
            }
            
        }
        
/// <summary>
        
/// 二分法搜索元素
        
/// </summary>
        
/// <param name="a"></param>
        
/// <param name="x"></param>
        
/// <param name="n"></param>
        
/// <returns></returns>
        private int binarySearch(List<int >a,int x,int n)
        {
            
int left=0;
            
int right=n-1;
            
while (left <=right)
            {
                
int middle=(left +right )/2;
                
if(x==a[middle])return middle;
                
if(x>a[middle ])left =middle +1;
                
else right =middle -1;
            }
            
//没有找到
            return -1;
        }
        
/// <summary>
        
/// 二分法定位规格
        
/// </summary>
        
/// <param name="pkgPrices"></param>
        
/// <param name="totalAmount"></param>
        
/// <param name="n"></param>
        
/// <returns></returns>
        private int binaryLocalize(List<PkgPrice > pkgPrices,decimal  totalAmount,int n)
        {
            
if(totalAmount >=pkgPrices [n-1].PkgAmount )
                
return n-1;
            
            
int left=0;
            
int right=n-1;
            
while (left <=right )
            {
                
int middle=(left+right )/2;
                
if(totalAmount >=pkgPrices [middle ].PkgAmount &&totalAmount <pkgPrices [middle +1].PkgAmount )
                {
                    
return middle ;
                }
                 
if(totalAmount ==pkgPrices [middle +1].PkgAmount )
                {
                    
return middle +1;
                }
                 
if(totalAmount >pkgPrices [middle +1].PkgAmount )
                     left 
=middle +1;
                 
else
                     right 
=middle -1;
            }
            
return -1;
        }
        
private int compareProductBudgetAsc(Product pro1,Product pro2)
        {
            
if(pro1.Budget>pro2 .Budget )
                
return 1;
            
if(pro1.Budget<pro2 .Budget )
                
return -1;
            
else 
                
return 0;
        }
        
        
private int comparePkgAmountAsc(PkgPrice pkg1,PkgPrice pkg2)
        {
            
if(pkg1.PkgAmount >pkg2.PkgAmount )
                
return 1;
            
if(pkg1.PkgAmount <pkg2 .PkgAmount )
                
return -1;
            
else 
                
return 0;
        }
    }
}

 

 

 

调用代码

 

代码
/*
 * Created by SharpDevelop.
 * User: haier
 * Date: 2010-3-21
 * Time: 1:02
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 
*/
using System;

namespace BeautyCode.ConApp
{
    
class Program
    {
        
public static void Main(string[] args)
        {
            Console.WriteLine(
"Hello World!");
            
            
// TODO: Implement Functionality Here
            BeiBao bag=new BeiBao();
            Product product
=    bag.ComputeOptimized ();
            
            Console.Write(
"Press any key to continue . . . ");
            Console.ReadKey(
true);
        }
    }
}