用欧拉化求解中文Postman算法

2023-12-08

我想在不存在欧拉循环的图中解决中国邮递员问题。所以基本上我正在寻找图中的一条路径,该路径恰好访问每个边一次,并在同一节点处开始和结束。当且仅当每个节点具有相同数量的进入和离开图的边时,图才会有欧拉循环。显然我的图表没有。

我发现欧拉化(制作欧拉图)可以解决我的问题LINK。任何人都可以建议一个脚本来向图中添加重复的边,以便生成的图没有奇数度的顶点(因此具有欧拉电路)?

这是我的例子:

require(igraph)
require(graph)
require(eulerian)
require(GA)
g1 <- graph(c(1,2, 1,3, 2,4, 2,5, 1,5, 3,5, 4,7, 5,7, 5,8, 3,6, 6,8, 6,9, 9,11, 8,11, 8,10, 8,12, 7,10, 10,12, 11,12), directed = FALSE)
mat <- get.adjacency(g1)
mat <- as.matrix(mat)
rownames(mat) <- LETTERS[1:12]
colnames(mat) <- LETTERS[1:12]
g2 <- as(graphAM(adjMat=mat), "graphNEL")
hasEulerianCycle(g2)

有趣的问题。

您在上面的代码中建议的图表可以具有重复项,从而可以创建欧拉循环。我在下面提供的函数尝试添加最少量的重复边,但如果需要,也可以通过添加新链接轻松破坏图形结构。

enter image description here

你可以运行:

eulerian.g1 <- make.eulerian(g1)$graph

检查该函数对您的图表做了什么:

make.eulerian(g1)$info

请记住:

  1. 这不是only将重复项添加到原始项的图形结构g1图可以构成欧拉循环。想象一下,例如我的函数向后循环图的顶点。
  2. 你的图已经有奇数个度数不均匀的顶点,并且所有顶点都有度数不均匀的邻居来配对。因此,此函数适用于您的特定示例数据。
  3. 即使在正确添加重复项的情况下可能存在欧拉循环的图中,该函数也可能无法仅使用重复项生成图形。这是因为它总是将一个节点与其第一个具有不均匀程度的邻居连接起来。如果您绝对想解决这个问题,那么 MCMC 方法将是最佳选择。

也可以看看this关于概率计算的优秀答案:

这是我的完整脚本中的函数,您可以开箱即用:

library(igraph)

# You asked about this graph
g1 <- graph(c(1,2, 1,3, 2,4, 2,5, 1,5, 3,5, 4,7, 5,7, 5,8, 3,6, 6,8, 6,9, 9,11, 8,11, 8,10, 8,12, 7,10, 10,12, 11,12), directed = FALSE)

# Make a CONNECTED random graph with at least n nodes
connected.erdos.renyi.game <- function(n,m){
       graph <- erdos.renyi.game(n,m,"gnm",directed=FALSE)
       graph <- delete_vertices(graph, (degree(graph) == 0))
}

# This is a random graph
g2 <- connected.erdos.renyi.game(n=12, m=16)



