我有一个带有2n个顶点的图形,其中每个边都有一个定义的长度.看起来像 **

**.

我试图找到从u到v的最短路径的长度(边长的最小总和),还有2个额外的限制:

>路径包含的蓝色边数与红色边数相同.
>路径包含的黑边数不大于p.

我想出了一个指数时间算法,我觉得它可行.它遍历所有长度为n-1的二进制组合,它们表示从u开始的路径,方式如下:

> 0是蓝色边缘
> 1是红色边缘
>无论什么时候都有黑边

>组合从1开始.第一个边缘(来自u)然后是左边的第一个黑色边缘.
>组合以0结束.然后最后一个边缘(到v)则是右边的最后一个黑色边缘.
>相邻的数字是不同的.这意味着我们从蓝色边缘变为红色边缘(反之亦然),因此中间有一个黑色边缘.

该算法将忽略不符合前面提到的2个要求的路径,并计算那些路径的长度,然后找到最短的路径.然而,这样做可能会非常慢,我正在寻找一些提示,以提出更快的算法.我怀疑用动态编程可以实现,但我真的不知道从哪里开始.任何帮助将非常感激.谢谢.

解决方法

编辑:不知何故,我查看了问题中的“寻找最短路径”短语,并忽略了原始问题后来澄清意图的“长度”短语.因此,我的下面的答案都存储了大量额外数据,以便在计算完长度后轻松回溯正确的路径.如果您在计算长度后不需要回溯,我的原始版本可以将其第一个维度从N更改为2,只存储一个奇数J和一个偶数J,覆盖任何旧的.我的更快版本可以降低管理J,R交互的所有复杂性,也只是将其外部级别存储为[0..1] [0..H]这些都不会改变时间,但它会大大改变存储.

为了理解我的答案,首先要理解一个原始的N ^ 3答案:(我无法弄清楚我的实际答案是否比粗N ^ 3更好,但它的平均情况要好得多).

注意N必须是奇数,表示为N = 2H 1.(P也必须是奇数.如果给定偶数P,则减去P.但如果N是偶数,则拒绝输入.)

使用3个实际坐标和一个隐含坐标存储成本:
J =第0列到第N列
R =红色边缘0到H的计数
B =黑色边缘0到P的计数
S =边奇数或偶数(S仅为B%1)

我们将计算/存储成本[J] [R] [B]作为使用正好R红色边缘和B黑色边缘到达列J的最低成本方式. (我们也使用了J-R蓝色边缘,但这个事实是多余的).
为方便起见直接写入成本,但通过访问器c(j,r,b)读取它,当r <0 ||时返回BIG b <0,否则返回成本[j] [r] [b]. 那么最里面的一步就是:

If (S)
   cost[J+1][R][B] = red[J]+min( c(J,R-1,B),c(J,B-1)+black[J] );
else
   cost[J+1][R][B] = blue[J]+min( c(J,R,B-1)+black[J] );

将cost [0] [0] [0]初始化为零,对于超原油版本,将所有其他cost [0] [R] [B]初始化为BIG.
你可以超级粗略地循环增加J序列和任何你喜欢的R,B序列计算所有这些.

最后,我们可以找到答案:
min(min(cost [N] [H] [all odd]),black [N] min(cost [N] [H] [all even]))

但是一半的R值并不是问题的真正原因.在前半部分,任何R> J都是不可能的,而在后半部分,任何R< J H-N都是无用的.您可以轻松避免计算这些.使用稍微更聪明的访问器功能,您可以避免在您需要计算的边界情况下使用您从未计算过的位置. 如果任何新成本[J] [R] [B]不小于相同J,R和S但低于B的成本,则新成本是无用数据.如果结构的最后一个dim是map而不是array,我们可以很容易地计算出从存储空间和时间中删除无用数据的序列.但是,减少的时间乘以那些地图的平均大小(最多为P)的对数.所以平均情况下可能是一场胜利,但最糟糕的情况可能是亏损. 稍微考虑一下成本所需的数据类型和BIG所需的值.如果该数据类型中的某些精确值既与最长路径一样大又小到可以存储在该数据类型中的最大值的一半,那么这对于BIG来说是一个微不足道的选择.否则,您需要更仔细的选择以避免任何舍入或截断. 如果你遵循这一切,你可能会理解我认为难以解释的更好的方法之一:这将使元素大小加倍,但将元素数量减少到不到一半.它将std :: map调整的所有好处发送到基本设计而没有log(P)成本.它会缩短平均时间,不会伤害病理时间. 定义包含成本和黑计数的结构CB.主存储器是矢量< vector< CB>.外部向量对于每个有效的J,R组合具有一个位置.这些是规则模式,因此我们可以很容易地计算给定J,R或给定位置的J,R的向量中的位置.但是保持这些增量更快,因此J和R是隐含的而不是直接使用.矢量应保留为其最终大小,约为N ^ 2/4.如果您预先计算H,0的索引可能是最好的

