Java 中旅行商问题的暴力算法

2024-06-19

我正在学校的数学课上做一个项目,我选择做旅行商问题,这是我一直想进行更多研究的问题。 但是,我的暴力求解算法遇到了问题。

*请前往底部更新查看最新版本代码



如果您知道旅行推销员问题是什么,请跳过本段:尽可能概括地说,TSP 是这样的:您是一名推销员,想要访问某个地区的每个城市(城市本质上是地图上的一个点)。在有界的 x 和 y 区域中有“n”个城市,每个城市都与每个城市相连(假设有一条直路)。你需要找到允许你访问每个城市的城市中最短的路线。我想使用的算法之一(并且我需要测试其他算法)是Brute Force,它会检查每条可能的路线并返回最短的路线路线。之所以不总是使用它,是因为它要求我们检查 (n-1)!可能的路线,并且随着“n”的增加,这个数字变得越来越大 - 事实上,只有 50 个城市,这将是 608281864034267560872252163321295376887552831379210240000000000 条路线要检查。

假设对于本文中讨论的所有示例,我们将使用包含 4 个城市的任意区域(即使该算法可以处理 n 个城市。而且我们也不关心距离 - 我们希望用暴力破解每条可能的路线)。

这是一张简单的图片,演示了我正在谈论的内容(我从 4 个城市开始检查该过程是否正常工作)

带有城市的地图图片 http://www.emeraldinsight.com/content_images/fig/0050300707002.png

这是暴力算法(假设所有其他调用的方法都正常工作,因为它们确实如此):

(查看下面的更多解释)

[code]

public void BruteForceFindBestRoute(Route r) //Must start r having 1 unflagged city to begin with
    {
        if(!r.allFlagged() && r.route.size() != m.cities.size())
        {
            /*STEP 1 Begin with last unflagged city*/
            City pivot = r.lastCityAdded();
            /*STEP 2: Flag city*/
            pivot.visited = true;
            /*STEP 3: Find cities "NOT IN ROUTE"*/
            ArrayList<City> citiesNotInRoute = new ArrayList<City>();
            for(int i = 0; i<m.cities.size(); i++)
            {
                if(!r.isCityInRoute(m.cities.get(i).name))
                {
                    citiesNotInRoute.add(m.cities.get(i));
                }
            }
            /*STEP 4: Recursively call BruteForceFindBestRoute() using these cities added to the end of our original route*/
            for(int i = 0; i<citiesNotInRoute.size(); i++)
            {
                Route newRoute = r;
                newRoute.addToRoute(citiesNotInRoute.get(i));
                BruteForceFindBestRoute(newRoute);
            }
        }
        /*STEP 5: If the route is full but the last city isn't flagged, then flag it call BruteForceFindBestRoute() again, with the last city flagged*/
        else if(!r.allFlagged() && r.route.size() == m.cities.size())
        {
            if(r.allFlaggedButLast())
            {
                Route x = r;
                x.flagLastCity();
                BruteForceFindBestRoute(x);
            }
        }
        /*STEP 6: If all cities are flagged, the route is full. Check to see if it's the best route.*/
        else if(r.allFlagged())
        {
            if(IsBestRoute(r))
                bestRoute = r;
        }
        else
            System.err.println("Error: somehow all cities got flagged, but the route isn't full");

    }

这是我的逻辑: (注意:城市对象有一个名为“visited”的“flag”布尔变量)

(如果所有路线均未标记,并且路线不包含每个可能的城市)

  • 从 1 个未标记城市的路线开始。
  • 标记“最后一个未标记”的城市(该城市是“枢轴”)
  • 找到“NOT IN ROUTE R”的每个城市,并将其添加到新路线中。
  • 在每个路由上递归调用 BruteForce 方法。

(如果所有路线均未标记,但路线包含每个城市)

  • 标记最后一个城市

(否则...这意味着该路线已标记每个城市并包含每个可能的城市)

  • 看看这是否是最短路线 - 如果是,则将其存储在全局变量中

