标签: combinatorics

如何在不迭代的情况下产生第i个组合/置换

给定任何可迭代的,例如:"ABCDEF"

处理它几乎像数字系统一样:

A B C D E F AA AB AC AD AE AF BA BB BC .... FF AAA AAB ....

我将如何在此列表中找到第i 成员?有效率,而不是通过所有这些计算.我想在这个列表中找到第十亿个(例如)成员.我正在尝试在python中执行此操作,并且我使用2.4(不是选择)可能是相关的,因为我无法访问itertools.

很好,但不是必需的:可以将解决方案推广到伪"混合基数"系统吗?

---结果---

# ------ paul -----
def f0(x, alph='ABCDE'):
    result = ''
    ct = len(alph)
    while x>=0:
        result += alph[x%ct]
        x /= ct-1
    return result[::-1]

# ----- Glenn Maynard -----
import math
def idx_to_length_and_value(n, length):
    chars = 1
    while True:
        cnt = pow(length, chars)
        if cnt > n:
            return chars, n

        chars += …
Run Code Online (Sandbox Code Playgroud)

python combinatorics

9
推荐指数
2
解决办法
1337
查看次数

查找树对称性的算法

我有n个扇区,逆时针枚举0到n-1.这些扇区之间的边界是无限分支(n个).扇区位于复平面中,对于n even,扇区0和n/2被实轴一分为二,扇区间隔均匀.

这些分支在某些点相遇,称为交叉点.每个交叉点与扇区的子集相邻(至少3个).

指定连接点(以预固定顺序,比如从邻近扇区0和1的连接点开始)以及连接点之间的距离,唯一地描述了树.

现在,给定这样的表示,我怎样才能看到它是否与实轴对称?

例如,n = 6,树(0,1,5)(1,2,4,5)(2,3,4)在实线上有三个结,因此它与实轴对称.如果(015)和(1245)之间的距离等于从(1245)到(234)的距离,则这也与虚轴对称.

树(0,1,5)(1,2,5)(2,4,5)(2,3,4)有4个连接点,这在假想轴或实轴上都不是对称的,但它有180个如果表示中前两个和最后两个结之间的距离相等,则旋转对称度.

编辑:以下是所有树木有6个分支,距离为1. http://www2.math.su.se/~per/files/allTrees.pdf

因此,给定描述/表示,我想找到一些算法来确定它是否是真实的,虚构的和180度旋转的对称.最后一个例子具有180度对称性.

编辑2:这实际上是我的研究.我也在mathoverflow上发布了这个问题,但是我在竞赛编程中的日子告诉我这更像是一个IOI任务.mathematica中的代码非常好,但java,python或人类可读的任何其他语言都足够了.

(这些对称性对应于Schroedinger方程中的特殊种类,它在量子力学中具有很好的性质.)

algorithm combinatorics

9
推荐指数
1
解决办法
785
查看次数

计算用两种瓷砖尺寸建造墙的方法

您将获得一组使用3"×1"和4.5"×1"块构建面板的块.

为了结构完整性,块之间的空间不得排列在相邻的行中.

构建7.5"×1"面板的方法有2种,构建7.5"×2"面板的方法有2种,构建12"×3"面板的方法有4种,构建27"×5"面板的方式有7958种. "小组.有多少种方法可以构建48"×10"面板?

这是我到目前为止所理解的:

3 x 14.5 x 1

我已经使用组合公式来找到可以在这个尺寸的面板中排列2个块的所有可能组合

C =选择 - > C(n,k)= n!/ r!(nr)!一次在r组合n组

面板:7.5 x 1 = 2种方式 - >

1(3 x 1块)和1(4.5 x 1块) - >仅使用2个块 - > 2 C 1 = 2路

面板:7.5 x 2 = 2种方式

我也在这里使用过组合

1(3 x 1块)和1(4.5 x 1块) - > 2 C 1 = 2路

面板:12 x 3面板= 2种方式 - >

2(4.5 x 1块)和1(3 x 1块) - > 3 C 1 = 3路

