JavaScript 盖尔-沙普利算法

最近在学 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>
原文地址:https://www.cnblogs.com/aitong/p/11170713.html