这张图片将帮助我解释这个问题...... 所以程序正确地从左侧向下移动。然而,在到达底部之后,人们会期望递归跳回步骤 4,事实也确实如此。然而,R 现在包含所有 4 个城市,并且所有 4 个城市都已标记,而不是 R 将城市 A 标记为标记,城市 B 未标记,然后在包含 A 标记和 B 的“新路线”上递归地调用自身。它失败了,因为它再次将城市 D 添加到“newRoute”,再次递归调用自身,在另一种方法中,我们得到一个数组越界错误,因为我所在的地区没有 5 个城市,但路线 r 中错误地有 5 个城市(A、B、C、D、D)。

递归树结构的有用图片 http://i264.photobucket.com/albums/ii191/om3n07/46049b90.jpg

该问题与在循环中调用递归或在递归调用中引用路由“r”有关。

如果您知道我需要做什么,我将非常感谢您的帮助。

感谢任何愿意帮助我的人。我会将整个项目发送给任何愿意提供帮助的人。


UPDATE

好吧,所以我尝试缩短和简化我原来的方法,这就是我所拥有的:

public void BruteForceFindBestRoute(Route r, ArrayList<City> citiesNotInRoute)
    {
        if(!citiesNotInRoute.isEmpty())
        {
            for(int i = 0; i<citiesNotInRoute.size(); i++)
            {
                City justRemoved = (City) citiesNotInRoute.remove(0).clone();
                Route newRoute = (Route) r.clone();
                newRoute.addToRoute(justRemoved);

                BruteForceFindBestRoute(newRoute, citiesNotInRoute);
                citiesNotInRoute.add(justRemoved);
            }
        }
        else //if(citiesNotInRoute.isEmpty())
        {
            if(IsBestRoute(r))
                bestRoute = r;
        }

    }

问题是,当我们跳出递归时,for循环中的变量i似乎失去了它的意义,并且循环不再继续。有想法吗?


递归调用返回后,您应该从路线中删除城市。你做这个:

            Route newRoute = r;
            newRoute.addToRoute(citiesNotInRoute.get(i));
            BruteForceFindBestRoute(newRoute);

但从来没有newRoute.removeFromRoute或类似的。

请注意,您正在编写Java,并且在Java中,完成了对象的赋值引用。意思就是r and newRoute are 同一个物体. newRoute不是独立的副本r正如你所期望的那样。所以任何修改newRoute会改变r以及。您可能想将您的路线明确复制到那里。 Java 术语是clone http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html。确保您的克隆足够深,即克隆所有相关的数据结构,而不是在原始数据结构与其克隆数据结构之间共享它们。

Note:在很多地方,您都可以使代码更加高效,但无论如何,暴力都远非高效,而且您只谈论少数城市,也许您不必关心。不过,如果您想研究替代方案,请考虑维护所有未访问过的城市的单个链接列表。每次调用都会循环该列表,删除一个元素,递归并将该元素放回原处。无需在每次调用中从头开始构建此列表。的想法跳舞链接 http://arxiv.org/abs/cs/0011047可以巧妙地应用于此任务,作为预制链表实现的替代方案。

EDIT:

您的代码的以下变体对我有用:

import java.util.*;

class SO11703827 {

    private static ArrayList<Integer> bestRoute;

    public static void bruteForceFindBestRoute
        (ArrayList<Integer> r,
         ArrayList<Integer> citiesNotInRoute)
    {
        if(!citiesNotInRoute.isEmpty())
        {
            for(int i = 0; i<citiesNotInRoute.size(); i++)
            {
                Integer justRemoved =
                    (Integer) citiesNotInRoute.remove(0);
                ArrayList<Integer> newRoute =
                    (ArrayList<Integer>) r.clone();
                newRoute.add(justRemoved);

                bruteForceFindBestRoute(newRoute, citiesNotInRoute);
                citiesNotInRoute.add(justRemoved);
            }
        }
        else //if(citiesNotInRoute.isEmpty())
        {
            if(isBestRoute(r))
                bestRoute = r;
        }

    }

