最近在学 JavaScript , 为了尽快熟悉语法,决定移植以前写的盖尔-沙普利算法。
c# 下的代码:https://www.cnblogs.com/aitong/p/10973774.html
在测试面向对象的继承特性时出现bug,也不知道怎么修改。所以这次就直接抛弃继承了。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>盖尔-沙普利算法</title> </head> <body> <script> function GetMaxPoint() { return 1000; }; function GetMinPoint() { return 200; }; function GetEstimatePoint(point)//估分 { var mul = 0.8 + Math.random() * 0.4; return point * mul; } //请求对象 function RequestObj(id, estimatePoint) { this.ID = id;// 对象编号 this.EstimatePoint = estimatePoint;// 对象在自己心目中的估分 }; function Male(id) { this.PartnerID = -1;//配偶id this.ID = id; this.Point = Math.random() * (GetMaxPoint() - GetMinPoint()) + GetMaxPoint(); this.MyEstimatePoint = GetEstimatePoint(this.Point); this.PartnerEstimatePoint = 0;//配偶估分 this.RequestList = []; } Male.prototype.InitRequestList = function (femaleDic) { this.RequestList = []; for (var i = 0; i < femaleDic.length; i++) { var female = femaleDic[i]; // var num = Math.floor(Math.random() * 10 + 1)//控制此人可以接触到的女性人数 // if (num != 1) { // continue; // } var point = GetEstimatePoint(female.Point);//对对方评分 if (point > this.MyEstimatePoint) { var mul = (point - this.MyEstimatePoint) / this.MyEstimatePoint; if (mul < 0.2) { this.RequestList.push(new RequestObj(female.ID, point)); } } else { var mul = (this.MyEstimatePoint - point) / this.MyEstimatePoint; if (mul < 0.2) { this.RequestList.push(new RequestObj(female.ID, point)); } } } this.RequestList.sort(RequestListSort); } Male.prototype.IfMarried = function () { if (this.PartnerID < 0) { return false; } else { return true; } } Male.prototype.GetSatisfaction = function ()//满意度 { var satis = 0; if (this.IfMarried()) { satis = 0; } var mul = Math.abs(this.MyEstimatePoint - this.PartnerEstimatePoint) / GetMaxPoint() / 2; if (this.MyEstimatePoint > this.PartnerEstimatePoint) { satis = 50.0 * (1 - mul); } else { satis = 50.0 * (1 + mul); } return satis; } RequestListSort = function (x, y)//降序 { if (x.EstimatePoint < y.EstimatePoint) { return 1; } if (x.EstimatePoint > y.EstimatePoint) { return -1; } return 0; } Male.prototype.Request = function (maleDic, femaleDic)//求婚 { if (this.IfMarried()) { return; } if (this.RequestList.length == 0) { return; } var female = femaleDic[this.RequestList[0].ID]; if (female.BeRequest(this, maleDic)) { this.PartnerID = female.ID; this.PartnerEstimatePoint = this.RequestList[0].EstimatePoint; } this.RequestList.splice(0, 1); } Male.prototype.Divorce = function ()//离婚 { this.PartnerID = -1; this.PartnerEstimatePoint = 0; } function Female(id) { this.PartnerID = -1;//配偶id this.ID = id; this.Point = Math.random() * (GetMaxPoint() - GetMinPoint()) + GetMaxPoint(); this.MyEstimatePoint = GetEstimatePoint(this.Point); this.PartnerEstimatePoint = 0;//配偶估分 this.RequestList = []; } Female.prototype.BeRequest = function (male, maleDic) { var estimatePoint = GetEstimatePoint(male.Point);//先评分 if (this.IfMarried()) { if (this.PartnerEstimatePoint < estimatePoint) { var difference = estimatePoint / this.PartnerEstimatePoint; if (difference > 1.5) { maleDic[this.PartnerID].Divorce(); this.PartnerID = male.ID; this.PartnerEstimatePoint = estimatePoint; return true; } } return false; } else//未婚 { if (estimatePoint > (this.MyEstimatePoint * 0.8)) { this.PartnerID = male.ID; this.PartnerEstimatePoint = estimatePoint; return true; } return false; } } Female.prototype.IfMarried = function () { if (this.PartnerID < 0) { return false; } else { return true; } } Female.prototype.GetSatisfaction = function ()//满意度 { var satis = 0; if (this.IfMarried()) { satis = 0; } var mul = Math.abs(this.MyEstimatePoint - this.PartnerEstimatePoint) / GetMaxPoint() / 2; if (this.MyEstimatePoint > this.PartnerEstimatePoint) { satis = 50.0 * (1 - mul); } else { satis = 50.0 * (1 + mul); } return satis; } function Marry(maleNumber, femaleNumber) { this.MaleDic = []; this.FemaleDic = []; for (var i = 0; i < maleNumber; i++) { this.MaleDic.push(new Male(i)); } for (var i = 0; i < femaleNumber; i++) { this.FemaleDic.push(new Female(i)); } for (var i = 0; i < this.MaleDic.length; i++) { var male = this.MaleDic[i]; male.InitRequestList(this.FemaleDic); } } Marry.prototype.GetMarriageCount = function () { var count = 0; for (var i = 0; i < this.MaleDic.length; i++) { if (this.MaleDic[i].IfMarried()) { count++; } } return count; } Marry.prototype.GetSingleCount = function () { return this.MaleDic.length + this.FemaleDic.length - this.GetMarriageCount() * 2; } Marry.prototype.GetMaleSatisfaction = function () { var satisfaction = 0; for (var i = 0; i < this.MaleDic.length; i++) { var male = this.MaleDic[i]; var mySatis = male.GetSatisfaction(); satisfaction += mySatis } return satisfaction / this.MaleDic.length; } Marry.prototype.GetFemaleSatisfaction = function () { var satisfaction = 0; for (var i = 0; i < this.FemaleDic.length; i++) { var female = this.FemaleDic[i]; satisfaction += female.GetSatisfaction(); } return satisfaction / this.FemaleDic.length; } Marry.prototype.NeedMatch = function () { for (var i = 0; i < this.MaleDic.length; i++) { if ((this.MaleDic[i].RequestList.length > 0) && !this.MaleDic[i].IfMarried()) { return true; } } return false; } Marry.prototype.Start = function () { var count = 0; while (this.NeedMatch()) { //console.log(count); count++; for (var i = 0; i < this.MaleDic.length; i++) { this.MaleDic[i].Request(this.MaleDic, this.FemaleDic); } } } var marry = new Marry(100, 100); marry.Start(); document.write("MaleSatisfaction: " + marry.GetMaleSatisfaction() + "<br>"); document.write("FemaleSatisfaction: " + marry.GetFemaleSatisfaction() + "<br>"); </script> </body> </html>