【人工智能算法】算法基础之离散优化[旅行商问题 背包问题]_离散 智能优化算法_桑桑在路上的博客-程序员宅基地

技术标签: 算法  机器学习  人工智能  人工智能算法  

本文重点:

  • 离散VS连续
  • 旅行商问题
  • 背包问题

旅行商问题

旅行商问题(Traveling Salesman Problem, TSP)是一个难以用传统迭代算法求解的NP困难问题,因此经常用模拟退火算法来解决,同时旅行商问题也是最著名的计算机科学问题之一。

旅行商问题简要说明

旅行商问题描述的是有一个旅行商,在指定的多个城市中,从任意城市开始,要分别经过其他城市并最终回到起点城市,求解其最短路径的方案,其中除起点城市外的其他城市能且只能经过一次。旅行商问题还有好些个变体,其中有些变体允许多次经过同一城市,或者是给城市之间的双向路径赋予不同的“成本”。
旅行商问题
乍一看寻找最短路径对常规的迭代算法而言好像是个轻而易举的事情,但随着给定城市数量的增多,可能的路径组合数量也急剧增加。假如城市只有一两个,那可能的路径也就只有一条;但3个城市的话,可能的路径就有6条。
这是阶乘式的,要使用暴力搜索的话,在城市数量增大的时候将无法完成,但是使用模拟退火算法可以在几分钟内找到50个城市下对应的最短路径。

旅行商问题求解的实现

行连续型模拟退火算法的时候,是在当前解的某个或某几个维度上加上一个随机值,而在离散型模拟退火算法上就有点儿不同了。在旅行商问题中,每个解都是一条遍历各城市的路径,当前解也是这么一条路径,而移动到新位置则意味着选取与当前相近的一条路径。
要应用模拟退火算法,首先要生成一个初始随机解。就旅行商问题而言,指的则是各城市的一个去重的有序随机列表,然后还必须通过添加微小的随机扰动来产生新解。在旅行商问题中,其实就是调换经过某两个城市的顺序,具体的实现方式是随机选取两个不同的索引并交换对应城市在列表中的顺序。
不管是模拟退火算法的哪一种实现形式,都必须具有以下3个要素:

  • 对各个解进行评估的评估函数;
  • 生成初始随机解的功能,且尽量向最优解靠拢;
  • 将当前解变换为新的随机解的功能。

在旅行商问题中,评估得分就是旅行商经过的距离,距离越小则认为表现越好;初始解是一个去重的随机城市列表;当前解变换为新解的操作则是由调换两个城市的顺序实现的。

环形旅行商问题

如何才能衡量一个NP困难问题的算法性能呢?在NP困难问题中,我们多数时候并不知道确切的最优解,这也就使得判断算法的结果与最优解的接近程度变得非常困难。不过,倒是有一种方法可以评估模拟退火算法在旅行商问题上的表现。将所有城市排成一个圈,最优解就应当在这个圆圈或者是椭圆的圆周上。
椭圆排布的模拟退火算法路径优化
模拟退火算法结果已经比较接近最优解了,但还不是最优解;不过没关系,多数情况下全局最优解都很难找得到。并且之所以立马能够知道当前路径不是最优解,还是因为我们对几何中的各种问题都研究得很透彻。如果你有某方面的知识储备可以帮助你解决问题,那么就尽管放手去干,用你的方法去解决问题。只有当你对某个问题一筹莫展的时候,人工智能才算得上是最佳解决方案。

背包问题

背包问题简要说明

背包问题讲的是一个在商店中陷入选择困难症的入室窃贼,他四周有很多货物,但却只有一个背包,要怎么样才能够使他的收获最大化呢?前提条件是选取的货物组合必须要背包能够放得下。
背包问题是一个离散型问题。背包问题最常见的一种形式是所选的东西数目固定,且每样东西一般最多只能选一次,被称为“0-1背包问题”。其他还有些变体的背包问题则允许每样东西重复选择。背包问题中给出的物品一般具有两个属性:重量和价值;并且也会指定背包能够承受的最大重量。此外你可能还会好奇背包的容积,但一般来说背包问题都不会考虑容积。

背包问题求解的实现

我们采用向量的方式表述结果,如下所示:
Coffee thermos(weight=5,profit=1):false
Baseball cap(weight=1,profit=1):true

确定了解的表达方式之后,还要让模拟退火算法具有这些条件:

  • 对每个解(即物品组合)进行评分的评估函数;
  • 生成初始随机解的功能;
  • 将当前解变换为新的随机解的功能。
    模拟退火算法求解的始终是最小化问题,这一点在构造评估函数的过程中务必要注意。任务目标是要使得所选取物品的价值最大,理论上价值的最大值就是所有物品价值的总和,但除非背包能够放下所有物品,否则理论上的最大价值就怎么也不可能达到。于是理论上的最大总价值和当前总价值的差就是最好的评分标准,并且因为几乎不可能出现背包能够放得下所有物品的情况,所以最佳得分也不可能为0——毕竟要是背包能够放得下所有东西,那这个问题就没有思考的意义了。反之,我们倒还可以尝试对方案进行优化调整。
    还有一个要考虑的关键是:如果某个解的总重超过了背包限重应该怎么办。理想状态下,随机算法生成解的时候不会出现这种情况,但这也并不妨碍在评估函数中进行限重检测。如果所选物品超出背包限重,就应该给分数赋一个相当大的值,这样就可以标识出这是一个无效的选取方案,从而使算法丢弃这一结果。
    要满足模拟退火算法的第二个条件,就要用某种方法初始化一个随机解。要初始化这第一个解,就要向一个空背包中放入物品,一次放入一个;只要放到背包超出限重了,就取出最后放入的物品,此时背包初始化完成。
    要满足模拟退火算法的第三个条件,即要将当前解变换为新的随机解。要达到这一目的,就向背包中放入一个此前没有放过的东西,这样一来如果超出限重,则随机取出包内一个物品,若仍超重,继续取出一个物品,直到包内总重低于限重。此时的选取方案即为新解。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_51656605/article/details/114628964