    private static boolean isBestRoute(ArrayList<Integer> r) {
        System.out.println(r.toString());
        return false;
    }

    public static void main(String[] args) {
        ArrayList<Integer> lst = new ArrayList<Integer>();
        for (int i = 0; i < 6; ++i)
            lst.add(i);
        ArrayList<Integer> route = new ArrayList<Integer>();
        bruteForceFindBestRoute(route, lst);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 中旅行商问题的暴力算法 的相关文章

  • 如何测试两个 Joda-Time DateTime 对象几乎相等?

    在单元测试中 我经常使用返回DateTime于或关于now 有没有办法说actual日期时间在几秒之内actual约会时间 这听起来是个坏主意 单元测试不应该以任何方式依赖于当前的实际时间 这就是为什么注入一些接口是一个很好的做法 称为Cl
  • JAX-RS:不区分大小写的路径

    我已将 REST 服务 方法锚定到 URI 模板 Path注解 它看起来像往常一样 GET Path message Produces application json public Response getMessage 但我的 REST
  • JavaFX 控制器如何访问其他服务?

    我将 JavaFX 2 与 Scala 一起使用 我有class Application extends javafx application Application它执行诸如读取应用程序配置等操作 然后它会启动主窗口 该主窗口需要连接到一
  • 如何使用 C 中的 Banker's Rounding 将 double 舍入为 int

    我想编写一个函数 使用银行家的舍入方法将双精度数舍入为整数 将一半舍入为偶数 http en wikipedia org wiki Rounding Round half to even http en wikipedia org wiki
  • 使用具有不同参数的 Jackson for List 将 JSON 映射到 pojo

    JSON 格式 0 cast showname woh pagle type Episodes video src video mp4 DRM False 这里的问题是我遇到以下异常 org codehaus jackson map Jso
  • 如何解决Spring Data JPA中的N+1问题?

    我使用 Spring Data JPA 作为持久层 并且面临 N 1 问题 我还使用规范 API 因为我发现很难解决 N 1 问题 请帮忙 Entity public class PopulationHealth Id private in
  • Unwrap 当使用 Collectors maxBy 和 groupingBy 时可选

    我有一堂课 有一个String and an int field public class Data private String name private int value private Data String name int va
  • LRU、FIFO、随机

    当出现页面错误或缓存未命中时 我们可以使用最近最少使用 LRU 先入先出 FIFO 或随机替换算法 我想知道 哪一个提供了最好的性能 也称为未来缓存丢失 页面错误最少的可能性 架构 Coldfire 处理器 没有愚蠢的问题 这句话非常适合这
  • n维匹配算法

    在这里寻求一些建议 有谁知道在 n 维空间中开始研究匹配算法的好地方 例如 任何约会网站都必须使用某种算法来匹配 2 个人 我读到的是 我们可以将一个人的特征映射到一个 n 维数组中 每个特征都有一个点系统 一旦我们拥有一个人的所有 可用
  • 全屏 Swing 组件无法在 Mac OS X Mountain Lion 上的 Java 7 上接收键盘输入

    12 21 更新 7u10 最近发布 确认 问题仍然存在 值得庆幸的是 解决方法仍然有效 11 7 更新 我们有一个解决方法 来自 Oracle 的 Leonid Romanov 在 openjdk java net 邮件列表上提供了一些关
  • 将私有 Java 9 模块包公开给 JUnit 的正确方法是什么?

    我有一个 可执行 Java 9 模块 意味着它不会公开任何包 它只包含一个main函数 我需要测试 我正在使用 Gradle 的java library and org gradle java experimental jigsaw插件 我
  • 从文件夹中读取java文件

    我开发了一个应用程序 可以从用户选择的文件夹中读取文件 它显示每个文件中有多少行代码 我只想在文件选择器中显示 Java 文件 具有 java 扩展名的文件 下面是我的代码 public static void main String ar
  • 如何规划庭院灯最有效的路线

    我正在尝试挂一些庭院灯 基于另一个问题 https cs stackexchange com questions 80134 christmas light route efficiency我问 我意识到我需要一种算法来解决路由检查问题 h
  • Spring MVC @RequestBody 不适用于 jquery ajax?

    这是我的ajax请求 var dataModel name1 value1 name2 value2 ajax url testURL type POST async false contentType application json d
  • 找出网络上所有活动机器的IP

    如何找到 LAN 上所有当前活动计算机的 IP 如何编写一个可以在任何子网上运行的通用程序 我目前正在这样做 尝试 isReachable 是否到达我子网上的所有机器 如果他们这样做 请存储他们的 IP 地址 无论如何 是否有其他方法可以手
  • 从 blob 反序列化 java 对象

    首先 我很抱歉 我要问一些愚蠢的问题 我根本不懂java 也不知道我们是否可以问这样的问题 如果没有 删除我的主题 oracle中有一个存储blob的表 它是二进制的 我能够解码它 输出看起来像这样 sr com epam insure c
  • java 未知深度的嵌套哈希图

    我有一个要求 我需要有一个嵌套的哈希图 但深度将在运行时决定 例如 如果在运行时 用户说 3 那么我的哈希图应该是这样的 HashMap
  • 如何在 Tomcat 6 中合理配置安全策略

    我使用的是为 Ubuntu Karmic 打包的 Tomcat 6 0 24 Ubuntu 的 Tomcat 软件包的默认安全策略相当严格 但看起来很简单 在 var lib tomcat6 conf policy d 有多种建立默认策略的
  • JSON 解析为 Java - Android 应用程序

    我需要在 Java Android 应用程序中解析 json 字符串的帮助 JSON 文件的文本 data columns location id name description latitude longitude error type
  • 为什么 java.io.File 没有 close 方法?

    While java io RandomAccessFile确实有一个close method java io File没有 这是为什么 文件在完成时会自动关闭吗 javadoc 的Fileclass 将该类描述为 文件和目录路径名的抽象表

随机推荐

  • Sencha Cmd 5 + Java 8 错误

    在我的 Windows 构建服务器上安装 Java 8 JDK 后 执行以下命令时遇到以下错误sencha命令 C gt sencha Error Registry key Software JavaSoft Java Runtime En
  • 如何将列表列表写入 CSV 文件 Python?

    我有一个列表 例如 a b c d e f 我想将其写入 CSV 文件 如下所示 a b c d e f 我怎么做 我尝试过使用 csv writerows 但输出文件的每个字符位于不同的单元格中 并且全部位于同一行中 从某种意义上说 第一
  • Cocos2D复杂动画[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 Cocos2D 将我的游戏从 Flash 移植到 iOS 我现在有一个工作版本 我很高兴我
  • 使用ftplib进行多线程上传

    我正在尝试进行多线程上传 但出现错误 我猜想也许不可能在 ftplib 中使用多线程 这是我的代码 class myThread threading Thread def init self threadID src counter ima
  • 在汇编中初始化字符串数组

    我想创建一个数据数组 在初始化数据部分保存 5 个字符串 每个字符串正好有 4 个字符 每个字符串都有一些初始数据 例如第一个字符串的 abcd 第二个字符串的 efgh 等等 无效的 0任何字符串都不需要字符 如何用汇编语言初始化字符串数
  • 从存储访问框架 UI 获取文件夹后保存图像

    我设置了一个首选项 让用户使用存储访问框架为我的应用程序选择保存文件夹 获取uri后onActivityResult我将其保存到SharedPreferences作为字符串并在要保存时保存图像 我正在使用此方法成功保存图像 public v
  • Flutter:如何使用 AnimatedContainer 和扩展列?

    假设我们有 3 个孩子Column Flexible flex 1 child Container color Colors red Flexible flex 3 child Container color Colors yellow F
  • 如何在 Ubuntu Karmic 上安装 LFE?

    Erlang 已经安装 dpkg l grep erlang ii erlang 1 13 b 3 dfsg 2ubuntu2 Concurrent real time distributed function ii erlang appm
  • 在响应模式下使用 CSS 更改元素顺序

    图1为桌面模式 下面两张图片和文字 总共三个div 图 2 是我希望它在移动浏览器 例如手机 中的显示方式 关于如何实现这一点有什么想法吗 我愿意接受任何建议 这个想法是让文本显示在图像上方 以最好地说明这两个图像的描述 在桌面版本中将文本
  • 无法删除 Access 中 SQL 表上的注册表

    我有一个在 Access 应用程序中链接的 SQL Server 表 如果我尝试使用删除查询删除记录 则没有问题 但是 如果我尝试直接在表中删除记录或在数据表模式下使用选择查询 Access 不允许我删除记录并引发以下警告 Microsof
  • 如何在 RequireJS 中模拟单元测试的依赖关系?

    我有一个要测试的 AMD 模块 但我想模拟它的依赖项 而不是加载实际的依赖项 我正在使用 requirejs 我的模块的代码如下所示 define hurp durp function Hurp Durp return foo functi
  • 如何获取核心数据中现有实体(表)的列表

    如何获取核心数据中特定模式 托管对象模型 的现有实体 表 列表 我刚刚开始实施核心数据概念并坚持这些要点 就像是 SELECT COUNT FROM information schema tables WHERE table schema
  • 当我启动 Windows 命令提示符时,我做了什么导致环境变量发生更改?

    我使用的是 Windows 10 x64 我安装了 Anaconda3 如果我启动 C Windows system32 cmd exe 时没有运行任何其他内容 并且在我可以看到的后台中没有任何有趣的内容 则以下内容将添加到控制面板 UI
  • 诊断“功能主机未运行。”在码头工人

    我正在尝试将几个基于 dotnet 的功能应用程序 v3 迁移到 docker 容器 为此 我们使用来自mcr microsoft com azure functions dotnet https hub docker com micros
  • 我如何在使用sequelize的包含模型中使用限制

    我想从关注模型中获取限制为 2 的用户图像 Models const Follow connector define Follow no type Sequelize INTEGER primaryKey true autoIncremen
  • 如何在android中使用kso​​ap2库解析复杂的响应

    大家好 我正在使用 Ksoap2 库解析以下类型的响应 但没有成功获得结果 我的请求如下
  • Excel 2007 从 C# get_Value 始终返回 -2146826265

    我有一个引用 Microsoft Excel 12 0 对象库的小型 C 应用程序 除此之外 它还从 Excel 单元格读取值 它从一些较旧的 Excel xls 文件和一些 2007 文件 xlsx 中读取此值 所有 xls 文件的值都会
  • 如何在 dataTable.js 中转置行和列

    我想在行而不是列中显示我的数据 转置 你可以在这里看到我的例子 var dataSet Tiger Nixon System Architect Edinburgh 5421 2011 04 25 320 800 Garrett Winte
  • 隐藏 CRM 2011 中使用 SSRS 2008 创建的报表的工具栏

    我已经在 SSRS 2008 中创建了报告并将其附加到仪表板 该报告显示良好 除了大约 15 20 的空间被 SSRS 菜单工具栏占用 该工具栏具有打印 缩放等选项 有没有办法最小化该工具栏 我还有一个可以隐藏的参数栏 但默认情况下它不会保
  • Java 中旅行商问题的暴力算法

    我正在学校的数学课上做一个项目 我选择做旅行商问题 这是我一直想进行更多研究的问题 但是 我的暴力求解算法遇到了问题 请前往底部更新查看最新版本代码 如果您知道旅行推销员问题是什么 请跳过本段 尽可能概括地说 TSP 是这样的 您是一名推销