public void RemoveRestrictionFromColorTest() { var csp = new CspInstance(); var variable = new Variable(3); var variable2 = new Variable(4); csp.AddVariable(variable); csp.AddVariable(variable2); var color1 = variable.AvalibleColors[0]; var color2 = variable2.AvalibleColors[0]; var color3 = variable2.AvalibleColors[1]; var pair1 = new Pair(variable, color1); var pair2 = new Pair(variable2, color2); var pair3 = new Pair(variable2, color3); csp.AddRestriction(new Restriction(pair1, pair2)); csp.AddRestriction(new Restriction(pair1, pair3)); Assert.Equal(2, color1.Restrictions.Count); csp.RemoveRestriction(new Restriction(pair1, pair2)); Assert.Equal(1, color1.Restrictions.Count); Assert.DoesNotContain(pair2, color1.Restrictions); Assert.DoesNotContain(pair1, color2.Restrictions); Assert.Contains(pair3, color1.Restrictions); csp.RemoveRestriction(new Restriction(pair1, pair3)); Assert.Equal(0, color1.Restrictions.Count); Assert.DoesNotContain(pair3, color1.Restrictions); CheckInstanceCorrectness(csp); }
public static void Lemma3(CspInstance instance, Variable v1, out bool applied) { applied = false; for (int i = 0; i < v1.AvalibleColors.Count; i++) { var c1 = v1.AvalibleColors[i]; var v2 = GetDistinctSingleVariableFromColor(c1); if (v2 != null) { for (int j = 0; j < v2.AvalibleColors.Count; j++) { var c2 = v2.AvalibleColors[j]; var v21 = GetDistinctSingleVariableFromColor(c2); if (v21 != null) { if (!c1.Restrictions.Any(p => p.Color == c2) && !c2.Restrictions.Any(p => p.Color == c1)) { if (v1 == v21) { applied = true; instance.AddToResult(v1, c1); instance.AddToResult(v2, c2); return; } } } } } } }
public static void RemoveVariableWith2Colors(CspInstance instance, Variable v) { #if DEBUG if (v.AvalibleColors.Count > 2) { throw new ArgumentException("Variable doesn't have 2 avalible colors"); } #endif if (v.AvalibleColors.Count == 2) { var c1Neighbors = new List <Pair>(v.AvalibleColors[0].Restrictions); var vc0 = new Pair(v, v.AvalibleColors[0]); var vc1 = new Pair(v, v.AvalibleColors[1]); List <Pair> restrictionClone = new(vc0.Color.Restrictions); instance.ResultRules.Add((2, restrictionClone, vc0, vc1)); foreach (var pair1 in v.AvalibleColors[0].Restrictions) { foreach (var pair2 in v.AvalibleColors[1].Restrictions) { instance.AddRestriction(pair1, pair2); } } instance.RemoveVariable(v); } else if (v.AvalibleColors.Count == 1) { instance.AddToResult(new Pair(v, v.AvalibleColors[0])); } }
private static CspInstance GetRandomInstance(int minColors = 2, int maxColors = 4, int variableCount = 100, int maxRestrictionsCount = 1000) { var instance = new CspInstance(); List <Variable> variables = new(); Random r = new(123); for (int i = 0; i < variableCount; i++) { var v = new Variable(r.Next(minColors, maxColors + 1)); instance.AddVariable(v); variables.Add(v); } for (int i = 0; i < maxRestrictionsCount; i++) { var v1 = variables[r.Next(0, variables.Count)]; var v2 = variables[r.Next(0, variables.Count)]; if (v1.AvalibleColors.Count > 0 && v2.AvalibleColors.Count > 0) { var c1 = v1.AvalibleColors[r.Next(0, v1.AvalibleColors.Count)]; var c2 = v2.AvalibleColors[r.Next(0, v2.AvalibleColors.Count)]; instance.AddRestriction(new Pair(v1, c1), new Pair(v2, c2)); } } return(instance); }
public void AddToResultTest3() { var instance = new CspInstance(); var variable1 = new Variable(2); var variable2 = new Variable(4); var variable3 = new Variable(4); instance.AddVariable(variable1); instance.AddVariable(variable2); instance.AddVariable(variable3); Assert.Equal(3, instance.Variables.Count); var color11 = variable1.AvalibleColors[0]; var color12 = variable1.AvalibleColors[1]; var color21 = variable2.AvalibleColors[0]; var color22 = variable2.AvalibleColors[1]; var color23 = variable2.AvalibleColors[3]; var color31 = variable3.AvalibleColors[0]; var color32 = variable3.AvalibleColors[1]; instance.AddRestriction(new Pair(variable1, color11), new Pair(variable2, color21)); instance.AddRestriction(new Pair(variable1, color11), new Pair(variable2, color22)); instance.AddRestriction(new Pair(variable1, color12), new Pair(variable2, color22)); instance.AddRestriction(new Pair(variable3, color31), new Pair(variable2, color22)); instance.AddRestriction(new Pair(variable3, color32), new Pair(variable2, color22)); instance.AddRestriction(new Pair(variable3, color32), new Pair(variable2, color23)); Assert.Equal(6, instance.Restrictions.Count); instance.AddToResult(new Pair(variable1, color11)); Assert.Equal(2, instance.Variables.Count); Assert.Equal(2, variable2.AvalibleColors.Count); Assert.Equal(1, instance.Restrictions.Count); CheckInstanceCorrectness(instance); }
public void RemoveVariableWith2ColorsTest(CspInstance instance, Variable variable) { int variableCount = instance.Variables.Count; List <Pair> c1Neighbors = new(); c1Neighbors.AddRange(variable.AvalibleColors[0].Restrictions); List <Pair> c2Neighbors = new(); c2Neighbors.AddRange(variable.AvalibleColors[1].Restrictions); CSPLemmas.RemoveVariableWith2Colors(instance, variable); Assert.False(instance.Variables.Contains(variable)); Assert.Equal(variableCount - 1, instance.Variables.Count); foreach (var p1 in c1Neighbors) { foreach (var p2 in c2Neighbors) { if (p1.Variable != p2.Variable) { Assert.Contains(instance.Restrictions, r => r.Contains(p1.Color) && r.Contains(p2.Color)); } } } }
public void CloneWithResultsTest() { var csp = new CspInstance(); var variablesList = new List <Variable>(); int variablesCount = 1000; for (int i = 0; i < variablesCount; i++) { var variable = new Variable(i % 4 + 1); variablesList.Add(variable); csp.AddVariable(variable); } for (int i = 0; i < variablesList.Count; i += 5) { var variable = variablesList[i]; csp.AddToResult(new Pair(variable, variable.AvalibleColors[i % variable.AvalibleColors.Count])); } var cloned = csp.Clone(); Assert.Equal(cloned.Variables.Count, csp.Variables.Count); Assert.Equal(cloned.Restrictions.Count, csp.Restrictions.Count); Assert.Equal(cloned.Result.Count, csp.Result.Count); foreach (var res in csp.Result) { Assert.Single(cloned.Result, p => { return(p.Variable.Id == res.Variable.Id && p.Color.Value == res.Color.Value); }); } CheckInstanceCorrectness(cloned); }
private static void NoVariableWith2Colors(CspInstance instance) { foreach (var variable in instance.Variables) { Assert.True(variable.AvalibleColors.Count > 2 || variable.AvalibleColors.Count == 2); } }
public static void Lemma4(CspInstance instance, Variable v, out bool applied) { applied = false; for (int i = 0; i < v.AvalibleColors.Count; i++) { var c1 = v.AvalibleColors[i]; for (int j = 0; j < v.AvalibleColors.Count; j++) { var c2 = v.AvalibleColors[j]; if (c1 != c2) { if (c1.Restrictions.IsSubsetOf(c2.Restrictions)) { applied = true; instance.RemoveColor(v, c2); if (v.AvalibleColors.Count <= 2) { RemoveVariableWith2Colors(instance, v); } i = v.AvalibleColors.Count; // to break 2 loops at once break; } } } } }
public void Lemma11Test(CspInstance instance) { foreach (var v in instance.Variables) { foreach (var c in v.AvalibleColors) { if ((c.Restrictions.Count >= 3 && v.AvalibleColors.Count == 4) || (c.Restrictions.Count >= 4 && v.AvalibleColors.Count == 3)) // Lemma11 applies { #if DEBUG if (c.Restrictions.Select(r => r.Variable).Distinct().Count() != c.Restrictions.Select(r => r.Variable).Count()) { Assert.Throws <ArgumentException>(() => CSPLemmas.Lemma11(instance, v, c)); } else { var res = CSPLemmas.Lemma11(instance, v, c); Assert.Equal(2, res.Count); Assert.Contains(res, inst => inst.Result.Any(p => p.Variable == v && p.Color == c)); } #endif } else { var res = CSPLemmas.Lemma11(instance, v, c); Assert.Single(res); } } } }
public void Lemma13Test(CspInstance instance) { foreach (var v in instance.Variables) { foreach (var c in v.AvalibleColors) { if (c.Restrictions.Count == 3) { foreach (var restrictionPair in c.Restrictions) { (var v2, var c2) = restrictionPair; if (c2.Restrictions.Count == 2) // Lemma13 applies { if (c.Restrictions.Any(r => r.Variable.AvalibleColors.Count != 3)) { Assert.Throws <ArgumentException>(() => CSPLemmas.Lemma13(instance, v, c)); } var res = CSPLemmas.Lemma13(instance, v, c); Assert.Equal(3, res.Count); Assert.Contains(res, inst => inst.Result.Any(p => p.Variable == v && p.Color == c)); } else { var res = CSPLemmas.Lemma13(instance, v, c); Assert.Single(res); } } } } } }
public void Lemma3Test(CspInstance instance, Pair pair1, Pair pair2) { UseLemma2to6(instance, CSPLemmas.Lemma3); Assert.Contains(pair1, instance.Result); Assert.Contains(pair2, instance.Result); Assert.DoesNotContain(pair1.Variable, instance.Variables); Assert.DoesNotContain(pair2.Variable, instance.Variables); }
// in the main alog: // for each (v, c) in instance: // res = Lemma12(instance, v, c) // if res.Count > 1: // for each inst in res: // recurrsion for inst public static List <CspInstance> Lemma12(CspInstance instance, Variable v, Color c) { if (c.Restrictions.Count == 3) { foreach (var restrictionPair in c.Restrictions) { (var v2, var c2) = restrictionPair; if (v2.AvalibleColors.Count == 4) // Lemma12 applies { #if DEBUG if (c2.Restrictions.Count != 2) { throw new ArgumentException("We can assume (v2, c2) has only two constraints, else it would be covered by the previous lemma."); } #endif // second neighbor of v2 (var v3, var c3) = c2.Restrictions.Where(r => r.Variable != v).First(); if (!Do_v1c1v2c2v3c3_FormTraingle(v, c, c3)) { (var instance2, var i2vArr, var i2cArr) = instance.CloneAndReturnCorresponding(new Variable[] { v, v2 }, new Color[] { c, c2 }); var i2v = i2vArr[0]; var i2v2 = i2vArr[1]; var i2c = i2cArr[0]; var i2c2 = i2cArr[1]; instance.AddToResult(v, c); instance2.RemoveColor(i2v, i2c); // creating a dangling constraint at (v2, c2) var res = new List <CspInstance>() { instance }; res.AddRange(Lemma9(instance2, i2v2, i2c2, out _)); return(res); } else { (var instance2, var i2v2, var i2c2) = instance.CloneAndReturnCorresponding(v2, c2); (var instance3, var i2v3, var i2c3) = instance.CloneAndReturnCorresponding(v3, c3); instance.AddToResult(v, c); instance2.AddToResult(i2v2, i2c2); instance3.AddToResult(i2v3, i2c3); return(new() { instance, instance2, instance3 }); } } } } return(new() { instance }); bool Do_v1c1v2c2v3c3_FormTraingle(Variable v, Color c, Color c3) { // we know that (v, c)-----(v2, c2) and (v2, c2)-----(v3, c3). // let's check whether (v3, c3)-----(v, c): return(c3.Restrictions.Any(r => r.Variable == v && r.Color == c)); } }
public void Lemma9Test(CspInstance instance, Variable v, Color c, Variable v2, Color c2) { var res = CSPLemmas.Lemma9(instance, v, c, out _); Assert.Equal(2, res.Count); Assert.True( res.Any(inst => inst.Result.Any(p => p.Variable == v && p.Color == c)) || res.Any(inst => inst.Result.Any(p => p.Variable == v2 && p.Color == c2))); }
public void CloneCheckInvariabilityTest() { var csp = new CspInstance(); var variablesList = new List <Variable>(); int variablesCount = 1000; for (int i = 0; i < variablesCount; i++) { var variable = new Variable(i % 4 + 1); variablesList.Add(variable); csp.AddVariable(variable); } for (int i = 0; i < variablesCount * 10; i++) { var variable1 = variablesList[(i * 21 + 5) % variablesCount]; var variable2 = variablesList[(i * 12 + 11) % variablesCount]; if (variable1.AvalibleColors.Count > 0 && variable2.AvalibleColors.Count > 0) { var color1 = variable1.AvalibleColors[i % variable1.AvalibleColors.Count]; var color2 = variable2.AvalibleColors[i % variable2.AvalibleColors.Count]; csp.AddRestriction(new Pair(variable1, color1), new Pair(variable2, color2)); } } for (int i = 0; i < variablesList.Count; i += 5) { var variable = variablesList[i]; csp.AddToResult(new Pair(variable, variable.AvalibleColors[i % variable.AvalibleColors.Count])); } var variableMem = new List <Variable>(csp.Variables); var resultMem = new List <Pair>(csp.Result); var restrictionsMem = new List <Restriction>(csp.Restrictions); _ = csp.Clone(); Assert.Equal(variableMem.Count, csp.Variables.Count); Assert.Equal(resultMem.Count, csp.Result.Count); Assert.Equal(restrictionsMem.Count, csp.Restrictions.Count); foreach (var variable in variableMem) { Assert.Contains(variable, csp.Variables); } foreach (var result in resultMem) { Assert.Contains(result, csp.Result); } foreach (var restriction in restrictionsMem) { Assert.Contains(restriction, csp.Restrictions); } CheckInstanceCorrectness(csp); }
public static void Lemma2(CspInstance instance, Variable variable, out bool applied) { applied = false; if (variable.AvalibleColors.Count <= 2) { applied = true; RemoveVariableWith2Colors(instance, variable); return; } }
public void SimpleCloneTest() { var csp = new CspInstance(); var cloned = csp.Clone(); Assert.Equal(cloned.Variables.Count, csp.Variables.Count); Assert.Equal(cloned.Restrictions.Count, csp.Restrictions.Count); Assert.Equal(cloned.Result.Count, csp.Result.Count); CheckInstanceCorrectness(cloned); }
public void Lemma19Test(CspInstance instance) { foreach (var R1 in instance.Result) { foreach (var R2 in instance.Result) { bool test = instance.Restrictions.Contains(new Restriction(R1, R2)); Assert.False(test); } } }
public static HashSet <Pair> FindBadThreeComponent(CspInstance instance, bool small = true) { HashSet <Pair> NotVisited = new(); foreach (var variable in instance.Variables) { foreach (var color in variable.AvalibleColors) { if (color.Restrictions.Count == 3) { NotVisited.Add(new Pair(variable, color)); } } } HashSet <Pair> CurrentThreeCompnent = new(); while (NotVisited.Count > 0) { void Rec(Pair pair) { NotVisited.Remove(pair); CurrentThreeCompnent.Add(pair); foreach (var p2 in pair.Color.Restrictions) { if (NotVisited.Contains(p2)) { Rec(p2); } } } var pair = NotVisited.First(); Rec(pair); if (CurrentThreeCompnent.Count > 4) // it's bad { if (small) { if (CurrentThreeCompnent.Select(p => p.Variable).Distinct().Count() == 4) // it's small { return(CurrentThreeCompnent); } } else { if (CurrentThreeCompnent.Select(p => p.Variable).Distinct().Count() > 4) // it's big { return(CurrentThreeCompnent); } } } } return(null); }
public void AddToResultTest2() { var instance = new CspInstance(); var variable = new Variable(2); instance.AddVariable(variable); Assert.Equal(1, instance.Variables.Count); instance.AddToResult(variable, variable.AvalibleColors[0]); Assert.Equal(0, instance.Variables.Count); CheckInstanceCorrectness(instance); }
private void UseLemma2to6(CspInstance instance, Lemma lemma) { foreach (var v in instance.Variables) { lemma(instance, v, out bool applied); if (applied) { UseLemma2to6(instance, lemma); return; } } }
public void RemoveVariableTest() { var csp = new CspInstance(); var variable = new Variable(3); var variable2 = new Variable(4); csp.AddVariable(variable); Assert.Equal(1, csp.Variables.Count); csp.RemoveVariable(variable2); Assert.Equal(1, csp.Variables.Count); csp.RemoveVariable(variable); Assert.Equal(0, csp.Variables.Count); CheckInstanceCorrectness(csp); }
public void Lemma17Test(CspInstance instance) { var res = CSPLemmas.Lemma17(instance, out bool applied); if (applied == false) { Assert.Null(CSPLemmas.FindBadThreeComponent(instance, false)); } else { foreach (var inst in res) { Lemma17Test(inst); } } }
// in main alg: // for every (v, c) in instance: // resInstances = Lemma9(instance, v, c) // if resInstaces.Count > 0: // recursion for every resnstaces[i] public static List <CspInstance> Lemma9(CspInstance instance, Variable v, Color c, out bool applied) { if (c.Restrictions.Count == 1) // (v,c) has one constraint => dangling constraint with (v2, c2) { applied = true; (var v2, var c2) = c.Restrictions.First(); (var instance2, var i2v2, var i2c2) = instance.CloneAndReturnCorresponding(v2, c2); instance.RemoveColor(v2, c2); instance.AddToResult(v, c); instance2.AddToResult(i2v2, i2c2); return(new() { instance, instance2 }); } applied = false; return(new() { instance }); }
public void CloneWithVariablesTest() { var csp = new CspInstance(); int variablesCount = 1000; for (int i = 0; i < variablesCount; i++) { var variable = new Variable(i % 4 + 1); csp.AddVariable(variable); } var cloned = csp.Clone(); Assert.Equal(cloned.Variables.Count, csp.Variables.Count); Assert.Equal(cloned.Restrictions.Count, csp.Restrictions.Count); Assert.Equal(cloned.Result.Count, csp.Result.Count); CheckInstanceCorrectness(cloned); }
public void AddRestrictionTest4() { var csp = new CspInstance(); var variable1 = new Variable(2); var variable2 = new Variable(2); csp.AddVariable(variable1); csp.AddVariable(variable2); var color1 = variable1.AvalibleColors[0]; var color2 = variable2.AvalibleColors[0]; csp.AddRestriction(new Pair(variable1, color1), new Pair(variable2, color2)); Assert.Equal(1, csp.Restrictions.Count); csp.AddRestriction(new Pair(variable1, color1), new Pair(variable2, color2)); Assert.Equal(1, csp.Restrictions.Count); CheckInstanceCorrectness(csp); }
public static void Lemma6(CspInstance instance, Variable v, out bool applied) { applied = false; for (int i = 0; i < v.AvalibleColors.Count; i++) { var c = v.AvalibleColors[i]; var neighbors = c.Restrictions.Select(r => r.Variable).Distinct(); foreach (var v2 in neighbors) { if (c.Restrictions.Where(r => r.Variable == v2).Count() == v2.AvalibleColors.Count) { applied = true; instance.RemoveColor(v, c); RemoveVariableWith2Colors(instance, v); } } } }
public void Lemma15Test(CspInstance instance) { var res = CSPLemmas.Lemma15(instance, out bool b); if (b == true) { foreach (var inst in res) { if (inst != null) { Lemma15Test(inst); } } } else { Assert.Null(CSPLemmas.FindBadThreeComponent(instance, true)); } }
public void RemoveRestrictionsTest() { var csp = new CspInstance(); var variable1 = new Variable(1); var variable2 = new Variable(2); csp.AddVariable(variable1); csp.AddVariable(variable2); var color1 = variable1.AvalibleColors[0]; var color2 = variable2.AvalibleColors[0]; var restriction = new Restriction(variable1, color1, variable2, color2); csp.AddRestriction(restriction); Assert.Equal(1, csp.Restrictions.Count); csp.RemoveRestriction(restriction); Assert.Equal(0, csp.Restrictions.Count); CheckInstanceCorrectness(csp); }
// in the main alog: // for each (v, c) in instance: // res = Lemma11(instance, v, c) // if res.Count > 1: // for each inst in res: // recurrsion for inst public static List<CspInstance> Lemma11(CspInstance instance, Variable v, Color c) { if ((c.Restrictions.Count >= 3 && v.AvalibleColors.Count == 4) || (c.Restrictions.Count >= 4 && v.AvalibleColors.Count == 3)) // Lemma11 applies { #if DEBUG if (c.Restrictions.Select(r =>r.Variable).Distinct().Count() != c.Restrictions.Select(r => r.Variable).Count()) { throw new ArgumentException("We can assume form Lemma 10 that each constraint connects (v, R) to a different varaible."); } #endif (var instance2, var i2v, var i2c) = instance.CloneAndReturnCorresponding(v, c); instance.AddToResult(v, c); instance2.RemoveColor(i2v, i2c); return new() { instance, instance2 }; } return new() { instance }; }