Langford 序列实现 Haskell 或 C
在组合数学中,兰福德配对,也称为兰福德序列,是以下序列的排列: 2n
数字 1, 1, 2, 2, ..., n,
n 其中两个 1 相距 1 个单位,两个 2 相距 2 个单位,并且更一般地,每个数字 k 的两个副本相距 k 个单位。
例如:
n = 3
的 Langford 配对由序列 2,3,1,2,1,3 给出。
- 解决这个问题的好方法是什么 < code>haskell 或
C
- 你能建议一种算法来解决它(不想使用暴力)吗?
------------------------编辑-------------------- --
我们如何定义数学规则以将 @Rafe 的代码放入 haskell 中
In combinatorial mathematics, a Langford pairing, also called a Langford sequence, is a permutation of the sequence of 2n
numbers 1, 1, 2, 2, ..., n,
n in which the two ones are one unit apart, the two twos are two units apart, and more generally the two copies of each number k are k units apart.
For example:
Langford pairing for n = 3
is given by the sequence 2,3,1,2,1,3.
- What is a good method to solve this in
haskell
orC
- Can you suggest an algorithm to solve it (Do not want to use brute force)?
--------------------------EDIT----------------------
How could we define the mathematical rules to put @Rafe's code in haskell
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您想要找到对变量 {p1, p2, ..., pn} 的赋值(其中 pi 是第一次出现“i”的位置),并且每个 pi 都遵循以下约束:
你需要一个合理的搜索策略 这里。一个好的选择是在每个选择点选择具有最小剩余可能值集的 pi。
干杯!
[编辑:第二个附录。]
这是我第一次编写的命令式版本的“主要功能”版本(请参阅下面的第一个附录)。它主要是功能性的,因为与搜索树中每个顶点相关的状态独立于所有其他状态,因此不需要这种类型的踪迹或机制。但是,我使用命令式代码来实现从父域集的副本构建每个新域集。
[编辑:第一个附录。]
我决定编写一个 C# 程序来解决 Langford 问题。它运行得非常快,直到 n = 16,但此后您需要将其更改为使用长整型,因为它将域表示为位模式。
You want to find an assignment to the variables {p1, p2, ..., pn} (where pi is the position of the first occurrence of 'i') with the following constraints holding for each pi:
You need a sensible search strategy here. A good choice is to at each choice point choose the pi with the smallest remaining set of possible values.
Cheers!
[EDIT: second addendum.]
This is a "mostly functional" version of the imperative version I first wrote (see first addendum below). It's mostly functional in the sense that the state associated with each vertex in the search tree is independent of all other state, hence there's no need for a trail or machinery of that kind. However, I have used imperative code to implement the construction of each new domain set from a copy of the parent domain set.
[EDIT: first addendum.]
I decided to write a C# program to solve Langford problems. It runs very quickly up to n = 16, but thereafter you need to change it to use longs since it represents domains as bit patterns.
我无法抗拒。这是我将 Rafe 的代码移植到 Haskell 的版本:
它似乎工作得很好。以下是 GHCi 的一些时间安排:
I couldn't resist. Here's my port of Rafe's code to Haskell:
It seems to work quite well. Here are some timings from GHCi:
由于 Langford 序列通常是为小整数 n 生成的,因此我在该程序中使用 bogosort,并在每次进行 bogosort 时都包含一个检查。当检查完成时,我就完成了。
例如,n=3:
1 2 3 1 2 3
仅对于小整数,这才可以快速工作,因为可能的排列数量为 n!,此处:3*2*1=6。
Since the Langford sequences are usually generated for a small integer n, I use bogosort for this program and include a check everytime it is bogosorted. When the check completes, I'm done.
For example, with n=3:
1 2 3 1 2 3
This will work fast for small integers only since the number of permutaions possible is n!, here: 3*2*1=6.