- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到了以下难题,无法在 Picat 中制定解决方案:
You will generate 5-digit numbers, where each digit is in
1..5
and different from the others, with the constraint that any three adjacent digits used in one number can’t be used in another number.How many different numbers can be obtained according to this rule?
12345
,则其他数字不能包含
123
、
345
或
456
,因此以下形式的所有数字都被禁止进入链:
123AB, A123B, AB123,
234AB, A234B, AB234,
345AB, A345B, AB345,
我对如何存储这些“禁止”子列表以及在构建数字列表时如何根据它们检查每个数字感到非常困惑。
import cp.
import util.
valid(Ls, Cd) ?=>
% verify that the head of the chain is correct?
% so the chain consists of permutations of 12345
foreach (L in Ls)
len(L) = 5,
permutation(L, [1,2,3,4,5])
end,
% generate the candidate
Cd = new_list(5),
permutation(Cd, [1,2,3,4,5]),
% check the candidate against the head of the chain
foreach (L in Ls)
not sublist([L[1],L[2],L[3]], Cd),
not sublist([L[2],L[3],L[4]], Cd),
not sublist([L[3],L[4],L[5]], Cd)
end,
solve(Ls),
printf("Cd: %w\n", Cd),
fail,
nl.
% so that 3 element sublists of 12345 are 123,234 and 345.
sublist(X, S) =>
append(_, T , S),
append(X, _ , T),
X.len #>= 0.
% seems to work, the candidates don't have the banned triplets as sublists.
% so in this case the banned triplets would be
% 123,234,345,543,432,321
go => valid([[1,2,3,4,5], [5,4,3,2,1]], _).
main => go.
评论:情况不对称确实很有趣。如果我们分析状态:
[12345,12435,12534,13245,13425,13524,14235,
14325,14523,21543,24153,25413,35421,43152]
我们看到有效/可以附加到此链的三个候选对象是:
Cd1: [5,3,2,1,4]
Cd2: [4,5,3,1,2]
Cd3: [4,5,3,2,1]
显然,如果我们选择
Cd3
,因为它同时包含
453
和
532
它不允许我们选择它之后的任何候选者,所以链结束于
N=15
。
Cd1
,它会排除
Cd3
但仍然保留
Cd2
,所以链继续到
N=16
。
Cd2
,它会排除
Cd3
但仍保留
Cd1
,因此
N=16
也是可能的。
最佳答案
这是带有 中的模型的 Picat 模型更新 4 和 更新 5 和 更新 6 :http://hakank.org/picat/generating_numbers.pi
更新 6 :这可能是我会写的约束模型,如果不是从一开始就对问题的错误假设误入歧途......这是一种更直接的方法(从约束程序员的角度来看)并且不要使用 permutations/1
等等。
比稍慢更新 5 (使用 sat 求解器为 3.7 秒,而 更新 4 模型为 3.3 秒)。然而,cp 求解器在此模型上要慢得多。
在上面引用的 Picat 程序中,它的模型是 go3/0
. (最快的模型是 go/0
。)
该方法:
go3 ?=>
nolog,
N = 5,
M = 20,
X = new_array(M,N),
X :: 1..N,
% symmetry breaking
X[1,1] #= 1,X[1,2] #= 2,X[1,3] #= 3,X[1,4] #= 4,X[1,5] #= 5,
foreach(I in 1..M)
all_distinct([X[I,K] : K in 1..N]),
foreach(J in 1..I-1)
foreach(A in 0..2)
foreach(B in 0..2)
sum([X[I,K+A] #= X[J,K+B] : K in 1..3]) #< 3
end
end
end
end,
solve($[ff,split],X),
foreach(P in X)
println(P.to_list)
end,
println(numbers=[[I.to_string : I in T].join('').to_int : T in X]),
nl.
go3 => true.
第一个解决方案(3.7s 与 sat):
[12345,35421,23154,25314,43512,32415,32541,12453,21534,14523,
34251,14235,54312,45132,51432,52134,53214,34125,41352,15243]
更新 5 这是一种更快的方法:大约 3.3 秒找到第一个解决方案,而
中的方法需要 1 分钟 25 秒。更新 4 .
Ps
) 中,构建一个 120 x 120 矩阵 A
0/1 其中 A[P1,P2] = 1
意味着 Ps[P1]
和 Ps[P2]
是兼容的,即它们没有共同的三元组 X
长度为 120,其中 X[I] = 1
表示排列 Ps[I]
应该在序列中(或者更确切地说是“设置”,因为排列的顺序没有区别)。 X[I]*X[J] #= 1 #=> A[I,J]
是一种“奇怪”的说法,两者都是 X[I]
和 X[J]
如果 A[I,J] #= 1
应该在序列中. go ?=>
N = 5,
Ps = permutations(1..N),
PsLen = Ps.len,
% Compatibility matrix:
% A[P1,P2] = 1 if they don't have any common triple
A = new_array(PsLen,PsLen),
bind_vars(A,0),
foreach(P1 in 1..PsLen)
A[P1,P1] := 1,
foreach(P2 in 1..PsLen, P1 < P2)
if check_perms(Ps[P1],Ps[P2]) then
A[P1,P2] := 1,
A[P2,P1] := 1
end
end
end,
M = 20, % length 20 sequence
println(m=M),
% List of 0/1:
% 1 means that it should be in the sequence
X = new_list(PsLen),
X :: 0..1,
sum(X) #= M, % We want M 1s
X[1] #= 1, % symmetry breaking
foreach(I in 1..PsLen)
foreach(J in 1..I-1)
X[I]*X[J] #= 1 #=> A[I,J]
end
end,
solve($[degree,updown],X),
println(x=X),
Perms = [Ps[I] : I in 1..PsLen, X[I]==1],
foreach(P in Perms)
println(P)
end,
println(numbers=[[I.to_string : I in T].join('').to_int : T in Perms]),
% println("Checking:"),
% foreach(I in 1..Perms.len, J in 1..I-1)
% if not check_perms(Perms[I],Perms[J]) then
% println("ERROR!"=Perms[I]=Perms[J])
% end
% end,
nl,
% fail,
nl.
go4 => true.
% list version
check2(Forbidden,Tri) =>
foreach(PP in Tri)
not membchk(PP,Forbidden)
end.
check_perms(Perm1,Perm2) =>
tri(Perm1,Tri1),
tri(Perm2,Tri2),
foreach(PP in Tri2)
not membchk(PP,Tri1)
end,
foreach(PP in Tri1)
not membchk(PP,Tri2)
end.
tri(P,Tri) :- Tri=[P[K..K+2] : K in 1..3].
这是第一个解决方案:
x = [1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1]
[1,2,3,4,5]
[3,2,4,1,5]
[3,4,2,5,1]
[2,1,4,3,5]
[4,3,1,2,5]
[4,1,3,5,2]
[2,4,5,1,3]
[4,2,1,5,3]
[4,5,2,3,1]
[1,4,5,3,2]
[2,3,5,4,1]
[1,3,2,5,4]
[3,5,1,2,4]
[3,1,5,4,2]
[2,5,3,1,4]
[5,2,1,3,4]
[5,3,4,1,2]
[1,5,2,4,3]
[5,1,4,2,3]
[5,4,3,2,1]
numbers = [12345,32415,34251,21435,43125,41352,24513,42153,45231,14532,23541,13254,35124,31542,25314,52134,53412,15243,51423,54321]
CPU time 3.325 seconds. Backtracks: 233455
更新 4 正如评论中提到的,这是一个约束模型,它找到了一个长度为 20 的序列。
[12345,32451,43125,15423,23541,41532,52134,
24135,14352,31524,54321,25314,42513,51243,
34215,53412,45231,35142,21453,13254]
这个使用 sat 解算器的模型需要大约 1 分 25 秒才能开始这个序列。它比使用回溯的先前版本中“简单”使用列表处理要复杂一些,这就是这些方法中获得最大长度序列的问题。
matrix_element/4
用于连接Y
中的三元组矩阵和 Z
中的数字. Z
中),因此我们可以确保它们是不同的。 cp
模块在更简单的实例(例如长度高达 16)上更快,但对于更大的实例(> 16)然后 sat
往往会好得多。 import sat, util.
go3 ?=>
nolog,
N = 5,
Ps = permutations(1..N),
PLen = Ps.len,
% Find the triplets
TripletsMap = new_map(),
foreach(P in Ps)
tri(P,Tri),
foreach(T in Tri) TripletsMap.put(T,1) end
end,
% Convert to numbers (123..543)
Triplets = [T[1]*100+T[2]*10+T[3] : T in keys(TripletsMap)].sort,
% length of sequence
member(M,20..20),
println(m=M),
% Indices of the selected permutation
X = new_list(M),
X :: 1..PLen,
% The triplets
Z = new_list(M*3),
Z :: Triplets,
% Y contains the "shortcuts" to the permutations
Y = new_array(M,5),
Y :: 1..N,
all_distinct(X),
all_distinct(Z),
X[1] #= 1, % symmetry breaking
% Fill Y
foreach(I in 1..M)
element(I,X,II),
foreach(K in 1..5)
matrix_element(Ps,II,K,Y[I,K])
end
end,
% Convert triplet list in Y <-> triplet number in Z
C = 1,
foreach(I in 1..M)
foreach(J in 1..3)
to_num([Y[I,J+K] : K in 0..2],10,Z[C]),
C := C+1
end
end,
Vars = Z ++ X ++ Y.vars,
solve($[constr,updown,split],Vars) % split (SAT)
PsX = [Ps[I] : I in X],
println(numbers=[[I.to_string : I in Ps[T]].join('').to_int : T in X]),
nl.
go3 => true.
tri(P,Tri) :- Tri=[P[K..K+2] : K in 1..3].
% converts a number Num to/from a list of integer
% List given a base Base
to_num(List, Base, Num) =>
Len = length(List),
Num #= sum([List[I]*Base**(Len-I) : I in 1..Len]).
而且我仍然认为有一些算法方法可以立即解决这个问题......
permutation(1..5,Next)
所以所有数字都有一个变化要选择。
go2 ?=>
Ps = permutations(1..5),
Forbidden = [],
gen(Ps,Forbidden,L),
println([[I.to_string : I in C].join('').to_int : C in L]),
println(len=L.len),
nl,
fail,
nl.
go2 => true.
%
% Create triplets (Tri) from the permutation P
%
tri(P,Tri) :- Tri=[P[K..K+2] : K in 1..3].
% list version
check2(Forbidden,Tri) =>
foreach(PP in Tri)
not membchk(PP,Forbidden)
end.
% list version
add_forbidden_triplets2(Forbidden,Triplets) = F =>
foreach(T in Triplets)
Forbidden := Forbidden ++ [T]
end,
F = Forbidden.
gen([],_Forbidden,[]).
gen(Ps,Forbidden,[Next|L]) :-
permutation(1..5,Next),
not membchk(Next,L),
tri(Next,Tri),
check2(Forbidden,Tri),
% Forbidden := add_forbidden_triplets2(Forbidden,Tri),
Forbidden2 = add_forbidden_triplets2(Forbidden,Tri), % better
Ps2 = [PP : PP in Ps, PP != Next],
gen(Ps2,Forbidden2,L).
gen(_Ps,Forbidden,[]) :-
not (permutation(1..5,Next),
tri(Next,Tri),
check2(Forbidden,Tri)).
第一个解决方案的长度为 16:
[12345,12435,12534,13245,13425,13524,14235,14325,
14523,21543,24153,25413,35421,43152,45312,53214]
下一个解决方案(通过回溯)是 - 然而 - 长度为 15:
[12345,12435,12534,13245,13425,13524,14235,14325,
14523,21543,24153,25413,35421,43152,45321]
所以我 - 仍然 - 不确定 16 是否是最大长度。
Forbidden
在循环中(
add_forbidden_triplets(Forbidden, Triplets)
。程序更新如下。
[12345,23145,13245,13425,34125,12435,24135,14235,
14325,43152,42153,45213,45312,53214]
len = 14
现在它变得有趣了,因为其他序列的长度(具有不同的起始编号)大约是 12..17 个数字。这是违反直觉的,因为这些东西应该是对称的,不是吗?
Forbidden
中。 .当没有任何可用号码时(当
Found
为假)时,序列结束。
go ?=>
N = 5,
Ps = permutations(1..N),
select(P,Ps,Ps2),
L = [P],
tri(P,Triplets),
Forbidden = new_map(), % keep forbidden triplets in a hash table
add_forbidden_triplets(Forbidden, Triplets), % added in **Update2**
Found = true,
while(Found == true)
if select(NextP,Ps2,Ps3), tri(NextP,PTri), check(Forbidden,PTri) then
L := L ++ [NextP],
add_forbidden_triplets(Forbidden, PTri),
P := NextP,
Ps2 := Ps3
else
Found := false
end
end,
println([[I.to_string : I in C].join('').to_int : C in L]),
println(len=L.len),
nl,
% fail, % generate a new solution
nl.
go => true.
%
% Create triplets (Tri) from the permutation P
%
tri(P,Tri) :- Tri=[P[K..K+2] : K in 1..3].
%
% Check if Tri contain some forbidden triplet
%
check(Forbidden,Tri) =>
foreach(PP in Tri)
not Forbidden.has_key(PP)
end.
%
% Add triplets to Forbidden map
%
add_forbidden_triplets(Forbidden,Triplets) =>
foreach(T in Triplets)
Forbidden.put(T,1)
end.
这是第一个解决方案:
[12345,23145,13245,31245,32145,32415,32451,13425,
1425,34125,34215,34251,31452,34152,12435,21435,
24135,24315,24351,14235,42135,42315,42351,14325,
41325,43125,43215,43251,14352,41352,43152,43512,
43521,12453,21453,24153,24513,24531,14253,41253,
42153,42513,42531,14523,41523,45213,45231,14532,
41532,45132,45312,45321,21354,23154,23514,23541,
13254,31254,32154,32514,32541,13524,31524,35124,
35214,35241,13542,31542,35142,35412,35421,12534,
21534,25134,25314,25341,52134,52314,15324,51324,
53124,53214,53241,15342,51342,53142,53412,53421,
12543,21543,25143,25413,25431,15243,51243,52143,
52413,52431,15423,51423,54213,54231,15432,51432,
54132,54312,54321]
len = 107
这是我的原始答案 :
solve/1
在您的程序中,因为没有任何限制。
permutations/1
(来自
util
模块)首先生成所有 120 个排列(
5!=120
)并不确定地选择一些剩余的排列(使用
select/3
)。使用
tri/2
来检查允许的后继者。生成所有三元组和
check/2
检查是否有常见的三胞胎。
import util.
% Using foreach loop
go ?=>
N = 5,
Ps = permutations(1..N),
select(P,Ps,Ps2), % pick the first number (i.e. 12345)
L := [P],
while(Ps2 != [])
tri(P,Forbidden),
select(NextP,Ps2,Ps3),
tri(NextP,PTri),
check(Forbidden,PTri),
L := L ++ [NextP],
P := NextP,
Ps2 := Ps3
end,
println([[I.to_string : I in C].join('').to_int : C in L]), % convert to number
nl.
go => true.
% Using genx/2 ("Prolog style")
go3 ?=>
Ps = permutations(1..5),
PLen = Ps.len,
println(plen=PLen),
genx(Ps,L),
println(len=L.len),
nl.
go3 => true.
% Create triplets (Tri) from the permutation P
tri(P,Tri) :- Tri=[P[K..K+2] : K in 1..3].
% Check if Tri contain some forbidden triplet
check(Forbidden,Tri) =>
foreach(PP in Tri)
not membchk(PP,Forbidden)
end.
% This is the same principal logic as used in go/0
% but in "Prolog style"
genx([],[]).
genx([P],[P]).
genx([P|Ps],[P|L]) :-
tri(P,Forbidden),
select(Next,Ps,Ps2), % pick a new available number
tri(Next,Tri),
check(Forbidden,Tri),
genx([Next|Ps2],L).
这是
go/0
的输出(转换为数字):
[12345,23145,21345,23415,13245,23451,31245,32145,32415,
13425,32451,31425,34125,34215,13452,34251,31452,34152,
34512,12435,34521,21435,24135,24315,14235,24351,41235,
42135,42315,14325,42351,41325,43125,43215,14352,43251,
41352,43152,43512,12453,43521,21453,24153,24513,14253,
24531,41253,42153,42513,14523,42531,41523,45123,45213,
14532,45231,41532,45132,45312,12354,45321,21354,23154,
23514,13254,23541,31254,32154,32514,13524,32541,31524,
35124,35214,13542,35241,31542,35142,35412,12534,35421,
21534,25134,25314,15234,25341,51234,52134,52314,15324,
52341,51324,53124,53214,15342,53241,51342,53142,53412,
12543,53421,21543,25143,25413,15243,25431,51243,52143,
52413,15423,52431,51423,54123,54213,15432,54231,51432,
54312,54132,54321]
关于list - "Generating Numbers"拼图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66127644/
我是 Julia 的新手。 我主要用python编程。 在 python 中, 如果你想迭代大量的值, 通常构造一个所谓的生成器来节省内存使用。 这是一个示例代码: def generator(N):
这个问题很奇怪。我试图直接在 build.gradle 中添加一个字符串,因为我需要它来使用 Tray 库 ( https://github.com/grandcentrix/tray )。在我的第一
我正在尝试在我的新 symfony3 项目中使用生成 CRUD 功能。我创建了一个名为 AdminBundle 的 bundle ,其中包含生成器、实体测试以及生成器,所有这些都处理得很好。我检查了我
我尝试理解生成器,但我发现了一个我无法遵循的示例。 // First Generator function* Colors () { yield "blue"; yield* MoreColo
我将制作一款完全由程序生成的空间/交易/战斗游戏。但是,我知道将整个星系的所有细节存储在内存中是不可行的。因此,我一直认为我可以使用种子来生成太阳系,并且从该太阳系,您可以使用跳跃门前往其他太阳系。问
我在 Eclipse Helios 中使用 MyBatis Generator (MyBatis Generator 1.3.1.201101032122),但每次我自动生成持久类时,生成器都会删除属
@GenerateInterface class A {} @GenerateInterface class B { void setA(IA a) {} } 我的注释处理器应该生成这些接口(in
我刚刚在一个空目录中安装了 yeoman,它打印出一个错误。这就是我所做的: npm i yo -g npm i generator-webapp -g 之后我抛出一个错误: require('yeo
我正在使用 NReco PDFGenerator 从 HTML 字符串创建 PDF 文档。当表格被分页符拆分时,表格标题与表格中的下一行重叠(见下图)。 有想法该怎么解决这个吗? 最佳答案 我发现这是
我有这个命名空间: namespace :manage do # Directs /manage/products/* to Manage::ProductsController
我有一个 Open API 3 规范的 yaml 文件,它有一些 x- 前缀的属性。我正在尝试使用 openapi-generator-cli 生成一个 Angular Typescript SDK。
我有一个返回生成器的函数。目前它使用yield from: function foo() { $generator = getGenerator(); // some other st
我选择Symfony2 docs 。据说添加 /** * @ORM\Entity(repositoryClass="Acme\StoreBundle\Entity\ProductRepository
运行命令生成新的 rails 项目: $ rails generate controller home index 以上将创建四个新的 Rails 项目:generate、controller、hom
我们实际上已经将jvm内存增加到了256M,现在老年代看起来很小,但Perm Generation相当高,接近80%。通过 jstat 捕获的示例数据如下。高永久代意味着什么? Timestamp
class Invoice def Invoice.generate(order_id, charge_amount, credited_amount = 0.0) Invoice.new
我在写 this comparison为了帮助人们理解所有这些废话,目前看来,generator-angular 的好处和值(value)只是您使用 generator-angular-fullsta
我有一个包含以下代码段的 OpenAPI 规范文档(我无法控制): servers: - url: http://www.[someservice].com/api 我正在使用这个 OpenAPI
我正在使用 openapi-yaml 将 swagger 文件转换为开放的 API v3 文件。使用 Maven 生成器。 我想做的是将新文件直接放入某个目录。 但是会生成一些我不需要的其他文件,例如
我的生成器中有以下标准文件夹结构。我当前正在努力解决的任务是我目前有一个模板化的 _package.json ,我将其写入磁盘以用于主要生成。我想在编写的 package.json 中包含一个变量,它
我是一名优秀的程序员,十分优秀!