Mathematica 生成有锁定位的二进制数

3
我有一个非常具体的Mathematica问题。我试图生成所有在某些“锁定”位周围的二进制数。我使用一组字符串值来表示哪些位是锁定的,例如{"U","U,"L","U"},其中U是“未锁定”的可变位,L是“锁定”的不可变位。我从一个临时列表开始,其中包含已经格式化为上述列表的随机二进制数,例如{0, 1, 1, 0},其中1是锁定位。我需要找到所有其余的二进制数,其中1位是常数。我已经尝试了递归、迭代和两者的组合来解决这个问题,但都没有结果。这是我在大学研究的一部分。
我正在构建二进制数的十进制形式列表。我意识到这段代码完全错误。这只是一次尝试。
    Do[
      If[bits[[pos]] == "U", 
        AppendTo[returnList, myFunction[bits, temp, pos, returnList]]; ],
    {pos, 8, 1}]

    myFunction[bits_, bin_, pos_, rList_] :=
      Module[{binary = bin, current = Length[bin], returnList = rList},
        If[pos == current,
          Return[returnList],
          If[bits[[current]] == "U",
          (*If true*)
            If[! MemberQ[returnList, FromDigits[binary, 2]],
            (*If true*)
              AppendTo[returnList, FromDigits[binary, 2]];
              binary[[current]] = Abs[binary[[current]] - 1],
            (*If false*)
              binary[[current]] = 0;
              current = current - 1]; ,
          (*If false*)
            current = current - 1];
          returnList = myFunction[bits, binary, pos, returnList];  
        Return[returnList]]]

如果你在这里得不到满意的答案,还可以去专门的http://mathematica.stackexchange.com/寻求帮助。 - m69 ''snarky and unwelcoming''
3个回答

2
你可以使用 TuplesFold 生成你感兴趣的位集合。
bits = {"U", "U", "L", "U"};

Fold[
  Function[{running, next}, 
    Insert[running, 1, next]], #, Position[bits, "L"]] & /@ Tuples[{0, 1}, Count["U"]@bits]

(*
{{0, 0, 1, 0}, {0, 0, 1, 1}, {0, 1, 1, 0}, {0, 1, 1, 1}, 
 {1, 0, 1, 0}, {1, 0, 1, 1}, {1, 1, 1, 0}, {1, 1, 1, 1}}
*)

希望这能有所帮助。

不错,但你只需要 Insert[#, 1, Position[bits, "L"]] & /@ Tuples[{0, 1}, Count["U"]@bits],因为 Insert 可以在没有 Fold 的情况下适用于多个位置。 - Chris Degnen
@ChrisDegnen 不行,需要使用 Fold。试一下用你的建议 bits = {"U", "L", "U", "L"}; 会失败,没有使用 Fold 是不行的。 - Edmund
哦,是的,我明白你的意思。 - Chris Degnen

1
myFunction[bits_] := Module[{length, num, range, all, pattern},
  length = Length[bits];
  num = 2^length;
  range = Range[0, num - 1]; 
  all = PadLeft[IntegerDigits[#, 2], length] & /@ range;
  pattern = bits /. {"U" -> _, "L" -> 1};
  Cases[all, pattern]]

bits = {"U", "U", "L", "U"};

myFunction[bits]
{{0, 0, 1, 0}, {0, 0, 1, 1}, {0, 1, 1, 0}, {0, 1, 1, 1},
 {1, 0, 1, 0}, {1, 0, 1, 1}, {1, 1, 1, 0}, {1, 1, 1, 1}}

1
细节问题,但是 IntegerDigits 可以直接使用 len 参数,因此您不需要使用 PadLeft - agentp

1
in = IntegerDigits[Round[ Pi 10^9 ], 2];
mask = RandomSample[ConstantArray["L", 28]~Join~ConstantArray["U", 4],32];

subs[in_, mask_] := Module[ {p = Position[mask, "U"]} ,
       ReplacePart[in, Rule @@@ Transpose[{p, #}]] & /@ 
          Tuples[{0, 1}, Length@p]]
subs[in, mask]

{{1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0}, {1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0}, {1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0}, {1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0}, ...}
 FromDigits[#, 2] & /@ % 

{3108030026, 3108030030, 3108038218, 3108038222, 3108095562, 3108095566, 3108103754, 3108103758, 3141584458, 3141584462, 3141592650, 3141592654, 3141649994, 3141649998, 3141658186, 3141658190}

这正是我所需要的。Degnen先生的答案也是正确的,但我正在使用32位数字。Cases[]适用于较小的数字,但会创建一个关于内存不足的错误消息。然而,这个方法完美地解决了问题。感谢大家的帮助和评论。 - Jordon Huffman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接