应公司内部业务发展需要才做了这个 直通车排名锁定 的功能
该算法经过本人仔细实践研究出来的结果,记录下来,以作备忘
如有不是之处,欢迎指导,以便改正;
/// <summary>
/// 获取预测后的最高或最低排名,最高或最低出价(以分为单位)
/// </summary>
/// <param name="keywordForecast"></param>
/// <param name="direction"></param>
/// <param name="realtimeRank"></param>
/// <param name="destinationRank"></param>
/// <param name="outPrice"></param>
/// <param name="outRank"></param>
/// <param name="isForecastedSameRank"></param>
/// <param name="isNeedModifyPrice"></param>
private static void GetForecastResult(KeywordForecast keywordForecast, EnumDirection direction, long realtimeRank, long destinationRank,
int originalPrice, out int outPrice, out int outRank, out bool isForecastedSameRank, out bool isNeedModifyPrice, out bool isForecastSucceeded)
{
outPrice = 0;
outRank = 0;
isForecastedSameRank = false;
isNeedModifyPrice = false;
isForecastSucceeded = false;
if (keywordForecast == null) return;
string[] priceRanks = keywordForecast.PriceRank.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
if (priceRanks.Count() == 0) return;
//=============================================
/* 升排名:一般是要加出价。但是,有可能因为其他人在某段时间内都在降排名,
* 导致我们预测的结果分析发现,排名升了,出价却比原来低了。
* (结论:升排名不一定加出价,也有可能会减出价)
*/
/* 降排名:一般是要加减价。但是,有可能因为其他人在某段时间内都在升排名,
* 导致我们预测的结果分析发现,排名降了,出价却比原来高了。
* (结论:降排名不一定减出价,也有可能会加出价)
*/
IDictionary<int, int> matchRankItemLst = new Dictionary<int, int>();
if (direction.Equals(EnumDirection.UP)) //加价
{
//==========================================
//加价条件:R(目标名次) =< Rx <= R(实际名次),且出价最高的
int maxPrice = priceRanks.Where(p => int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].ToString()) >= destinationRank
&& int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].ToString()) <= realtimeRank)
.Max(p => int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[0].ToString()));
int rankOfMaxPrice = priceRanks.Where(p => int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[0].ToString()) == maxPrice)
.Select(p=>int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].ToString())).FirstOrDefault();
matchRankItemLst.Clear();
matchRankItemLst.Add(rankOfMaxPrice, maxPrice);
}
else if (direction.Equals(EnumDirection.DOWN)) //减价
{
//==========================================
//减价条件:R(实际名次) =< Rx <= R(目标名次),且出价最低的
int minPrice = priceRanks.Where(p => int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].ToString()) >= realtimeRank
&& int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].ToString()) <= destinationRank)
.Min(p => int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[0].ToString()));
int rankOfMinPrice = priceRanks.Where(p => int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[0].ToString()) == minPrice)
.Select(p => int.Parse(p.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].ToString())).FirstOrDefault();
matchRankItemLst.Clear();
matchRankItemLst.Add(rankOfMinPrice, minPrice);
}
//查找到匹配项目//==================================================
/* 首先判断预测是否成功,即预测结果是否在预期范围内
* 如果在预期范围:
* a. 出价与原来出价不相等,则可以调价
* b. 出价与原来出价相等,则不可以调价(没必要调价)
* 否则,直接跳出
*/
if (matchRankItemLst.Count > 0) //预测排名在预期范围
{
isForecastSucceeded = true;
KeyValuePair<int, int> kvp = matchRankItemLst.FirstOrDefault();
if (kvp.Key == destinationRank) isForecastedSameRank = true;
if (kvp.Value == originalPrice) //原来的出价与预测出的目标排名的出价相等(没必要调价)
{
outPrice = kvp.Value;
outRank = kvp.Key;
isNeedModifyPrice = false;
} //如果不与原来的出价相同,则调价
else
{
outPrice = kvp.Value;
outRank = kvp.Key;
isNeedModifyPrice = true;
}
}
else //预测排名不在预期范围
{
outPrice =0;
outRank = 0;
isForecastSucceeded = false;
isNeedModifyPrice = false;
isForecastedSameRank = false;
}
}