智能推荐

java后端编程需要什么软件?_学习java后端开发需要用到什么软件-程序员宅基地

Java都需要JavaSDK,注意是SDK,不仅仅是JRE,而是SDKjava8,安装好java了后,设置classpath为dt.jar和tools.jar两个文件,Path为bin目录为sdk和jre的bin目录。即可java客户端编程只需要IDE就可以了其实java后端编程需要的东西还是蛮多的,大概分为四大类IDE,服务器数据库,数据库客户端软件另外都..._学习java后端开发需要用到什么软件

将1234567890转换成1,234,567,890 每3位用逗号隔开的形式 PHP千分位_"php将\"津a12345"-程序员宅基地

1.使用php的系统函数 number_format$num = 1234567890;echo number_format($num);//1,234,567,890echo number_format($num,2);//1,234,567,890.00echo number_format($num,2,'-','');//1,234,567,890-00 2...._"php将\"津a12345"

【TensorFlow】TensorFlow函数精讲之tf.contrib.layers.flatten()_tensorflow flatten-程序员宅基地

tf.contrib.layers.flatten(A)函数使得P保留第一个维度,把第一个维度包含的每一子张量展开成一个行向量,返回张量是一个二维的,返回的shape为[第一维度,子张量乘积)。一般用于卷积神经网络全连接层前的预处理,因为全连接层需要将输入数据变为一个向量,向量大小为[batch_size, ……]如下边,pool是全连接层的输入,则需要将其转换为一个向量。假设pool是一..._tensorflow flatten

(转)【NOIP模拟题】【线段树】【扫描线】2016.11.17 第三题 矩形 题解-程序员宅基地

因为今天的第三题不会(其实是不想打),所以转来一篇某大大的题解。 转自@Star_Weeper矩形 文件名:brother.pas/c/cpp 时限:1S 空间:256M Description 胜负胸中料已明,又从堂上出奇兵。秋实大哥是一个下棋好手,独孤求败的他觉得下棋已经无法满足他了,他开始研究一种新的玩法。 在一个n×m的棋盘上,放置了k个车,并且他在棋盘上标出了q个

编译安装httpd 2.4-程序员宅基地

author:JevonWei版权声明:原创作品官方网站下载httpd2.4、apr及apr-util的相关软件包,并传输到centos 7系统中的/usr/local/src(apr1.6版本过高不兼容,故需下载apr-1.5*版本)httpd2.4http://httpd.apache.org/download.cgi#apache2.4apr及apr-utilhttp://h...

随便推点

博客_老赵点滴-程序员宅基地

国内科技博客极客公园PingWest爱范儿36Kr月光博客虎嗅网雷锋网钛媒体TechWeb互联网的那些事数字尾巴Engadget 中国cnBetaTech2ipo 创见TechCrunch 中国Donews科技娲母网易科技新浪科技腾讯科技_老赵点滴

利用tensorflow 一步一步实现一个简单神经网络,线性回归-程序员宅基地

下面是基于一个简单例子,一步一步注释加翻译A look at a very simple neural network inTensorFlow让我们来看一个基于tensorFlow创建一个非常简单的神经网络,实现线性回归的功能。 This is an introduction to working withTensorFlow. It works through an

算法练习-NOJ-1045-六数码问题_noj六数码-程序员宅基地

NOJ-1045-六数码问题时限:1000ms 内存限制:10000K 总时限:3000ms描述现有一两行三列的表格如下:A B CD E F把1、2、3、4、5、6六个数字分别填入A、B、C、D、E、F格子中,每个格子一个数字且各不相同。每种不同的填法称为一种布局。如下:1 3 52 4 6布局12 5 64 3 1布局2定义α变换如下:把A格中的数字放入B格..._noj六数码

第十周项目1(2)-由先序序列和中序序列构造二叉树-程序员宅基地

/* *Copyright(c)2017,烟台大学计算机学院 *All right reserved. *文件名:sk.cpp btree.h btree.cpp *作者:盛凯 *完成日期:2017年11月16日 *版本号:v1.0 * *问题描述:先序序列和中序序列构造二叉树*输入描述:无 *程序输出:见运行结果 sk.cpp:#inclu

Maven 整合POI_maven org.apache.poi-程序员宅基地

首先,导入依赖<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.10-FINAL</version> _maven org.apache.poi

java记事本打开功能_Java简易实现记事本的打开与保存-程序员宅基地

记事本的打开与保存一些总结* Swing中有时方法不显示,需要把方setVisible(true)放到最后执行* AWT中的TextArea默认是中间布局* fileDialog对话框Load模式需要对取消事件进行处理* 快捷键使用需要用到JmenuItem主方法package cn.work.demo.demo03;public class NotePad {public static void..._java记事本打开功能