算法project实验报告

这篇实验报告详细介绍了中山大学数据科学与计算机学院2018年秋季学期的一个算法项目,解决Capacitated Facility Location Problem。报告探讨了贪心算法、局部搜索法(爬山法)和模拟退火法三种解决方案,并对比分析了它们的优缺点。实验结果显示,局部搜索法通常优于贪心算法,而模拟退火法虽然运行时间较长,但能提供更稳定的解。
摘要由CSDN通过智能技术生成

中山大学数据科学与计算机学院本科生实验报告

(2018年秋季学期)

课程名称 算法设计与分析 任课老师 张子臻
年级 2016级 专业(方向) 计算机应用
学号 16340030 姓名 陈斯敏
电话 15917173057 Email 2540740154@qq.com
开始日期 2018.12.18 完成日期 2018.12.22

实验问题描述

Capacitated Facility Location Problem
Suppose there are n facilities and m customers. We wish
to choose:
(1) which of the n facilities to open ?
(2) the assignment of customers to facilities ?
The objective is to minimize the sum of the opening cost and the assignment cost.
note: The total demand assigned to a facility must not exceed its capacity.
题目要求给定相应的工厂和顾客,每个工厂有相应的容量(可容纳顾客需求)和相应的开启费用,而每个顾客有相应的需求(固定的)和任务费用(因工厂而改变),现在要对每个工厂进行分配顾客,要求所有顾客都要分配到工厂,然后工厂的容量不能超过它所分配到的顾客的需求之和,同时希望工厂开启费用和顾客任务费用总和最小,每一份数据的输入格式如下:
在这里插入图片描述


解决方案一、贪心算法

因为题目要求希望求出最优的算法,所以我们很容易可以想到使用贪心算法进行求解,但是贪心策略的选取很关键。对于该问题,贪心算法并不一定能求出最优解法,但是可以在较短的时间求得一个可满足解且该解的优劣程度不会太差。
接下来,讲一下实现该算法的流程和贪心策略:

一、贪心算法流程

  1. 读取数据(采用C++的流读取方式)。
  2. 运用贪心策略选择分配一个未被分配顾客到相对应的工厂(该工厂需要可满足要求)。
  3. 重复第2步的操作,直至分配完所有的顾客。
  4. 评估当前费用,输出结果。

二、贪心策略
采用的贪心选取策略是选取性价比最高的操作,因为需要满足的需求是固定的,而产生的费用是不固定的,所以我们希望性价比最高当然是费用/需求最少,那么,我们每次分配顾客时,便会产生相应的费用,也会满足相应的需求,便可以遍历所有可进行的操作,选取其中费用需求比最小(性价比最高的)的操作,具体公式如下:

GreadyVal = assignment / demand

此处,我们除了考虑对应的客户任务费用,工厂的开启费用也需要考虑进去,这里需要进行判断,如果该工厂并未开启,则需要加上OpenCost,如果已经开启(分配过用户),那么我们便不需要加上这部分的费用,所以我们进行改进,总的运算公式如下:

GreadyVal = assignment / demand
if not isOpen:
	GreadyVal += OpenCost / demand

三、贪心算法的优缺点
优点:

  • 运行时间快,所有样例只需要进行两层循环遍历所有的操作,直至选取完所有的顾客节点即可,所有样例的运行时间都极短。

缺点:

  • 不一定可解,因为这样的贪心策略,如果测例不够温柔的话,很容易分配到最后会剩余大量工厂碎片导致无法插入客户,不过此次实验的测试样例并不会出现该情况。
  • 解的误差性有时候不一定可接受,这个需要跟后边的算法结果进行对比,很明显贪心算法不是最优算法,而有时其解与最优解的差距较大。

四、算法实现的代码
代码地址:https://github.com/chensm9/Algorithm-project/blob/master/Greedy.cpp
这里贴出主要的贪心算法实现函数:

 // 贪心算法流程
 int Greedyrun() {
   
 	  // 需要遍历“顾客数量”次,以此达到分配完所有的顾客
     for (int i = 0; i < Cnum; i++) {
   
         int greedyVal = INT_MAX;
         int c_id = -1, f_id = -1;
         // 遍历所有的用户和工厂
         for (int j = 0; j < Cnum; j++) {
   
         	  // 该用户已经被分配
             if (CList[j].belongTo != -1)
                 continue;
             // 遍历所有的可容纳该用户的工厂
             for (int k = 0; k < Fnum; k++) {
   
                 if (CList[j].demand <= FList[k].leftCapacity) {
   
                     int tempVal = assignmentMap[k][j] / CList[j].demand;
                     if (FList[k].leftCapacity == FList[k].Capacity)
                         tempVal += FList[k].OpenCost / CList[j].demand;
                     // 判断性价比是否优于当前最优操作
                     if (greedyVal > tempVal) {
   
                         greedyVal = tempVal;
                         c_id = j;
                         f_id = k;
                     }
                 }
             }
         }
         // 这一轮最后被选取的操作
         FList[f_id].leftCapacity -= CList[c_id].demand;
         CList[c_id].belongTo = f_id;
     }
     int bestSolution = evaluate(FList, CList);
     return bestSolution;
 }

解决方案二、局部搜索法(爬山法)