make.eulerian <- function(graph){
       # Carl Hierholzer (1873) had explained how eulirian cycles exist for graphs that are
       # 1) connected, and 2) contain only vertecies with even degrees. Based on this proof
       # the posibility of an eulerian cycle existing in a graph can be tested by testing
       # on these two conditions.
       #
       # This function assumes a connected graph.
       # It adds edges to a graph to ensure that all nodes eventuall has an even numbered. It 
       # tries to maintain the structure of the graph by primarily adding duplicates of already
       # existing edges, but can also add "structurally new" edges if the structure of the 
       # graph does not allow.

       # save output
       info <- c("broken" = FALSE, "Added" = 0, "Successfull" = TRUE)

       # Is a number even
       is.even <- function(x){ x %% 2 == 0 }

       # Graphs with an even number of verticies with uneven degree will more easily converge
       # as eulerian.
       # Should we even out the number of unevenly degreed verticies?
       search.for.even.neighbor <- !is.even(sum(!is.even(degree(graph))))

       # Loop to add edges but never to change nodes that have been set to have even degree
       for(i in V(graph)){
              set.j <- NULL

              #neighbors of i with uneven number of edges are good candidates for new edges
              uneven.neighbors <- !is.even(degree(graph, neighbors(graph,i)))

              if(!is.even(degree(graph,i))){
                     # This node needs a new connection. That edge e(i,j) needs an appropriate j:

                     if(sum(uneven.neighbors) == 0){
                            # There is no neighbor of i that has uneven degree. We will 
                            # have to break the graph structure and connect nodes that
                            # were not connected before:

                            if(sum(!is.even(degree(graph))) > 0){
                                   # Only break the structure if it's absolutely nessecary
                                   # to force the graph into a structure where an euclidian
                                   # cycle exists:
                                   info["Broken"] <- TRUE

                                   # Find candidates for j amongst any unevenly degreed nodes
                                   uneven.candidates <- !is.even(degree(graph, V(graph)))

                                   # Sugest a new edge between i and any node with uneven degree
                                   if(sum(uneven.candidates) != 0){
                                          set.j <- V(graph)[uneven.candidates][[1]]
                                   }else{
                                          # No candidate with uneven degree exists!

                                          # If all edges except the last have even degrees, thith
                                          # function will fail to make the graph eulerian:
                                          info["Successfull"] <- FALSE
                                   }
                            }

                     }else{
                            # A "structurally duplicated" edge may be formed between i one of
                            # the nodes of uneven degree that is already connected to it.

                            # Sugest a new edge between i and its first neighbor with uneven degree
                            set.j <- neighbors(graph, i)[uneven.neighbors][[1]]
                     }
              }else if(search.for.even.neighbor == TRUE & is.null(set.j)){
                     # This only happens once (probably) in the beginning of the loop of
                     # treating graphs that have an uneven number of verticies with uneven
                     # degree. It creates a duplicate between a node and one of its evenly
                     # degreed neighbors (if possible)
                     info["Added"] <- info["Added"] + 1

                     set.j <- neighbors(graph, i)[ !uneven.neighbors ][[1]]
                     # Never do this again if a j is correctly set
                     if(!is.null(set.j)){search.for.even.neighbor <- FALSE}
              }

              # Add that a new edge to alter degrees in the desired direction
              # OBS: as.numeric() since set.j might be NULL
              if(!is.null(set.j)){
                     # i may not link to j
                     if(i != set.j){
                            graph <- add_edges(graph, edges=c(i, set.j))
                            info["Added"] <- info["Added"] + 1
                     }
              }
       }

       # return the graph
       (list("graph" = graph, "info" = info))
}

# Look at what we did
eulerian <- make.eulerian(g1)
eulerian$info
g <- eulerian$graph

