Can someone give me a code sample of 2-opt algorithm for traveling salesman problem. For now im using nearest neighbour to find the path but this method is far from perfect, and after some research i found 2-opt algorithm that would correct that path to the acceptable level. I found some sample apps but without source code.
So I got bored and wrote it. It looks like it works, but I haven't tested it very thoroughly. It assumes triangle inequality, all edges exist, that sort of thing. It works largely like the answer I outlined. It prints each iteration; the last one is the 2-optimized one.
I'm sure it can be improved in a zillion ways.
using System;
using System.Collections.Generic;
using System.Linq;
namespace TSP
{
internal static class Program
{
private static void Main(string[] args)
{
//create an initial tour out of nearest neighbors
var stops = Enumerable.Range(1, 10)
.Select(i => new Stop(new City(i)))
.NearestNeighbors()
.ToList();
//create next pointers between them
stops.Connect(true);
//wrap in a tour object
Tour startingTour = new Tour(stops);
//the actual algorithm
while (true)
{
Console.WriteLine(startingTour);
var newTour = startingTour.GenerateMutations()
.MinBy(tour => tour.Cost());
if (newTour.Cost() < startingTour.Cost()) startingTour = newTour;
else break;
}
Console.ReadLine();
}
private class City
{
private static Random rand = new Random();
public City(int cityName)
{
X = rand.NextDouble() * 100;
Y = rand.NextDouble() * 100;
CityName = cityName;
}
public double X { get; private set; }
public double Y { get; private set; }
public int CityName { get; private set; }
}
private class Stop
{
public Stop(City city)
{
City = city;
}
public Stop Next { get; set; }
public City City { get; set; }
public Stop Clone()
{
return new Stop(City);
}
public static double Distance(Stop first, Stop other)
{
return Math.Sqrt(
Math.Pow(first.City.X - other.City.X, 2) +
Math.Pow(first.City.Y - other.City.Y, 2));
}
//list of nodes, including this one, that we can get to
public IEnumerable<Stop> CanGetTo()
{
var current = this;
while (true)
{
yield return current;
current = current.Next;
if (current == this) break;
}
}
public override bool Equals(object obj)
{
return City == ((Stop)obj).City;
}
public override int GetHashCode()
{
return City.GetHashCode();
}
public override string ToString()
{
return City.CityName.ToString();
}
}
private class Tour
{
public Tour(IEnumerable<Stop> stops)
{
Anchor = stops.First();
}
//the set of tours we can make with 2-opt out of this one
public IEnumerable<Tour> GenerateMutations()
{
for (Stop stop = Anchor; stop.Next != Anchor; stop = stop.Next)
{
//skip the next one, since you can't swap with that
Stop current = stop.Next.Next;
while (current != Anchor)
{
yield return CloneWithSwap(stop.City, current.City);
current = current.Next;
}
}
}
public Stop Anchor { get; set; }
public Tour CloneWithSwap(City firstCity, City secondCity)
{
Stop firstFrom = null, secondFrom = null;
var stops = UnconnectedClones();
stops.Connect(true);
foreach (Stop stop in stops)
{
if (stop.City == firstCity) firstFrom = stop;
if (stop.City == secondCity) secondFrom = stop;
}
//the swap part
var firstTo = firstFrom.Next;
var secondTo = secondFrom.Next;
//reverse all of the links between the swaps
firstTo.CanGetTo()
.TakeWhile(stop => stop != secondTo)
.Reverse()
.Connect(false);
firstTo.Next = secondTo;
firstFrom.Next = secondFrom;
var tour = new Tour(stops);
return tour;
}
public IList<Stop> UnconnectedClones()
{
return Cycle().Select(stop => stop.Clone()).ToList();
}
public double Cost()
{
return Cycle().Aggregate(
0.0,
(sum, stop) =>
sum + Stop.Distance(stop, stop.Next));
}
private IEnumerable<Stop> Cycle()
{
return Anchor.CanGetTo();
}
public override string ToString()
{
string path = String.Join(
"->",
Cycle().Select(stop => stop.ToString()).ToArray());
return String.Format("Cost: {0}, Path:{1}", Cost(), path);
}
}
//take an ordered list of nodes and set their next properties
private static void Connect(this IEnumerable<Stop> stops, bool loop)
{
Stop prev = null, first = null;
foreach (var stop in stops)
{
if (first == null) first = stop;
if (prev != null) prev.Next = stop;
prev = stop;
}
if (loop)
{
prev.Next = first;
}
}
//T with the smallest func(T)
private static T MinBy<T, TComparable>(
this IEnumerable<T> xs,
Func<T, TComparable> func)
where TComparable : IComparable<TComparable>
{
return xs.DefaultIfEmpty().Aggregate(
(maxSoFar, elem) =>
func(elem).CompareTo(func(maxSoFar)) > 0 ? maxSoFar : elem);
}
//return an ordered nearest neighbor set
private static IEnumerable<Stop> NearestNeighbors(this IEnumerable<Stop> stops)
{
var stopsLeft = stops.ToList();
for (var stop = stopsLeft.First();
stop != null;
stop = stopsLeft.MinBy(s => Stop.Distance(stop, s)))
{
stopsLeft.Remove(stop);
yield return stop;
}
}
}
}
Well, your solution to TSP is always going to be far from perfect. No code, but here's how to go about 2-Opt. It's not too bad:
You need a class called Stop that has a Next, Prev, and City property, and probably a Stops property that just returns the array containing Next and Prev.
When you link them together, we'll call that a Tour. Tour has a Stop property (any of the stops will do), and an AllStops property, whose getter just walks the stops and returns them
You need a method that takes a tour and returns its cost. Let's call that Tour.Cost().
You need Tour.Clone(), which just walks the stops and clones them individually
You need a method that generates the set of tours with two edges switched. Call this Tour.PossibleMutations()
Start with your NN solution
Call PossibleMutations() on it
Call Cost() on all of them and take the one with the lowest result
Repeat until the cost doesn't go down
If the problem is euclidian distance and you want the cost of the solution produced by the algorithm is within 3/2 of the optimum then you want the Christofides algorithm. ACO and GA don't have a guaranteed cost.
Related
This is my object
public class Totals {
public int Total1 { get; set; }
public int Total2 { get; set; }
public int Total3 { get; set; }
public int Total4 { get; set; }
}
Incrementing the values of Total1 and Total2 using calculateTotals method
private Totals calculateTotals(Totals t) {
if (//condition) {
t.Total1 += 1;
} else {
t.Total2 += 1;
}
return t;
}
**Incrementing value of Total3 and Total4 of the same object with same conditions at a different location using different method calculateOtherTotals, at this point I only need to update Total3 and Total4 **
private Totals calculateOtherTotals(Totals t) {
if (//condition) {
t.Total3 += 1;
} else {
t.Total4 += 1;
}
return t;
}
I am new to c# , I need to increment the values Total1,Total2 and Total3,Total4 separately and the code which I have is working fine
Is there a way to improve my code?, how can I avoid creating two different methods which pretty much does the same logic on different properties? is there a way to create only 1 method to achieve my functionality?
You could do it this way, but essentially the amount of code doesn't change.
This adds a judgment:
Totals calculateTotals(Totals t, bool Flag)
{
//function1:
if (Flag)
{
if (true)
{ //(condition) {
t.Total1++;
}
else
{
t.Total2++;
}
}
//function2:
else
{
if (true)
{ //(condition) {
t.Total3++;
}
else
{
t.Total4++;
}
}
return t;
}
Call it like this:
Totals totals = new Totals();
totals.Total1=0;
totals.Total2=0;
totals.Total3=0;
totals.Total4=0;
calculateTotals(totals,true);//function1:
calculateTotals(totals,false);//function2:
Reflection is one way, though its slow and not a Domain Specific Language:
Type totalsType = typeof(Totals);
var totalToIncrement = condition;
PropertyInfo prop = totalsType.GetProperty("Total" + totalToIncrement);
prop.SetValue(null, 76);
Or perhaps you want to abstract the properties you're incrementing:
private Totals calculateTotals(Totals t)
{
bool condition = true;
AbstractAdds(ref t.Total1, ref t.Total2, condition);
return t;
}
private void AbstractAdds(ref int a, ref int b, bool condition = false)
{
if (condition)
{
a++;
}
else
{
b++;
}
}
}
public class Totals
{
public int Total1;//{ get; set; }
public int Total2;//{ get; set; }
public int Total3;//{ get; set; }
public int Total4;//{ get; set; }
}
I'd personally have a List<int> or int[3] and make the condition calculate the index 0-3:
var index = calcCondition;
Totals[index]++;
This way its extensible for more totals and you get inbuilt functions like LINQ, eg Totals.Sum().
Is there a way to improve my code?, how can I avoid creating two different methods which pretty much does the same logic on different properties? is there a way to create only 1 method to achieve my functionality?
Then it depends on how you want your method (function) to be. (E.g., how you define what your function will do and how your class and properties are characteristic—which, currently, many who want to help you still wonder about.)
Let me give another clear example.
Assume that you answer your additional requirement are:
My object has only 4 properties of "Total"
I want these new function to increment value only 1 when call, no need to add more than 1
This function is called from another class to modify my object value
I want my cool function name calculateOtherTotals being private, because of some unexplained reason such as “I don't like others knowing it exists”.
Then
public OtherClass{
Public Totals ExposeThePrivateCalculateOtherTotals(Totals t, bool IncrementT1 , bool IncrementT2 , bool IncrementT3, bool IncrementT4)
{
calculateOtherTotals(t, IncrementT1 , IncrementT2 , IncrementT3, IncrementT4);
}
Private Totals calculateOtherTotals(Totals t, bool IncrementT1 , bool IncrementT2 , bool IncrementT3, bool IncrementT4) {
if( IncrementT1 ) t.Total1 += 1; //choose your style
if( IncrementT2==true ) ++t.Total2;//choose your style
if( IncrementT3!=false ) t.Total3++; //choose your style
t.Total4 += IncrementT4==true?1:0;//choose your style
return t;
}
}
//In main (how to use)
Totals t= new Totals();
OtherClass doMyFunc = new OtherClass();
t = doMyFunc.ExposeThePrivateCalculateOtherTotals(t, true, false,false,false); // result of operation => t.total1 += 1;
t = doMyFunc.ExposeThePrivateCalculateOtherTotals(t, false, true,false,false); // result of operation => t.total2 += 1;
Well, I would like to do my own benchmarking system like spark in Minecraft (https://github.com/lucko/spark):
I'm using Harmony lib (https://github.com/pardeike/Harmony) which allows me to interact/modify methods and allows me to add a Prefix/Postfix on each call that will help me out with this stack.
The basic structure has something similar to (https://github.com/pardeike/Harmony/issues/355):
[HarmonyPatch]
class MyPatches
{
static IEnumerable<MethodBase> TargetMethods()
{
return AccessTools.GetTypesFromAssembly(Assembly.GetExecutingAssembly())
.SelectMany(type => type.GetMethods())
.Where(method => method.ReturnType != typeof(void) && method.Name.StartsWith("Do"));
}
static void Prefix(out Stopwatch __state, MethodBase __originalMethod)
{
__state = Stopwatch.StartNew();
// ...
}
static void Postfix(Stopwatch __state, MethodBase __originalMethod)
{
__state.Stop();
// ....
}
}
The problem here is that the __originalMethod doesn't take care if it was called from A or B.
So for example, we had patched string.Join method. And the we call from A or B, where A or B, is the full callstack of this method.
So first, we need to assign a ID to this call, and we need to create a Tree-based structure (which is hard to serialize later), from here (https://stackoverflow.com/a/36649069/3286975):
public class TreeModel : Tree<TreeModel>
{
public int ID { get; set; }
public TreeModel() { }
public TreeModel(TreeModel parent) : base(parent) { }
}
public class Tree<T> where T : Tree<T>
{
protected Tree() : this(null) { }
protected Tree(T parent)
{
Parent=parent;
Children=new List<T>();
if(parent!=null)
{
parent.Children.Add(this as T);
}
}
public T Parent { get; set; }
public List<T> Children { get; set; }
public bool IsRoot { get { return Parent==null; } }
public T Root { get { return IsRoot?this as T:Parent.Root; } }
public T RecursiveFind(Predicate<T> check)
{
if(check(this as T)) return this as T;
foreach(var item in Children)
{
var result=item.RecursiveFind(check);
if(result!=null)
{
return result;
}
}
return null;
}
}
Now, the thing is that we need to fill the Tree as long as we iterate all the method and instructions got from Harmony. Forget about Harmony for a second, I will explain only two facts about it.
The lib allows you first to get all patched methods through IEnumerable<MethodBase> TargetMethods() so, you have the Assembly X passed through reflection and filtered all methods that are allowed to be patched (some of them broke Unity, so I decided to skip methods from UnityEngine., UnityEditor. and System.* namespaces).
And we have also the ReadMethodBody method (https://harmony.pardeike.net/api/HarmonyLib.PatchProcessor.html#HarmonyLib_PatchProcessor_ReadMethodBody_System_Reflection_MethodBase_) from a given MethodBase it returns all IL stack instructions.
So we can start to iterate over and over in order to get all instructions and fill the entire tree. This is what I wrote last night:
internal static class BenchmarkEnumerator
{
internal static Dictionary<MethodBase, int> Mappings { get; } = new Dictionary<MethodBase, int>();
internal static Dictionary<int, TreeModel> TreeIDs { get; } = new Dictionary<int, TreeModel>();
internal static Dictionary<MethodBase, BenchmarkTreeModel> TreeMappings { get; } = new Dictionary<MethodBase, BenchmarkTreeModel>();
private static HashSet<int> IDUsed { get; } = new HashSet<int>();
public static int GetID(this MethodBase method)
{
return GetID(method, out _);
}
public static int GetID(this MethodBase method, out bool contains)
{
// A > X = X1
// B > X = X2
if (!Mappings.ContainsKey(method))
{
var id = Mappings.Count;
Mappings.Add(method, Mappings.Count);
IDUsed.Add(id);
contains = false;
return id;
}
contains = true;
return Mappings[method];
}
public static int GetFreeID()
{
int id;
Random rnd = new Random();
do
{
id = rnd.Next();
} while (IDUsed.Contains(id));
IDUsed.Add(id);
return id;
}
public static BenchmarkCall GetCall(int id)
{
return TreeIDs[id]?.Call;
}
public static BenchmarkCall GetCall(this MethodBase method)
{
return TreeIDs[Mappings[method]]?.Call;
}
}
The BenchmarkEnumerator class allow us to differentiate between A or B, but it doesn't care about the full hierarchy, only from the parent MethodBase itself, so I need to write something complex to take in care of the full call stack, which I said I have a problem to understand.
Then we have the TargetMethods:
private static IEnumerable<MethodBase> TargetMethods()
{
Model = new BenchmarkTreeModel();
var sw = Stopwatch.StartNew();
//int i = 0;
return Filter.GetTargetMethods(method =>
{
try
{
var instructions = PatchProcessor.ReadMethodBody(method);
var i = method.GetID(out var contains);
var tree = new TreeModel
{
ID = i
};
if (contains)
{
//var lastId = i;
i = GetFreeID();
tree.ID = i;
tree.FillMethodName($"{method.GetMethodSignature()}_{i}"); // TODO: Check this
tree.Parent = null;
tree.Children = TreeMappings[method].Forest.First().Children; // ??
//DictionaryHelper.AddOrAppend(TreeMappings, method, tree);
TreeMappings[method].Forest.Add(tree);
TreeIDs.Add(i, tree);
Model.Forest.Add(tree);
// UNIT TESTING: All contained methods at this point will have a parent.
// string.Join is being added as a method by a instruction, so when we try to patch it, it will have already a reference on the dictionary
// Here, we check if the method was already added by a instruction CALL
// Logic: If the method is already contained by the mapping dictionary
// then, we will exit adding a new that will have the same childs but a new ID
return false;
}
TreeIDs.Add(i, tree);
tree.FillMethodName($"{method.GetMethodSignature()}_{i}"); // TODO: Check this
foreach (var pair in instructions)
{
var opcode = pair.Key;
if (opcode != OpCodes.Call || opcode != OpCodes.Callvirt) continue;
var childMethod = (MethodBase)pair.Value;
var id = childMethod.GetID(out var _contains);
var subTree = new TreeModel(tree)
{
ID = id
};
if (_contains)
{
id = GetFreeID();
subTree.ID = id;
subTree.FillMethodName($"{childMethod.GetMethodSignature()}_{id}"); // TODO: Check this
subTree.Parent = TreeIDs[i];
subTree.Children = TreeMappings[childMethod].Forest.First().Children;
TreeIDs.Add(id, subTree);
continue;
}
TreeIDs.Add(id, subTree);
subTree.FillMethodName($"{childMethod.GetMethodSignature()}_{id}");
tree.Children.Add(subTree);
TreeMappings.Add(childMethod, new BenchmarkTreeModel());
TreeMappings[childMethod].Forest.Add(subTree);
}
TreeMappings.Add(method, new BenchmarkTreeModel());
TreeMappings[method].Forest.Add(tree);
Model.Forest.Add(tree);
return true;
//var treeModel = new TreeModel();
}
catch (Exception ex)
{
//Debug.LogException(new Exception(method.GetMethodSignature(), ex));
return false;
}
}, sw);
//return methods;
}
The GetMethodSignature is something like:
public static string GetMethodSignature(this MethodBase method)
{
if (method == null) return null;
return method.DeclaringType == null ? method.Name : $"{method.DeclaringType.FullName}.{method.Name}";
}
I think I'll replace it with the MethodBase.ToString instead (what do you think?)
Also, we have the BenchmarkCall class which allow us to take in care how many times the call was done and how many time it has spent at all:
[Serializable]
public class BenchmarkCall
{
public string Method { get; set; }
public double SpentMilliseconds { get; set; }
public long SpentTicks { get; set; }
public double MinSpentMs { get; set; } = double.MaxValue;
public double MaxSpentMs { get; set; } = double.MinValue;
public long MinSpentTicks { get; set; } = long.MaxValue;
public long MaxSpentTicks { get; set; } = long.MinValue;
public double AvgMs => SpentMilliseconds / TimesCalled;
public double AvgTicks => SpentTicks / (double)TimesCalled;
public BenchmarkCall()
{
}
public BenchmarkCall(MethodBase method)
{
Method = method.GetMethodSignature();
}
public override string ToString()
{
if (TimesCalled > 0)
return "BenchmarkCall{\n" +
$"Ticks[SpentTicks={SpentTicks},MinTicks={MinSpentTicks},MaxTicks={MaxSpentTicks},AvgTicks={AvgTicks:F2}]\n" +
$"Ms[SpentMs={SpentMilliseconds:F2},MinMs={MinSpentMs:F2},MaxMs={MaxSpentMs:F2},AvgMs={AvgMs:F2}]\n" +
"}";
return "BenchmarkCall{}";
}
}
}
So I think that my next movement will be to differentiate between X method being called from A or B (Xa or Xb) taking care of the full hierarchy (which I'm not sure how to do) instead of the parent method that calls it, maybe the code I wrote has some to do it with it, but I'm not sure (last night I was so tired, so I didn't code it taking care those facts), build up a list of method signatures with different IDs, and then fill up the tree, ID 1 is Xa and ID 2 is Xb (where I have problems also filling up the tree).
Also I'll need to use the Transpiler in order to alter all code instructions, so if a method has:
void method() {
X1();
X2();
}
We will need to add 2 methods (like prefix/postfix) to measure each instruction call:
void method() {
Start(1);
X1();
End(1);
Start(2);
X2();
End(2);
}
This will be a hard task, but I hope somebody could guide me with this out.
I need to find if the playlist is repeating. From my below code pls help to suggest a solution.
A playlist is considered a repeating playlist if any of the songs contain a reference to a previous song in the playlist. Otherwise, the playlist will end with the last song which points to null.
using System;
public class Song
{
private string name;
public Song NextSong { get; set; }
public Song(string name)
{
this.name = name;
}
public bool IsRepeatingPlaylist()
{
if(this.name == NextSong.name)
{
return true;
}
else
{
return false;
}
}
public static void Main(string[] args)
{
Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");
first.NextSong = second;
second.NextSong = first;
Console.WriteLine(first.IsRepeatingPlaylist());
}
}
This would appear to be equivalent to checking for cycles in a linked-list, so we can simply use Floyd's "Tortoise and Hare" cycle detection algorithm:
public bool IsRepeatingPlaylist()
{
var tortoise = this;
var hare = NextSong;
while (tortoise is not null && hare is not null)
{
if (ReferenceEquals(tortoise, hare))
return true;
tortoise = tortoise.NextSong;
hare = hare.NextSong?.NextSong; // Twice as fast.
}
return false;
}
Here's some code that tests a playlist where the end of the play list loops back to a song about halfway through the playlist:
static void Main()
{
Song start = new Song("1");
Song curr = start;
Song halfway = null;
for (int i = 2; i < 100; ++i)
{
curr.NextSong = new Song(i.ToString());
curr = curr.NextSong;
if (i == 50)
halfway = curr;
}
curr.NextSong = halfway;
Console.WriteLine(start.IsRepeatingPlaylist());
}
public boolean isRepeatingPlaylist() {
Song next = this.NextSong;
while (next != null) {
if (next.name.equalsIgnoreCase(name)) {
return true;
}
next = next.NextSong;
}
return false;
}
If playlist repeats, starting songs can be skipped.
To respond to this condition we need to use collections to register every song to ensure that aren't no circular playlist at the medium.
The use of HashSet is to ensure that our script is runing fine on a large playlist.
public bool Contains (T item);
The time complexity of this method is O(1).
public bool IsRepeatingPlaylist()
{
var playList = new HashSet<Song>(){this};
var song = this.NextSong;
while (song != null) {
if (playList.Contains(song)) {
return true;
} else {
playList.Add(song);
song = song.NextSong;
}
}
return false;
}
public bool IsRepeatingPlaylist()
{
var first = this;
var second = NextSong;
while (first is not null && second is not null)
{
if (ReferenceEquals(first, second))
return true;
first = first.NextSong;
second = second.NextSong?.NextSong; // Twice as fast.
}
return false;
}
Create a list for playlist songs. Before adding a next song to list, check if song is not null and if it already exist in list.
If null, not a repetitive playlist.
if doesn't exist, add to list and continue the logic.
If exists, its repetitive playlist.
public bool IsInRepeatingPlaylist()
{
List<string> songsList = new List<string>();
songsList.Add(this.name);
Song thenext = this.NextSong;
while (thenext != null)
{
if (songsList.Contains(thenext.name))
{
return true;
}
else
{
songsList.Add(thenext.name);
thenext = thenext.NextSong;
}
}
return false;
}
I have created a simple list class from scratch. This is for a class assignment that I have been working on for about a week - very new to lists. We can not use generics so trying to research my question below has not been fruitful. Although I did get to watch 7 tutorials on youtube by BetterCoder and I found some stuff in my book but nothing with an example of "merging".
I have three classes - my node, my list, and my program. In my list class, I am working on building a Merge() method which eventually will compare the data in the two lists and merge them into an ordered list.
Right now for some reason my Merge method - which is very basic to help me understand what is happening - is not working correctly. It has both lists passed to it, and is adding the data from listTwo to listOne BUT for some reason when it's printing to the console the second Node's Data shows twice :
EX: 1 -> 2 -> 2
instead of printing the head (1), the next (2) and then the next (3) which it should be.
EX: 1 -> 2 -> 3
In the program class I have proven with a write line that (listOne.firstNode.Next.Next.Data) = 3 . Which it should be.
Can someone help me figure out if the nodes in list one aren't pointing to each other correctly or whatever is going on?
My Merge Method must be passed both list objects (listOne and listTwo) and eventually I need to make those passed as references but I haven't figured that out quite yet and will focus on that later I suppose.
namespace LinkedList
{
//This is my Node Class
class Node
{
public object Data { get; set; }
public Node Next { get; set; }
public Node(object dataValue) : this(dataValue, null) { }
public Node(object dataValue, Node nextNode)
{
Data = dataValue;
Next = nextNode;
}
}
//This is my List Class
class List
{
public Node firstNode;
public int count;
public List()
{
firstNode = null;
}
public bool Empty
{
get { return this.count == 0; }
}
public int Count
{
get { return this.count; }
}
public object Add(int index, object o)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (index > count)
index = count;
Node current = this.firstNode;
if (this.Empty || index == 0)
{
this.firstNode = new Node(o, this.firstNode);
}
else
{
for (int i = 0; i < index - 1; i++)
current = current.Next;
current.Next = new Node(o, current.Next);
}
count++;
return o;
}
public object Add(object o)
{
return this.Add(count, o);
}
public object Merge(List a, List b)
{
a.Add(b.firstNode.Data);
return a;
}
public void Print()
{
while (this.count > 0)
{
Console.Write(firstNode.Data + "->");
if(firstNode.Next != null)
firstNode.Data = firstNode.Next.Data;
count--;
}
}
}
//And here is my Program
class Program
{
static void Main(string[] args)
{
List listOne = new List();
List listTwo = new List();
listOne.Add(1);
listOne.Add(2);
listTwo.Add(3);
listTwo.Print();
Console.WriteLine("");
listOne.Merge(listOne, listTwo);
Console.WriteLine("");
listOne.Print();
//This line below shows that the data "3" from listTwo is being added to listOne in the list Merge Method
//Console.WriteLine(listOne.firstNode.Next.Next.Data);
Console.ReadKey();
}
}
}
Actual problem in your print method
public void Print()
{
Node node = firstNode;
for (int i = 0; i < this.count; i++)
{
Console.Write(node.Data + "->");
if (node.Next != null)
node = node.Next;
}
}
Alex Sikilinda , you are right the merge method is incomplete.
public object Merge(List a, List b)
{
Node bNode = b.firstNode;
while (bNode != null)
{
a.Add(bNode.Data);
bNode = bNode.Next;
}
return a;
}
I would write it this way:
public void Merge(List b)
{
Node lastNode = GetLastNode();
if (lastNode != null)
{
lastNode.Next = b.firstNode;
}
else
{
this.firstNode = b.firstNode;
}
}
// this method is used to find the last node in current list
private Node GetLastNode()
{
if (this.firstNode == null)
{
return null;
}
Node current = this.firstNode;
while (current.Next != null)
{
current = current.Next;
}
return current;
}
First of all, I changed signature of Merge from public object Merge(List a, List b) to public void Merge(List b). Now we can use it like this:
listOne.Merge(listTwo);
This will link listOne's last element with the first element of listTwo and thus they are merged.
Now we need to change Print method since current version modifies the list, which shouldn't happen:
public void Print()
{
Node currentNode = this.firstNode;
while(currentNode != null)
{
Console.Write(currentNode.Data + ' ');
currentNode = currentNode.Next;
}
}
Instead of assigning the data back to first node I assign the
firstNode = firstNode.Next;
Please check the below Print Code
public void Print()
{
while (this.count > 0)
{
Console.Write(firstNode.Data + "->");
if (firstNode.Next != null)
firstNode = firstNode.Next;
count--;
}
}
I'm having some strange results with PLINQ that I can't seem to explain. I've been trying to parallelize an Alpha Beta tree search to speed up the search process, but it is effectively slowing it down. I'd expect as I raise the degree of parallelism, I'd linearly increase nodes per second... and take a hit with additional nodes processed as pruning is pushed off until later. While the node count matches expectation, my times don't:
non-plinq,
nodes visited: 61418,
runtime: 0:00.67
degree of parallelism: 1,
nodes visited: 61418,
runtime: 0:01.48
degree of parallelism: 2,
nodes visited: 75504,
runtime: 0:10.08
degree of parallelism: 4,
nodes visited: 95664,
runtime: 1:51.98
degree of parallelism: 8,
nodes visited: 108148,
runtime: 1:48.94
Anyone help me with identifying the likely culprits?
relevant code:
public int AlphaBeta(IPosition position, AlphaBetaCutoff parent, int depthleft)
{
if (parent.Cutoff)
return parent.Beta;
if (depthleft == 0)
return Quiesce(position, parent);
var moves = position.Mover.GetMoves().ToList();
if (!moves.Any(m => true))
return position.Scorer.Score();
//Young Brothers Wait Concept...
var first = ProcessScore(moves.First(), parent, depthleft);
if(first >= parent.Beta)
{
parent.Cutoff = true;
return parent.BestScore;
}
//Now parallelize the rest...
if (moves.Skip(1)
.AsParallel()
.WithDegreeOfParallelism(1)
.WithMergeOptions(ParallelMergeOptions.NotBuffered)
.Select(m => ProcessScore(m, parent, depthleft))
.Any(score => parent.BestScore >= parent.Beta))
{
parent.Cutoff = true;
return parent.BestScore;
}
return parent.BestScore;
}
private int ProcessScore(IMove move, AlphaBetaCutoff parent, int depthleft)
{
var child = ABFactory.Create(parent);
if (parent.Cutoff)
{
return parent.BestScore;
}
var score = -AlphaBeta(move.MakeMove(), child, depthleft - 1);
parent.Alpha = score;
parent.BestScore = score;
if (score >= parent.Beta)
{
parent.Cutoff = true;
}
return score;
}
And then the data structure for sharing Alpha Beta parameters across levels of the tree...
public class AlphaBetaCutoff
{
public AlphaBetaCutoff Parent { get; set; }
private bool _cutoff;
public bool Cutoff
{
get
{
return _cutoff || (Parent != null && Parent.Cutoff);
}
set
{
_cutoff = value;
}
}
private readonly object _alphaLock = new object();
private int _alpha = -10000;
public int Alpha
{
get
{
if (Parent == null) return _alpha;
return Math.Max(-Parent.Beta, _alpha);
}
set
{
lock (_alphaLock)
{
_alpha = Math.Max(_alpha, value);
}
}
}
private int _beta = 10000;
public int Beta
{
get
{
if (Parent == null) return _beta;
return -Parent.Alpha;
}
set
{
_beta = value;
}
}
private readonly object _bestScoreLock = new object();
private int _bestScore = -10000;
public int BestScore
{
get
{
return _bestScore;
}
set
{
lock (_bestScoreLock)
{
_bestScore = Math.Max(_bestScore, value);
}
}
}
}
When you do only very little work and setoff new threads for all underlying nodes you create a huge overhead on threading. You are probably processing more nodes because of the Any, normally the processing whould stop, but some nodes have started processing before Any (the first match) was found. Parallelism will better work when you have a known set of large underlying workloads. You can try what happens if you only do parallelism at your top level node(s).