每个内部载体在严格增加的B序列中具有C,B对,并且在每个S内,严格降低C序列.内部向量一次生成一个(在临时向量中),然后复制到它们的最终位置,之后只读取(未修改).在每个内部矢量的生成内,候选C,B对将以增加的B序列生成.因此,在构建临时向量时,保持bestOdd和bestEven的位置.然后,只有当C的C值低于最佳值(或者最佳值尚不存在)时,才将每个候选者推入向量.我们也可以将所有B< P J-N视为B == S,因此该范围内的较低C代替而不是推动. 外部向量的隐含(从未存储)J,R对以(0,0)(1,1)(2,0)开始,以(N-1,H-1)(N)结束-1,H)(N,H).以递增方式处理这些索引是最快的,所以当我们计算隐含位置J,R的向量时,我们将V作为J,R和U的实际位置作为J-1,R和minU的实际位置作为J-1的第一个位置,?和minV作为J的第一个位置,?和minW作为J 1的第一个位置,?
在外循环中,我们将minV复制到minU和minW到minV和V,并且很容易计算新的minW并确定U是以minU还是minU 1开始.

内部循环使V前进到(但不包括)minW,同时每次V前进时前进U,并且在典型位置使用位置U-1处的矢量和位置U处的矢量一起计算位置V的矢量但是你必须涵盖U == minU的特殊情况,其中你不使用U-1处的向量和U == minV的特殊情况,其中你只使用U-1处的向量.

当组合两个向量时,您可以通过B值同步遍历它们,使用一个或另一个根据您遇到的B值生成候选(参见上文).

概念:假设您了解隐含的J,R和显式C,B的值是如何存储的:其含义是在成本C处存在到J列的路径,使用正好R红色分支和B黑色分支并且不存在存在一条到J列的路径,它使用正好的R红色分支和相同的S,其中C’或B’中的一个更好而另一个不差.

c – 在图表中查找最短路径,并附加其他限制的更多相关文章

  1. 如何在Xcode 6.4中使用矢量图像

    解决方法试试这个article.它描述了如何正确保存矢量图像以及如何在Xcode中使用它.需要知道的事项:Xcode将矢量图像切割成所需的尺寸.例如.如果您放置50×50矢量图像,它将创建50×50,100×100,150×150图像.因此,您应该保存x1维度的原始矢量图像.

  2. Swift中的集合类数据结构

    在那种情况下,你将会需要一种基本的集合类数据结构。继续学习,你将会比较成熟的Cocoa数据结构与对应的纯Swift结构的性能。常见iOS数据结构iOS中三种最常用的数据结构是arrays,dictionaries和sets。除了在Swift和Objective-C中旧的Foundation框架中的数据结构,现在又有了新的仅支持Swift版本的数据结构与语言紧密结合在一起。Swift数组是同质的,意味着每一个Swift数组都只包含一种类型的对象。

  3. 是Swift词典的索引性能?即使是异国风情(UUID)?

    我想构建一些将保留以便快速搜索的数组.如果我使用这样的东西:请问查询:在对数时间内执行?如果是,对其他类型是否相同:Float,Double,String.最后,我需要它使用UUID类型,它会工作吗?

  4. android – 线性加速方向,用于跟踪手机的上下移动

    我试图仅在垂直方向上跟踪设备的移动,即向上和向下移动.这应该与设备的方向无关.我已经知道或尝试过的事情就是这些>线性加速度由传感器TYPE_LINEAR_acceleration给出,轴是电话轴,因此跟踪任何特定轴都没有区别.>我尝试应用转置或旋转矢量的倒数(旋转矢量的反转或转置相同),然后尝试跟踪线性加速度矢量的z方向.似乎没有帮助.>我正在尝试使用重力值(TYPE_GraviTY)来制作点积,

  5. android – 需要从Sensor.TYPE_ORIENTATION数据计算旋转矢量

    我需要从Sensor.TYPE_ORIENTATION获得的数据中计算出一个旋转矢量.传感器数据定义如下:>必须重新计算这些值才能成为正确的3d位置:值[0]:方位角,磁北方向和Y轴之间的角度,绕Z轴(0到359).0=北,90=东,180=南,270=西>values1:俯仰,绕X轴旋转(-180到180),当z轴向y轴移动时为正值.>值[2]:滚动,绕Y轴旋转(-90到90),当x轴远离z轴时

  6. android – 如何更改矢量可绘的路径的颜色按钮点击

    通过新的android支持更新,向量可绘制获得向后兼容性.我有一个矢量图像与各种路径.我希望路径的颜色在点击一个按钮或根据输入值以编程方式更改.可以访问矢量路径的name参数吗?

  7. android – 我们如何平铺矢量图像?

    id=187566有没有其他的方法来平铺/重复矢量图像?

  8. Java利用遗传算法求解最短路径问题

    遗传算法(Genetic Algorithm,GA)最早是由美国的John holland于20世纪70年代提出,该算法是根据大自然中生物体进化规律而设计提出的。本文将利用遗传算法求解最短路径问题,需要的可以参考一下

  9. Java利用Dijkstra算法求解拓扑关系最短路径

    迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学迪家迪杰斯特拉于1959年提出的,因此又叫狄克斯特拉算法。本文将利用迪克斯特拉(Dijkstra)算法求拓扑关系最短路径,感兴趣的可以了解一下

  10. PHP实现二维数组中的查找算法小结

    这篇文章主要介绍了PHP实现二维数组中的查找算法,涉及PHP数组遍历、判断、计算等相关操作技巧,需要的朋友可以参考下