par(mfrow=c(1,2))
plot(g1)
plot(g)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用欧拉化求解中文Postman算法 的相关文章

  • 零膨胀泊松分布的经验和理论分布图

    以下是我正在研究的一种数据集 data lt c 0 1 0 11 2 0 3 0 0 2 1 3 1 0 1 0 0 0 2 3 0 0 0 8 1 1 1 0 1 1 2 7 0 0 0 5 2 3 6 1 1 5 2 9 0 0 1
  • 循环遍历列并将字符串长度添加为新列

    我有一个包含多列的数据框 并且希望为每个列输出一个单独的列 其中包含每行的长度 我试图迭代列名称 并为每列输出一个附加有 length 的相应列 例如 col1 col2 将转到 col1 列2 col1 长度 列2 长度 我正在使用的代码
  • 在闪亮仪表板中显示/隐藏菜单项

    当进入应用程序时 我需要隐藏一个菜单项 当用户选择某个值时 菜单项必须出现 我努力了shinyjs功能hidden 并且它隐藏了一个 menuItem 但是当使用show or toggle 菜单项不会出现 我发现了Rshinydashbo
  • glmnet R 包中的 cv.glmnet 出现“drop(y %*% rep(1, nc)) 错误”错误

    我有一个返回 cv glmnet 模型的 auc 值的函数 尽管不是大多数时间 但在执行 cv glmnet 函数时 它经常返回以下错误 下降误差 y 代表 1 NC 在为函数 drop 选择方法时评估参数 x 时出错 y 中的错误 rep
  • lme4:如何指定 2 个与随机截距的相关性,而不添加随机斜率之间的相关性

    重新发布自stats stackexchange com https stats stackexchange com q 195385 33560 我试图在 R 的 lme4 包中指定一个模型 其中随机截距和随机斜率之间有 2 个相关性 但
  • 数据集子集的回归

    我想做以下事情并需要一些帮助 分别计算 身高 与 年龄 的斜率和截距 lm Height Age 一 每个人 二 性别 并创建一个包含结果 斜率和截距 的表 我可以使用 申请 吗 在下一步中 我想做一个统计测试 以确定性别之间的斜率和截距是
  • 将线条剪裁到绘图区域并在绘图区域外显示文本

    我想限制绘图的可见 y 范围 为了保留超出此范围的值 我需要设置oob 出界 to rescale none这效果很好 不过 我还想在图外的页边空白处添加一些文本 为了做到这一点 我需要关闭剪辑 这会导致超出范围的值被绘制在绘图区域之外的边
  • 添加不同的标签以在 ggplot R 中的堆积条形图中显示总计?

    我的问题有点类似 如何添加文本标签以显示ggplot中堆叠比例条的每个条中的总数n https stackoverflow com questions 65201095 how to add text label to show total
  • 使用 dplyr 和 ggplot 绘制包括负值的多面水平发散堆积条形图

    我希望这个例子能够让人清楚 我想要堆叠条形 其中中间条形跨越 0 因为它代表中性值 这与李克特量表一起使用 为了重现性 我使用钻石数据集 以下示例与我的用例足够接近 并演示了我很难以正确的顺序获取 好 或 正 数据 因此中性最接近 0 这是
  • 如何使用 ggplot 绘制矩阵图

    我想可视化一个矩阵 MAT lt matrix c 100 7 0 0 49 0 0 0 49 nrow 3 ncol 3 gt MAT 1 2 3 1 100 7 0 2 0 49 0 3 0 0 49 然而 标准方法不能正确地对小数字进
  • R:使用 as.formula 修复模型中的模型调用

    我有一个gls模型 其中我将公式 来自另一个对象 分配给模型 equation lt as formula aic obj row model gt equation temp avg I year 1950 mod1 lt gls equ
  • R 包“raster”在搜索“terra”最新版本时无法上传

    我正在 Windows 10 中使用 RStudio 2021 09 2 中的 R 4 1 2 工作 我正在处理空间数据 包括矢量和栅格 但三天前命令库 栅格 开始向我发出此警告 错误 loadNamespace i c lib loc l
  • 对 R/Sweave 进行编程以获得正确的 \Sexpr 输出

    我在为 Sweave 进行 R 编程时遇到了一些问题 rstats twitter 小组经常指出这里 所以我想我应该把这个问题向大家提出 我是一名分析师 而不是程序员 所以在我的第一篇文章中请放轻松 问题是 我正在使用 R 在 Sweave
  • 是否可以在 R 中创建自定义 pch 形状?

    R 中的许多绘图函数都使用图形参数pch指定数据点的形状 根据R 文档 https www rdocumentation org packages graphics versions 3 6 2 topics points 有 26 个矢量
  • 当 header=TRUE 时 read.fwf 出错

    我的模拟数据如下所示 LastName Date email CreditCardNum AgeZip Amount Paul 21 02 14 email protected cdn cgi l email protection 4241
  • 如何在 R 中使用 msgbox [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何在中显示消息框R 我正在寻找类似的东西msgbox在 VBA 中 因此我可以向用户发出有关问题的警报 此外 我想允许一些用户交互 例如
  • 根据第二个数据帧中的匹配创建新列

    如果有两个数据框 top3df http dpaste com 1709875 and qw qw lt structure list id structure 1 25 Label c w01 w02 w03 w04 w05 w06 w0
  • 将英寸高度的字符向量转换为厘米?

    我得到一个字符向量 tibble H c 6 2 5 10 5 5 5 1 5 5 5 4 我想将其转换为厘米 请告知我该怎么做 有几种方法可以使用 1 阅读与fread粘贴到单个字符串后 library data table fread
  • R 中的微秒时间戳

    在 CSV 文件中 我有几列 其中一列有时间戳 其中每个时间戳是今天午夜经过的微秒 每个 csv 文件仅包含一天内的数据 因此这并不含糊 我的问题是 如何将这些微秒时间戳解析为 R 多谢 我的 CSV 文件的一部分 34201881666
  • 如何解决 R 估计中的整数溢出错误

    我正在尝试使用估计模型speedglm在 R 中 数据集很大 约 6988 万行和 38 列 行数和列数相乘得到约 27 亿 超出了整数限制 我无法提供数据 但以下示例重现了该问题 library speedglm large exampl

随机推荐

  • python unittest 的 setUp 函数不使用在类上声明的模拟

    所以我正在编写单元测试 但我在设置函数方面遇到了问题 据我所知 它应该在函数之前执行代码 因此我可以将任何重复的内容放在那里 然而 这个函数似乎并没有将我创建的模拟应用为整个类的补丁装饰器 这是我希望它看起来像的一小部分 patch geo
  • Java MySQL的executeUpdate()对于INSERT ON ON DUPLICATE KEY UPDATE返回什么?

    我在网上查了大约3个小时 仍然找不到这个问题的答案 爪哇文档还有这个tutorial says 返回 1 SQL 数据操作语言的行计数 DML 语句或 2 0 表示不返回任何内容的 SQL 语句 那么这意味着 插入 1 行无重复项 gt 1
  • 尽管已安装,但未找到底图数据雇用

    我和这个帖子有同样的问题 使用辅助脚本中的导入来声明 var 可由另一个函数使用 但答案在我这边不起作用 对于上下文 basemap and basemap data hires已安装 但使用时resolution f 它会触发以下错误 O
  • 将 MJPEG 流式传输到文件,但仅保留最后 x 分钟

    我希望在检测到运动时记录 MJPEG 流 但我的运动检测通知比运动发生晚了几秒钟 为了解决这个问题 我想一直录制 但只保留最后 2 分钟的镜头 现在我正在使用 cURL 无限下载 但我一直在思考如何让它将文件的前面正确地修剪为 2 分钟 L
  • 纯CSS棋盘,带有div且没有类或id,可能吗?

    我有以下布局 div div div div div div div div div div div div div div div div div div div div div div div div div div div div d
  • 通知操作图标未显示

    我尝试在 Android 中显示通知 并使用来自这个链接 在一些消息来源中 人们说图标应该是全白色的 而一些消息来源说我应该使用 png代替vector 我尝试了所有这些方法 但没有人帮助我 我尝试这段代码 Notification new
  • 搜索数据库 JavaScript

    我已经消除了所有语法错误 但无法检索任何数据 任何帮助将不胜感激 db 变量存储我正在查找的视频数组 它是一个单独的 js 文件 数据库 var db JavaScript Version History http http wddbs c
  • 有人可以帮我使用 livestream 的 api 发出跨域 xml 请求吗?

    我正在尝试使用 livestream 非常有用的移动 api 位于http www livestream com userguide title Mobile API Requesting a mobile stream发出 xml 请求
  • 如何在 django 中为每个模型关联多种类型的标签

    我对 django 不太陌生 并试图找到最好的方法来做事 而不是自己编写所有内容 我正在开发一个模型 其中需要将多种类型的标签与模型关联 然后我想使用多个过滤条件检索对象 我看到在 django tagging 中 标签是按模型存储的 所以
  • 当两个应用程序都使用嵌入式 activemq 时,如何将 Jms 消息从一个 spring-boot 应用程序发送到另一个应用程序

    我有两个 spring boot 应用程序 在接收器应用程序的 Application java 中我有 Bean public JmsListenerContainerFactory
  • 在 WebAPI 中将 HttpResponseMessage 作为 excel 文件返回的问题

    我创建了 WebAPI 它使用 closexml nuget 返回一个 excel 文件 基本上它改变了我的DataTable脱颖而出 我指的是下面的几个链接 如何在 ASP NET WebAPI 中返回文件 FileContentResu
  • 在 Flutter 中访问 Firebase 存储

    我对 Flutter 相当陌生 以前从未使用过 Firebase 所以如果有明显的解决方案 我深表歉意 我正在开发一个 Flutter 应用程序 其中涉及记录表单提交并将其提交到中央位置 Firebase Storage 似乎很合适 因为据
  • 获取 GeoPandas 中几何图形之间的交集计数

    是否可以使用 GeoPandas 对象获取两个几何图形之间的交集计数 也就是说 我想计算一个 GeoDataFrame 中与另一个 GeoDataFrame 中的每个多边形相交的多边形或线串的数量 在浏览 GeoPandas 文档时 我没有
  • 寻找 C# 注册表类 [已关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 寻找包装调用以执行以下操作的 C 类 读取和写入键值 读取和写入密钥条目 枚举键中的条目 这个很重要 例如 需要列出以下位置的所有条目 HKEY L
  • 如何使用装饰器将变量注入作用域?

    免责声明 可能有更多的Python方式来做我想做的事情 但我想知道Python的作用域在这里是如何工作的 我正在尝试找到一种方法来制作一个装饰器 该装饰器可以执行诸如将名称注入另一个函数的作用域之类的操作 这样该名称就不会泄漏到装饰器的作用
  • 根据参考重新排序多索引数据框列

    我有一个多索引数据框 其名称附加到列级别 数据表看起来像这样 df1 TIME TMC 111N1 111P2 111N3 111P4 DATE EPOCH 0 143 113 103 NaN 1 183 NaN NaN NaN 2 NaN
  • CodeIgniter 与 PHPExcel 致命错误无法重新声明类 IOFactory

    我正在尝试将 PHPExcel 与 CodeIgniter 一起使用 我的问题是当我想使用下面的方法时 我得到了PHP 致命错误 无法重新声明类 IOFactory 如果您不确定文件类型 则可以在使用 createReader 方法实例化读
  • 在切片末尾工作是否惯用?

    我正在阅读 Go 的compress flate包 我发现了这段奇怪的代码 1 n int32 len list list list 0 n 1 list n maxNode 在上下文中 list保证指向后面有更多数据的数组 这是一个私有函
  • 如何在 Laravel PHP 框架中合并两个集合而不丢失(丢失)键?

    我是 Laravel PHP 的新手 我正在做我的个人 玩具项目 我遇到了一个我已经在 Google 上搜索了很长时间的问题 但是 我无法找出完美的解决方案 问题是 我有两个集合 questions and answers 我想将它们合并到
  • 用欧拉化求解中文Postman算法

    我想在不存在欧拉循环的图中解决中国邮递员问题 所以基本上我正在寻找图中的一条路径 该路径恰好访问每个边一次 并在同一节点处开始和结束 当且仅当每个节点具有相同数量的进入和离开图的边时 图才会有欧拉循环 显然我的图表没有 我发现欧拉化 制作欧