非重复边的折线 排列问题

问题说明

n条不同边的可选排列,排列成一条折线,使得该折线内部,任意长度大于0的子排列不会相邻出现,这种情况有多少种?
如:有两条边a,b,则其符合的排列有:
a, b, ab, ba, aba, bab, 共6种。
abaa是不符合的,因为aa中a模式重复了。
baba也是不符合的,因为ba的模式重复了。
同理:
n = 1 有 m = 1;
n = 2 有 m = 6;
那么 n = 3 时, m = ?

python代码

import time
def isloops(s:str)->bool:
    '''
    判断字符串是否出现重复模式,或折线是否出现重复的相同环
    '''
    n = len(s)
    flag = False
    if n>1:
        for i in range(1,n):
            #print(i)
            if flag == True:
                break
            else:
                for j in range(i):
                    #print(s[j], s[i])
                    if s[j] == s[i] and s[j:i] == s[i:min(2*i-j,n)]:
                        flag = True
    return flag

t0 = time.time()
s = "123aa2dgshsjskuilsdlbstyjhykje123aa2dgshsjskuilsdlbstyjhykje"
print(isloops(s))
t1 = time.time()
print(t1-t0)

def noloops_one2n(li, n):
    '''
    返回字符串列表中,长度大于0且不超过n的所有非重环排列
    所有最长的字符串都不可能在追加li中的任意一个或已达到追加的个数时,程序停止!
    '''
    li_longest = li # 存放最长字符串
    li_nolongest = [] # 存放非最长字符串
    #longeset = 1 # 最长字符串长度
    t = 0 # 追加的字符个数
    while (li_longest!=[] and t< n-1):
        li_temp = []
        for i in li_longest:
            for j in li:
                if isloops(i+j) == False:
                    li_temp.append(i+j)
        li_nolongest += li_longest
        li_longest = li_temp # 更新最长字符串列表
        t += 1
    if li_longest == []:
        return sorted(li_nolongest)
    else:
        return sorted(li_nolongest+li_longest)


li = ["a", "b", "c"]
n = 40
t0 = time.time()
li_rs = noloops_one2n(li, n)
t1 = time.time()
print(len(li_rs))
print(t1-t0)

# n    m        耗时
# 15   2385
# 16   3183
# 17   4227
# 18   5619
# 19   7449
# 20   9837
# 21   13017
# 22   17163
# 23   22581
# 24   29613
# 25   38811
# 26   50703
# 27   66189
# 28   86409
# 29   112833
# 30   147255
# 31   192117
# 32   250563
# 33   326685
# 34   425961   152秒
# 35   555477   201秒
# 40   2085939  982.375秒
# 45   

部分结果

对于n = 1 ,n = 2 的情况,以上noloops_one2n()函数是符合的,
当对于n = 3的情况,普通计算机很难计算结果:
因为此时的noloops_one2n()内字符串的长度可能超过15,如:cbcacbacabcbacbcacb
用noloops_one2n()来验证的耗时,不断增加。
因此,只能从优化算法来实现计算n=3时的m值。或验证n=3时,m值是否为无限呢?

体会

对于n=1或2的情况,我们很容易就得到了,甚至用笔算就可得到,当对于n=3的情况,
没想到如此之复杂,以至于难倒普通计算机;这让人想起“三体问题”,由上面的问题,
可体会到1点和2点的路径问题是十分简单的,而3点的路径问题(或三体问题中的轨迹问题),就没那么简单了!

是否n=3时,情况为无限?

上面设置的条件可能太弱了,以至于n=3的情况十分难算;当n=3的情况数超过一百万时,也许可能m是否为无穷呢?
召唤数学大神!
召唤失败,自己来:

证明:n = 3时,m=无穷。
在这里插入图片描述
在这里插入图片描述
三条不同边的可选择性的任意长度的排列,使得相邻的任意长度大于0的子排列不会相邻重复出现,
符合以上条件的排列有无数多种。即,由三条不同的边排列而成的任意长的折线中,
符合没有重复相同相邻边环的情况的折线有无数条!
启示:在这么离散的情况下尚且情况无数种,更何况连续的三体问题,三体问题很可能无解!

—结束—220707

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值