我试图解决我遇到问题的部分问题,这是我正在做的更大项目(不是家庭作业)的一部分。我认为将它描述为游戏是最容易的(因为我需要它来完成我正在努力的游戏)。这是一个单人游戏,就像我描述它一样。
START 您从以下两个职位之一开始:
(2,0,-1)
和一个red
玩(3,1,-1)
和两个red
次 结束当您没有更多游戏时,游戏结束。目标是以权重(0,0,0)
结束游戏。
有两种类型的游戏red
和blue
。给定一个游戏,你可以选择以下四个部分中的一个:A,B,C,D
,它可以为你提供额外的重量,也可能是额外的游戏。以下是规则:
在red
游戏:
(0,-2,-1)
(1,-1,-1)
并添加一个red
游戏(2,0,-1)
和两个red
次(0,2,1)
和两个blue
次 blue
次播放的规则类似,但重量的前两列是交换的,最后一列是反向的,播放的类型是相反的,所以你得到了这个:
在blue
游戏:
(-2,0,1)
(-1,1,1)
并添加一个blue
游戏(0,2,1)
和两个blue
次(2,0,-1)
和两个red
次问题可以赢得这场比赛吗?
我尝试编写一个通过选择游戏来赢得游戏的程序,以便在没有更多游戏时最终余额为(0,0,0)
。只有我似乎无法做到这一点。所以现在我认为也许没有算法来赢得比赛。我真的很想知道为什么会这样。如果有人有任何想法我可以证明这一点,那么请让我知道!或者,如果你尝试并找到获胜的方法,那么请告诉我。谢谢!
答案 0 :(得分:11)
可能我错过了一些东西,但只是通过检查,看起来这一系列步骤应该有效吗? :
(2,0,-1)
和一个red
玩”red
游戏,C
,“增加重量(2,0,-1)
和两个red
游戏”,为您留下重量(4,0,-2)
和两个{ {1}}播放。red
游戏,red
,“增加重量A
”,让您体重(0,-2,-1)
和(4,-2,-3)
游戏。red
游戏,red
,“增加重量D
和两个(0,2,1)
游戏”,为您留下重量blue
和两个{ {1}}播放。(4,0,-2)
游戏,blue
,“增加重量blue
”,让您体重A
和(-2,0,1)
游戏。(2,0,-1)
游戏,blue
,“增加重量blue
”,为您留下重量A
而不进行游戏。更具示意性:
(-2,0,1)
。 。 。没有?
已编辑添加:
我是如何找到这个:
由于这个问题引起了很多人的兴趣,也许我应该解释一下我是如何找到上述解决方案的。这基本上是运气;我碰巧发现了两个关键的观察结果:
(0,0,0)
和move weight plays
------ --------- -------
(2,0,-1) red
red C (4,0,-2) red x2
red A (4,-2,-3) red
red D (4,0,-2) blue x2
blue A (2,0,-1) blue
blue A (0,0,0) -
在重量方面相互抵消(前者添加red A
,后者添加red D
),并添加总共两个{{1}播放(来自(0,-2,-1)
)和没有(0,2,1)
播放;因此,如果你一个接一个地播放,你可以将两个blue
个剧本“转换”为两个red D
个剧本。red
取消了初始权重(它添加red
)并且不添加任何播放,因此可以通过将一个blue
播放“转换为”{{1}来解决整个问题播放。这给了我一个良好的开端。我从blue A
开始,以便获得我可以“转换”为两个(2,0,-1)
次播放的两个red
次播放,我立即看到blue
也是“对面“red C
权重,因此也可以red
取消。在我的脑海中,这一切似乎完全抵消了;然后我把它写下来以确保。
证明它是最小的:
此外,虽然我当时没有理由通过它,但我也可以证明这是一个“最小”的起始位置的获胜序列 - 我的意思是,如果一个序列以“重量”开头blue
和red C
播放“并以重量blue A
结尾且没有播放,则序列必须包含至少五个移动。为此,假设我们有一个满足此条件的序列,并且少于而不是五个移动。然后:
blue A
比赛减少它,序列将需要至少一个(2,0,-1)
比赛,这意味着它必然包括{{1}至少一次(因为这是获得red
游戏的唯一途径,如果你不开始一个)。(0,0,0)
一次,而red
为我们提供了两次blue
次播放,因此序列必须包含red D
至少两次(因为游戏不会结束直到没有戏剧为止。blue
一次,而red D
为权重的第二个分量添加2,因此它必须至少包含red D
一次,否则包含{ {1}}至少两次(因为没有其他方法可以将重量的第二个分量减少至少2)。但显然,如果它至少包含blue
一次,blue
至少两次,red D
至少两次,那么它将包含至少五次移动,这是假设禁止的;所以它必须使用red D
方法。red A
一次,red B
至少两次,red D
至少一次。并且通过假设,它包含少于五个移动。因此,它必须包含完全一个blue
,两个red B
,一个red A
和其他零个动作。red D
个游戏,序列中恰好包含两个blue
个游戏。因此,序列必须包含一个只能产生red A
个游戏的移动。但唯一可能的做法是red D
,序列不包含。因此,没有这样的序列是可能的。
其他起始位置:
我还可以使用类似的参数证明任何以“weight blue
和两个red A
播放”选项开头的解决方案也必须包含至少五个动作。一个这样的五步解决方案是:
red
答案 1 :(得分:6)
以下是每个起始位置的解决方案:
Start 1: (2, 0, -1) Reds=1 Blues=0
Red B ==> (3, -1, -2) Reds=1 Blues=0
Red B ==> (4, -2, -3) Reds=1 Blues=0
Red D ==> (4, 0, -2) Reds=0 Blues=2
Blue A ==> (2, 0, -1) Reds=0 Blues=1
Blue A ==> (0, 0, 0) Reds=0 Blues=0
Start 2: (3, 1, -1) Reds=2 Blues=0
Red A ==> (3, -1, -2) Reds=1 Blues=0
Red B ==> (4, -2, -3) Reds=1 Blues=0
Red D ==> (4, 0, -2) Reds=0 Blues=2
Blue A ==> (2, 0, -1) Reds=0 Blues=1
Blue A ==> (0, 0, 0) Reds=0 Blues=0
通过以下随机游走的C#程序立即找到,并在少量移动后放弃。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SO8683939
{
struct State
{
public int V1;
public int V2;
public int V3;
public int Reds;
public int Blues;
public int Tokens { get { return Reds + Blues; } }
public string Description;
public State(int v1, int v2, int v3, int reds, int blues)
{
V1 = v1;
V2 = v2;
V3 = v3;
Reds = reds;
Blues = blues;
Description = null;
}
public State Add(State other)
{
State sum;
sum.V1 = V1 + other.V1;
sum.V2 = V2 + other.V2;
sum.V3 = V3 + other.V3;
sum.Reds = Reds + other.Reds;
sum.Blues = Blues + other.Blues;
sum.Description = null;
return sum;
}
public override string ToString()
{
var detail = string.Format("({0}, {1}, {2}) Reds={3} Blues={4}", V1, V2, V3, Reds, Blues);
if (Description != null)
{
return Description + ": " + detail;
}
return detail;
}
}
class Program
{
static void Main(string[] args)
{
var start1 = new State(2, 0, -1, 1, 0) { Description = "Start 1" };
var start2 = new State(3, 1, -1, 2, 0) { Description = "Start 2" };
var end = new State(0, 0, 0, 0, 0);
var redA = new State(0, -2, -1, -1, 0) { Description = "Red A" };
var redB = new State(1, -1, -1, 0, 0) { Description = "Red B" }; ;
var redC = new State(2, 0, -1, 1, 0) { Description = "Red C" }; ;
var redD = new State(0, 2, 1, -1, 2) { Description = "Red D" }; ;
var redOptions = new[] { redA, redB, redC, redD };
var blueA = new State(-2, 0, 1, 0, -1) { Description = "Blue A" };
var blueB = new State(-1, 1, 1, 0, 0) { Description = "Blue B" };
var blueC = new State(0, 2, 1, 0, 1) { Description = "Blue C" };
var blueD = new State(2, 0, -1, 2, -1) { Description = "Blue D" };
var blueOptions = new[] { blueA, blueB, blueC, blueD };
var startingPosition = start1;
var maxSolutionLength = 5;
var rand = new Random();
var path = new List<State>();
while (true)
{
var current = startingPosition;
path.Clear();
//Console.WriteLine("Starting");
//Console.WriteLine(current);
while (true)
{
State selected;
if (current.Reds == 0)
{
selected = blueOptions[rand.Next(4)];
}
else if (current.Blues == 0)
{
selected = redOptions[rand.Next(4)];
}
else
{
if (rand.NextDouble() < 0.5)
{
selected = blueOptions[rand.Next(4)];
}
else
{
selected = redOptions[rand.Next(4)];
}
}
//Console.WriteLine(selected);
path.Add(selected);
current = current.Add(selected);
//Console.WriteLine(current);
if (current.Equals(end))
{
Console.WriteLine("Success!");
var retrace = startingPosition;
Console.WriteLine(retrace);
foreach (var selection in path)
{
retrace = retrace.Add(selection);
Console.WriteLine("{0} ==> {1}", selection.Description, retrace);
}
Console.ReadLine();
break;
}
else if (current.Tokens == 0)
{
// fail
//Console.WriteLine("Fail");
break;
}
else if (path.Count >= maxSolutionLength)
{
// fail
//Console.WriteLine("Fail");
break;
}
}
}
}
}
}
答案 2 :(得分:2)
将红色和蓝色游戏的数量视为您位置的两个额外维度。这大大降低了问题的复杂性。
下面,问题以最后两个维度重新表示,表示剩余的红色和蓝色游戏。
START 您从以下两个职位之一开始:
(2, 0,-1, 1, 0)
(3,-1,-1, 2, 0)
结束当你有体重(0, 0, 0, 0, 0)
时游戏结束。
考虑到一个游戏,你可以从八个部分中选择一个:Ar,Br,Cr,Dr,Ab,Bb,Cb,Db
来增加你的体重。以下是规则:
(0,-2,-1,-1, 0)
(1,-1,-1, 0, 0)
(2, 0,-1, 1, 0)
(0, 2, 1,-1, 2)
(-2,0, 1, 0,-1)
(-1,1, 1, 0, 0)
(0, 2, 1, 0, 1)
(2, 0,-1, 2,-1)
此外,最后两个维度可能永远不会是负面的。
现在,它可以作为一个8变量方程来解决。