0(4.5 x …

algorithm combinations tiling combinatorics

9
推荐指数
1
解决办法
4475
查看次数

从不均匀分布的集中删除项目

我有一个网站,用户提交问题(每天零,一或多个),投票并每天回答一个问题(更多细节在这里).用户只能通过提交,投票或回答一次来查看问题.

我有一些玩家已经看过的问题.我需要每个月从池中删除30个问题.我需要选择要删除的问题,以便最大限度地提高游泳池中可用问题的数量.

有5个问题的池的例子(需要删除3个):

  • 玩家A遇到过问题1,3和5
  • 玩家B已经看到问题1和4
  • 玩家C见过问题2和4

我虽然要删除顶级玩家所看到的问题,但这个位置会发生变化.按照上面的例子,玩家A只剩下2个问题要玩(2和4).但是,如果我删除1,3和5,情况将是:

  • 玩家A可以玩问题2和4
  • 玩家B可以玩问题2
  • 玩家C不能玩任何东西因为1,3,5被移除而他已经看过2和4.

该解决方案的得分为零,即具有最少可用问题量的玩家具有零可用问题.

在这种情况下,最好删除1,3和4,给出:

  • 玩家A可以玩问题2
  • 玩家B可以玩问题2和5
  • 玩家C可以玩问题5

此解决方案的得分为1,因为有两个可用问题最少的玩家有一个可用问题.

如果数据量很小,我就可以强制解决问题.但是,我有数百个玩家和问题,所以我正在寻找一些算法来解决这个问题.

algorithm combinatorics

9
推荐指数
1
解决办法
500
查看次数

计算具有特定子集大小的集合分区

给定一个具有n个元素的集合,我需要找到该集合中具有几乎相等大小的k个子集的所有分区.

例如,对于具有7个元素和3个子集的集合,我只需要分区,其中有两个子集,每个子​​集有2个元素,一个子集有3个元素.我不希望分区具有1,2和4个元素的子集.

换句话说,一组7个元素有877个可能的分区,但我只对105(?)分区感兴趣,这些分区由2/2/3个元素构成子集:

                                7个元素集的分区的图形表示,其中子集每个具有2个,2个和3个元素.

实际上,n大约为35,这意味着大约有2.81*10 27个分区,"仅" 8,338,573,669,964,101个分区有三个子集.因此,我不可能全部计算它们并趟过去找到我想要的那些.

什么算法只计算感兴趣的分区?(不是分区数,而是每个分区的每个子集中的实际成员.)

ruby algorithm combinations set combinatorics

9
推荐指数
1
解决办法
1396
查看次数

计算可能的"蛇"密码

我们都知道移动设备上的新密码屏幕.它由要连接的点阵组成.

唯一密码是点矢量.这些点可以通过以下限制连接到自己:

  • 一个点只能连接到另一个点
  • 如果目标点和自由点在同一条线上,则将强制线路连接到更近的点.一个例子:

在此输入图像描述

由于之前未连接中间点,因此无法将顶点连接到底部.

第一个限制使得它可以找到树的图形数量.这是我无法找到计算方法的第二个限制.

是否有更简单的方法来计算可能性的数量,或者唯一的方法是生成所有可能性并计算它们?

combinatorics

9
推荐指数
1
解决办法
343
查看次数

如何将PuLP中的弹性子问题用作约束?

在Python PuLP中,线性编程约束可以变成弹性子问题.

http://www.coin-or.org/PuLP/pulp.html?highlight=lpsum#elastic-constraints

解决子问题可以优化距目标值的距离.

当然,目标值是这个子问题的最佳解决方案,但弹性化的全部意义在于我们认为这种解决方案可能是不可行的.

如何将子问题纳入整体问题?我尝试按照添加约束的方式将其添加到问题中,这会引发类型错误.我尝试将它放在目标函数中,这也不起作用.

我在上面的文档或此处托管的示例中找不到任何内容:

https://code.google.com/p/pulp-or/wiki/OptimisationWithPuLP?tm=6

这是我制定的子问题:

capacity = LpConstraint(e=lpSum([ x[m][n] * len(n.items) for n in N ]),
    sense=-1, rhs=30, name=str(random.random()))
stretch_proportion = 30/50
elasticCapacity = capacity.makeElasticSubProblem(penalty=50,
    proportionFreeBoundList=[1,stretch_proportion])
Run Code Online (Sandbox Code Playgroud)

以下是我认为必须将其纳入LP目标的最接近的事情:

def sub(m):
    capacity = LpConstraint(e=lpSum([ x[m][n] * len(n.items) for n in N ]),
        sense=-1, rhs=30, name=str(random.random()))
    stretch_proportion = 30/50
    elasticCapacity = capacity.makeElasticSubProblem(penalty=50,
        proportionFreeBoundList=[1,stretch_proportion])
    elasticCapacity.solve()
    return elasticCapacity.isViolated()
Run Code Online (Sandbox Code Playgroud)

...

prob += lpSum( [ x[m][n] * reduce(op.add, map(D2, [i.l for i in n.items], [j.l for j in n.items]))\
    for n in N …
Run Code Online (Sandbox Code Playgroud)

python linear-programming combinatorics cplex pulp

9
推荐指数
1
解决办法
1338
查看次数

动态编程 - 油漆栅栏算法

有一个有n个帖子的围栏,每个帖子都可以涂上一种k颜色.您必须绘制所有帖子,使得不超过两个相邻的栅栏柱具有相同的颜色.返回可以绘制栅栏的总方式.

diff - 具有不同颜色的组合的数量,
相同 - 具有相同颜色的组合的数量,
n - 发布的数量,
k - 颜色的数量.

对于n = 1:

diff = k;
same = 0;
Run Code Online (Sandbox Code Playgroud)

对于n = 2:

diff = k * (k - 1);
same = k;
Run Code Online (Sandbox Code Playgroud)

对于n = 3:

diff = (k + k * (k - 1)) * (k - 1);
same = k * (k - 1);
Run Code Online (Sandbox Code Playgroud)

最后的公式是:

diff[i] = (diff[i - 1] + diff[i - 2]) * (k - 1);
same[i] =  diff[i - …
Run Code Online (Sandbox Code Playgroud)

algorithm dynamic-programming combinatorics

9
推荐指数
3
解决办法
4659
查看次数

+ -r,+ -s的所有排列

鉴于两个数字rs,我想获得的所有排列的列表n +-rm +-s.例如(带r=3.14s=2.71),

n = 1
m = 1
out = [
    (+r, +s), (+r, -s), (-r, +s), (-r, -s), 
    (+s, +r), (+s, -r), (-s, +r), (-s, -r)
    ]
Run Code Online (Sandbox Code Playgroud)
n = 1
m = 2
out = [
    (+r, +s, +s), (+r, -s, +s), (-r, +s, +s), (-r, -s, +s), ...
    (+s, +r, +s), (-s, +r, +s), (+s, -r, +s), (-s, -r, +s), ...
    ...
    ]
Run Code Online (Sandbox Code Playgroud)

随着itertools.product([+r, …

python combinatorics python-itertools

9
推荐指数
2
解决办法
717
查看次数

查找大小为 k 的所有精确覆盖

我正在寻找一些关于如何解决以下问题的想法。我的主要语言是 R。

描述

我有一个集合S和一组有效子集U。我希望找到US的所有精确覆盖,并且恰好使用k个子集。

例如

  • S = {1,2,3,4}
  • 有效子集U = {{1,2,3,4},{1,2},{3,4},{1,4},{2,3},{1},{4}}
  • k = 1 时,有 1 个解 {1,2,3,4}
  • k = 2 时,有 2 个解 {{{1,2}{3,4}},{{1,4}{2,3}}}
  • k = 3 时,有 1 个解
  • k >= 4 时无解

问题

在我的现实生活示例中,集合S有 500 个元素,U有 500,000 个子集。每个子集都有 1 到 8 个元素。使用线性程序,我发现最小精确覆盖的大小为 70。我正在寻找大小为 70 的所有覆盖。理论上,我可以循环线性程序,为现有解决方案添加约束,以便找到新的解决方案。我怀疑这会很慢。

我还尝试了 R 中修改的跳舞链接方法,如果深度大于k ,则带有停止点。这适用于较小的示例,但似乎会陷入更深入的搜索。我可以通过切换到 C++ 或使用更高级的数据结构(例如 ZDD)来添加一些改进。

任何替代方法的建议将不胜感激。

尝试线性优化

下面的代码是我如何使用线性规划找到最小覆盖范围

library(Rsymphony) …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm performance r combinatorics

9
推荐指数
1
解决办法
351
查看次数