随机推荐

  1. 从C到C#的zlib(如何将byte []转换为流并将流转换为byte [])

    我的任务是使用zlib解压缩数据包(已接收),然后使用算法从数据中生成图片好消息是我在C中有代码,但任务是在C#中完成C我正在尝试使用zlib.NET,但所有演示都有该代码进行解压缩(C#)我的问题:我不想在解压缩后保存文件,因为我必须使用C代码中显示的算法.如何将byte[]数组转换为类似于C#zlib代码中的流来解压缩数据然后如何将流转换回字节数组?

  2. 为什么C标准使用不确定的变量未定义?

    垃圾价值存储在哪里,为什么目的?解决方法由于效率原因,C选择不将变量初始化为某些自动值.为了初始化这些数据,必须添加指令.以下是一个例子:产生:虽然这段代码:产生:你可以看到,一个完整的额外的指令用来移动1到x.这对于嵌入式系统来说至关重要.

  3. 如何使用命名管道从c调用WCF方法?

    更新:通过协议here,我无法弄清楚未知的信封记录.我在网上找不到任何例子.原版的:我有以下WCF服务我输出添加5行,所以我知道服务器是否处理了请求与否.我有一个.NET客户端,我曾经测试这一切,一切正常工作预期.现在我想为这个做一个非托管的C客户端.我想出了如何得到管道的名称,并写信给它.我从here下载了协议我可以写信给管道,但我看不懂.每当我尝试读取它,我得到一个ERROR_broKEN_P

  4. “这”是否保证指向C中的对象的开始?

    我想使用fwrite将一个对象写入顺序文件.班级就像当我将一个对象写入文件时.我正在游荡,我可以使用fwrite(this,sizeof(int),2,fo)写入前两个整数.问题是:这是否保证指向对象数据的开始,即使对象的最开始可能存在虚拟表.所以上面的操作是安全的.解决方法这提供了对象的地址,这不一定是第一个成员的地址.唯一的例外是所谓的标准布局类型.从C11标准:(9.2/20)Apointe

  5. c – 编译单元之间共享的全局const对象

    当我声明并初始化一个const对象时.两个cpp文件包含此标头.和当我构建解决方案时,没有链接错误,你会得到什么如果g_Const是一个非const基本类型!PrintInUnit1()和PrintInUnit2()表明在两个编译单元中有两个独立的“g_Const”具有不同的地址,为什么?

  6. 什么是C名称查找在这里? (&amp;GCC对吗?)

    为什么在第三个变体找到func,但是在实例化的时候,原始变体中不合格查找找不到func?解决方法一般规则是,任何不在模板定义上下文中的内容只能通过ADL来获取.换句话说,正常的不合格查找仅在模板定义上下文中执行.因为在定义中间语句时没有声明func,并且func不在与ns::type相关联的命名空间中,所以代码形式不正确.

  7. c – 在输出参数中使用auto

    有没有办法在这种情况下使用auto关键字:当然,不可能知道什么类型的.因此,解决方案应该是以某种方式将它们合并为一个句子.这可用吗?解决方法看起来您希望默认初始化给定函数期望作为参数的类型的对象.您无法使用auto执行此操作,但您可以编写一个特征来提取函数所需的类型,然后使用它来声明您的变量:然后你就像这样使用它:当然,只要你重载函数,这一切都会失败.

  8. 在C中说“推动一切浮动”的确定性方式

    鉴于我更喜欢将程序中的数字保留为int或任何内容,那么使用这些数字的浮点数等效的任意算术最方便的方法是什么?说,我有我想写通过将转换放在解析的运算符树叶中,无需将表达式转化为混乱是否可以使用C风格的宏?应该用新的类和重载操作符完成吗?解决方法这是一个非常复杂的表达.更好地给它一个名字:现在当您使用整数参数调用它时,由于参数的类型为double,因此使用常规的算术转换将参数转换为double用C11lambda……

  9. objective-c – 如何获取未知大小的NSArray的第一个X元素?

    在objectiveC中,我有一个NSArray,我们称之为NSArray*largeArray,我想要获得一个新的NSArray*smallArray,只有第一个x对象…

  10. c – Setprecision是混乱

    我只是想问一下setprecision,因为我有点困惑.这里是代码:其中x=以下:方程的左边是x的值.1.105=1.10应为1.111.115=1.11应为1.121.125=1.12应为1.131.135=1.14是正确的1.145=1.15也正确但如果x是:2.115=2.12是正确的2.125=2.12应为2.13所以为什么在一定的价值是正确的,但有时是错误的?请启发我谢谢解决方法没有理由期望使用浮点系统可以正确地表示您的帖子中的任何常量.因此,一旦将它们存储在一个双变量中,那么你所拥有的确切的一

返回
顶部