局部搜索法的过程是对一个初始化的解反复进行相关领域操作,直到得到比该解更优的解,然后一直迭代下去,直到逼近最优的解,同样的,该算法也不一定能够得到最优的解,且其解与我们所选取的初始解和进行的邻域操作相关,但因为进行多次迭代能够得到比初始解更优的解,那么我们很容易想到可以将上面贪心算法得到的解作为初始解来进行迭代,那么最后得到的结果一定比贪心算法更优。
一、局部搜索算法流程

  1. 输入数据(同样采用相同的流读取)
  2. 初始化一个最优解(此处可以采用贪心算法的解作为初始解)
  3. 对最优解进行邻域操作,产生一个新的解,如果该解优于当前最优解,则代替当前最优解。
  4. 重复第3步操作,直到N次迭代都未达到更优解,退出重复操作。
  5. 输出当前最优解。

二、相关邻域操作
这里为了效果较好,我采用了两种邻域操作:

  1. 随意寻找一个客户,改变其要分配去的工厂(需要满足容量和需求的关系),以此改变当前的费用总和。
  2. 随意交换两个客户的所属工厂(同样需要满足容量和需求的关系)。

还有N的取值,即未找到更优解的次数N,需要取多少次,此处我取的是1000。

三、局部搜索法的优缺点
优点:

  • 相比贪心算法,能更趋近于最优解
  • 收敛速度足够快,运算的时间也不会很长

缺点:

  • 容易陷入局部最优,部分测例产生的解并不比贪心算法得到的解好多少
  • 不够稳定,因为上面说到的陷入局部最优的原因,所以不同次运行可能陷入不同的局部最优,导致产生的结果相差较大

四、算法实现的代码
代码地址:https://github.com/chensm9/Algorithm-project/blob/master/HC.cpp
这里主要贴出局部搜索函数部分的代码:

 // 局部搜索法
 int HCrun() {
   
     // initBestSolution();
     // 利用贪心算法产生一个解
     Greedyrun();
     srand((int)time(0));
     int flag = 0;
     int bestSolution = evaluate(FList, CList);
     
《实用计算机软件》 实验报告 实验报告题目: 某企业大门建造方案 姓名: 学号: 年级: 专业: 指导教师: 日期: 年 月 日 项目概述 project实验报告全文共11页,当前为第1页。本次计算机实用软件做的项目是有关于某企业大门工程有关的一些前期准备工作的流程。包括确定项目的范围、编写计划书和准备一系列相关材料等。 project实验报告全文共11页,当前为第1页。 项目内容 1.任务 project实验报告全文共11页,当前为第2页。 project实验报告全文共11页,当前为第2页。 project实验报告全文共11页,当前为第3页。 project实验报告全文共11页,当前为第3页。 2.资源 project实验报告全文共11页,当前为第4页。 project实验报告全文共11页,当前为第4页。 3.任务+资源 project实验报告全文共11页,当前为第5页。 project实验报告全文共11页,当前为第5页。 project实验报告全文共11页,当前为第6页。 project实验报告全文共11页,当前为第6页。 project实验报告全文共11页,当前为第7页。 project实验报告全文共11页,当前为第7页。 project实验报告全文共11页,当前为第8页。 project实验报告全文共11页,当前为第8页。 共享资源项目 三.实验体会或收获 project2010软件课程的学习,使我学会了项目类软件的使用,以及对大二上学期的项目管理课程更深一步的强化学习了一下,对今后的社会工作会有很大的帮助。 project实验报告全文共11页,当前为第9页。 project实验报告全文共11页,当前为第9页。 Project完成报告 一、项目介绍 施工工程一直是人们谈论的焦点,该行业在如今社会发展领域占据了主要地位,一个大型房产从筹办到竣工是一个庞大且复杂的过程,其每一个环节都可以单独作为一个项目进行操作。 项目三要素包括范围、时间、费用,对于房地产项目来说范围可以是获得竞标书、按要求交付房子;时间可以指何时开时间建造何时竣工、何时销售;费用可以指建造房产花费多少人力、物力等等。 此次作业将房地产开发大体流程分为三个项目:建设工程、市政工程、办理用地手续,以"建设工程"为主项目,"市政工程"、"办理用地手续"作为子项目,最后将三个项目合并,合并主要包括创建资源库、插入项目、创建链接与调配资源等操作,目的是实现共享,方便分析与查阅项目成本、资源使用情况、项目进度等信息 二、优化说明 为了保证项目实施有条不紊地进行,需要对项目不断地调整、优化、以满足实际需求,例如: 将"办理建设项目地征求意见函"与"办理用地手续"项目中的任务"交地"的任务间相关性类型设置为"开始—开始",因为"办理建设项目地征求意见函"行为必须在"交地"开始后才能开始。如果按照系统默认的"完成—开始"任务相关性类型则会浪费资源,"交地"完成后可以直接开始"把办理建设项目地征求意见函"。 设置计算方式查看关键任务,关键任务的时差为零,所以对于不为零的关键任务需要及时调整。 设置比较基准,在任务工作表视图中选择"差异"命令,可以查看比较基准开始时间、比较基准完成时间等信息。 三、应用界面 project实验报告全文共11页,当前为第10页。建设工程甘特图 project实验报告全文共11页,当前为第10页。 project实验报告全文共11页,当前为第11页。 project实验报告全文共11页,当前为第11页。 project实验报告
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值