【问题标题】:Mathematica Generate Binary Numbers with Locked BitsMathematica 生成带有锁定位的二进制数
【发布时间】:2015-12-28 22:48:26
【问题描述】:

我有一个非常具体的 Mathematica 问题。我正在尝试围绕某些“锁定”位生成所有二进制数。我正在使用字符串值列表来表示哪些位被锁定,例如{"U","U,"L","U"},其中 U 是“未锁定”的可变位,L 是“锁定”的不可变位。我从已格式化的随机二进制数的临时列表开始到上一个列表,例如 {0, 1, 1, 0},其中 1 是锁定位. 我需要找到 1 位为常数的所有剩余二进制数。我已经递归、迭代地处理了这个问题,并且将两者结合起来没有结果. 这是我在大学里做的研究。

我正在构建一个以 10 为基数的二进制数列表。我意识到这段代码是完全错误的。这只是一种尝试。

    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]]]

【问题讨论】:

标签: algorithm binary wolfram-mathematica


【解决方案1】:

您可以使用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}}
*)

希望这会有所帮助。

【讨论】:

  • +1 不错,但您只需要Insert[#, 1, Position[bits, "L"]] & /@ Tuples[{0, 1}, Count["U"]@bits],因为无需折叠即可插入多个位置。
  • @ChrisDegnen 不。你需要Fold。根据您的建议尝试bits = {"U", "L", "U", "L"};。如果没有Fold,它将无法工作。
  • 哦,是的,我明白你的意思了。
【解决方案2】:
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[] 适用于较小的数字,但会创建有关内存不足的错误消息。但是,这非常有效。谢谢大家的帮助和cmets。
【解决方案3】:
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}}

【讨论】:

  • 很好,但是IntegerDigits 可以直接使用 len 参数,所以你不需要PadLeft
猜你喜欢
  • 2013-01-13
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 2018-04-25
相关资源
最近更新 更多