how to code simple minimax algorithm in C#? - recursion

i want to build a simple tree and compare the child and recursive call, its like a mini-max algorithm. compare the value of each node and return the child of root.
i have tried all the day and i cant code it right yet. if u have experience with mini-max algorithm please help me or if u have any source to learn about it please tell me.
can someone make an example code with 3 or more depth (iteration) based on this node ?
class node
{
public int value;
public int id;
public List <node> child = new List <node>();
}

Try this:
make global variable:
public node minNode;
public node maxNode;
create function :
public void Compare(node currentNode)
{
if (minNode.value>currentNode.value)
{
minNode=currentNode;
}
if (maxNode.value<currentNode.value)
{
maxNode=currentNode;
}
foreach(var currNode in currentNode.child)
{
Compare(currNode);
}
}
and then in your code call it:
minNode=rootNode;
maxNode=rootNode;
Compare(rootNode);
And after that your will take max and min in this variable, where rootNode is your root node in a tree

Related

Sum up the tree nodes using Java 8 Streams

Is it possible to sum up the nodes of a tree using Java 8 streams, if possible in a one liner ?
Here is a node class
public class Node
{
private int nodeNum;
ArrayList<Node> children = new ArrayList<>();
public Node(int num)
{
this.nodeNum = num;
}
public int getNodeNum()
{
return nodeNum;
}
public boolean addNode(Node node)
{
return children.add(node);
}
public ArrayList<Node> getNodes()
{
return this.children;
}
}
Normal way to solve this is using a recursion and sum up the node , like the code below.
int getNodeSum(Node node)
{
int total = 0;
if(node.children.isEmpty())
return node.getNodeNum();
else
{
for(Node tempNode:node.children)
{
total+= getNodeSum(tempNode);
}
return total+node.getNodeNum();
}
}
We can use streams to sum up the immediate child nodes but I'm not getting how to move deep and do it recursively using Streams.
This code only solves the problem to a single level. Any ideas?
total = list.stream().filter(Node -> node.children.isEmpty()).map(Node:: getNodeNum).reduce(node.getNodeNum(), (a,b) -> a+b);
One solution to your problem would be to use recursion along with Stream.flatMap.
First, you'd need to add the following helper method to your Node class:
public Stream<Node> allChildren() {
return Stream.concat(
Stream.of(this),
this.children.stream().flatMap(Node::allChildren)); // recursion here
}
This returns a Stream<Node> whose elements are this node and all its descendant nodes.
Then, you could rewrite your getNodeSum method as follows:
int getNodeSum(Node node) {
return node.allChildren()
.mapToInt(Node::getNodeNum)
.sum();
}
This uses the above defined Node.allChildren method along with the Stream.mapToInt and IntStream.sum methods to calculate the total sum.
Alternatively, you could have a Function<Node, Stream<Node>> descendants attribute in your Node class that performs the recursion in place:
private Function<Node, Stream<Node>> descendants =
node -> Stream.concat(
Stream.of(node),
node.children.stream()
.flatMap(this.descendants)); // recursion here: function invoked again
This is a recursive lambda expression, since the function you are defining is at both sides of the = sign. This kind of lambda expressions are allowed only as attributes of a class, i.e. you cannot assign a recursive lambda expression to a local variable.
With that recursive function in place, you could rewrite the allChildren method as follows:
public Stream<Node> allChildren() {
return descendants.apply(this);
}
Finally, the code for your getNodeSum method would be identical to the previous version:
int getNodeSum(Node node) {
return node.allChildren()
.mapToInt(Node::getNodeNum)
.sum();
}
Note: while this approach might result attractive for some people, it might have some drawbacks, i.e. now every instance of the Node class has the descendants attribute, despite not being needed at all. You could circumvect this i.e. by having a Tree class with this recursive function as an attribute, and Node being an inner class (with the descendants attribute removed).
You need to add recusive method for Node class, which wil be join child streams
public Stream<Node> recursiveConcat() {
return Stream.concat(
Stream.of(this),
children.stream().flatMap(Node::recursiveConcat));
}
Then do -
root.recusiveConcat().mapToInt(Node::getNodeNum).sum()
whole code
public class Node {
private int nodeNum;
ArrayList<Node> children = new ArrayList<>();
public Node(int num) {
this.nodeNum = num;
}
public int getNodeNum() {
return nodeNum;
}
public boolean addNode(Node node) {
return children.add(node);
}
public ArrayList<Node> getNodes() {
return this.children;
}
public Stream<Node> recursiveConcat() {
return Stream.concat(
Stream.of(this),
children.stream().flatMap(Node::recursiveConcat));
}
}
Node root = new Node(1);
Node node1 = new Node(2);
Node node2 = new Node(3);
Node node3 = new Node(4);
node2.addNode(node3);
node1.addNode(node2);
root.addNode(node1);
System.out.println(root.recursiveConcat().mapToInt(Node::getNodeNum).sum());

BinaryTree count leaves infinite loof

I wrote countLeaf method in my binary tree class to count every leaves from root.
However, it gave me stack overflow error, but I couldn't figure what I did wrong.
this is the countLeaf class from my binaryTree
public int countLeaf(Node node){
if(root == null){return 0;} // this part work when I create null Tree
else if(root.left == null && root.right == null){
return 1; //this work when I create tree without left and right
}
else {
System.out.print(root.data); // check infinite loop
return countLeaf(root.left) + countLeaf(root.right);
}
}
And this is my main
public static void main (String[] args){
BinaryTree a = new BinaryTree("A?",
new BinaryTree("B?",
new BinaryTree("D"),
new BinaryTree("E")),
new BinaryTree("C?",
new BinaryTree("E"),
new BinaryTree("F")));
System.out.print(a);
int n = a.countLeaf(a.root);
}
and when I run it, it gave me
A?A?A?A?A?A?A?A?A?A?A?A?A? ... and stackoverflow error
why it keep repeating original root instead of follow left or right??
Replace public int countLeaf(Node node) with public int countLeaf(Node root).
I believe it will help.
Anyways, variable node is never used.

Rebuild BST from preorder, error in logic

Trying to wrap my head around how to correct my code. I have the idea up, but I get stuck during the implementation.
when I step through the code below, I can reconstruct part of the BST from a pre-order traversal. But at some point, I will have function call like:
recon(preOrd,2,2)
which results in a leaf not being assigned. I do yet know how to correct this.
I have seen other threads on this topic, but want to iron out my issue so I can really learn this concept of rebuilding the BST.
public static Node recon(int[] preOrd,int start,int end){
if (start==end){
return null;
}
Node root = new Node (preOrd[start]);
int div=start;
for (i=start+1;i<=end && preOrd[i]<preOrd[start];i++){
div=i;
}
Node left= reconstruct(preOrd,start+1,div);
Node right= reconstruct(preOrd,div+1,end);
root.setLeft= left;
root.setRight=right;
return root;
}
Turns out this is pretty straightforward. Just needed to correct my thinking on the updating of leaf nodes..
public static Node recon(int[] preOrd,int start,int end){
Node root = new Node (preOrd[start]);//declare the new node
if (start>end){ //this is illegal, so return null
return null;
}
if (start==end){
return root;
}
int div=start;
for (int i=start+1;i<=end preOrd[i]<preOrd[start];i++){
div=i;
}
Node left= reconstruct(preOrd,start+1,div);
Node right= reconstruct(preOrd,div+1,end);
root.setLeft= left;
root.setRight=right;
return root;
}

Binding to a Property that only have get method

I have a question regarding binding in WinRT.
I have a Viewmodel like this:
public class MainPageViewModel : INotifyPropertyChanged
{
private ObservableCollection<Vehicle> _vehicles = new ObservableCollection<Vehicle>();
public ObservableCollection<Vehicle> Vehicles
{
get { return _vehicles; }
set { _vehicles = value; }
}
and also I have some properties that I get the value from this main list, for example
public int GetType1Vehicles
{
get { return Vehicles.Where(x => x.Type == Type1).Count(); }
}
public int TotalVehicles
{
get { return Vehicles.Count(); }
}
I binded a UI textbox to a "GetType1Vehicles" and another textbot to a "TotalVehicles". The problem is that when I update the Vehicle List, the ListView with all vehicles is correctly updated but the Total and the Type don't. What I doing wrong?
Anybody can help me? Thanks!
UPDATE
I found a workarround, but I'm not sure that is the best approach. Every time that I change some from the list, call manually the methods:
RaisePropertyChanged("GetType1Vehicles");
RaisePropertyChanged("TotalVehicles");
Is the correct approach?
You are correct in that you will need to manually call RaisePropertyChanged. Anyway, why do you have a TotalVehicles property when you could just bind to "Vehicles.Count"?
David is right, why this TotalVehicles property ?
With an ObservableCollection, you should not call the Count() method, just use the Count property.
The Count method is usefull if you want to count only the items with a specific value, not the size of the collection, that's the job of the property.

How to generate a sitemap ?(asp.net mvc3)

This is my database table
DB Table
how to generate a sitemap?
controller is category
action is Id
that is look like it
Page
TreeMenu.cs:
using System;
using System.Collections.Generic;
namespace Pmvc.Models
{
public partial class TreeMenu
{
public int TreeId { get; set; }
public int TreeParentId { get; set; }
public string TreeName { get; set; }
public List<TreeMenu> Children { get; set; }
}
}
StoreDetailsDynamicNodeProvider.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcSiteMapProvider.Extensibility;
using Pmvc.Models;
namespace Pmvc
{
public class StoreDetailsDynamicNodeProvider : DynamicNodeProviderBase
{
PMVCEntities pmvcDB = new PMVCEntities();
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
var nodes = new List<DynamicNode>();
foreach (var treemenu in pmvcDB.TreeMenu)
{
nodes.Add(CreateNode(treemenu));
}
return nodes;
}
private DynamicNode CreateNode(TreeMenu treemenu)
{
DynamicNode node = new DynamicNode();
node.Action = "ProductDetails";
node.Controller = "Product";
node.Title = treemenu.TreeName;
if (treemenu.Children != null)
{
foreach (var child in treemenu.Children)
{
node.Children.Add(CreateNode(child)); //This line is wrong!
}
}
return node;
}
}
}
wrong:
'MvcSiteMapProvider.Extensibility.DynamicNode' is not include 'Children' definition,and not find Extension Methods 'Children'
public class StoreDetailsDynamicNodeProvider : DynamicNodeProviderBase
{
PMVCEntities pmvcDB = new PMVCEntities();
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
// Build value
var returnValue = new List<DynamicNode>();
// Create a node for each album
foreach (var treemenu in pmvcDB.TreeMenu)
{
DynamicNode node = new DynamicNode();
node.Action = "ProductDetails";
node.Controller = "Product";
node.Title = treemenu.TreeName;
node.RouteValues.Add("id", treemenu.TreeId);
returnValue.Add(node);
}
// Return
return returnValue;
}
}
This is my table
TreeId TreeParentId TreeName
1 0 Category 1
2 1 Menu Item X
3 1 Menu Item Y
4 1 Menu Item Z
5 0 Category 2
6 5 Other Menu 1
7 5 Other Menu 2
8 0 Empty Category
9 7 Menu Lvl 3
How do I write child node code?
Take a look at the MvcSitemap provider. It's pretty easy to write a dynamic provider that reads from your database.
Edit - did you read the documentation or attempt to implement anything? Copied almost verbatim from their site:
Within the sitemap config file, add the dynamic node where appropriate:
<mvcSiteMapNode
title="Details"
action="Details"
dynamicNodeProvider="MyProjectName.MyDynamicNodeProvider, MyProjectName" />
Then, write the actual node provider:
public class MyDynamicNodeProvider
: DynamicNodeProviderBase
{
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
// Build value
var returnValue = new List<DynamicNode>();
// ... Here, get values from your database and build up
// the list of nodes. They can be in a tree structure
// too since it appears that's how your data is - just
// build the nodes in that way with sub-lists.
// Return
return returnValue;
}
}
And that's it.
Edit 2 - addressing other answer.
The code that you provided flattens the tree structure. In your original post you showed that you are already able to print the tree structure. Whatever code you had in your view, you can apply the same principles of a depth-first traversal.
Just in case that was a mockup and not actual code, here's some quick psuedo code to demonstrate an depth-first traversal.
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
// Build value
var nodes = new List<DynamicNode>();
// Get all categories without parents.
var rootCategories = db.GetRootCategories();
// Loop all root level categories, creating a node for each and adding
// to the return value.
foreach (var category in rootCategories)
{
nodes.Add(CreateNode(category));
}
return nodes;
}
private DynamicNode CreateNode(Category category)
{
// Create a new node for the category
DynamicNode node = new DynamicNode();
node.Name = category.Name;
// ... set node properties here ...
// If the category has children, then continue down the tree
// and create nodes for them. This will continue recursively
// to the bottom of the tree.
// Note that I'm just guessing on the property names because
// you didn't show us the code for what your entity actually
// looks like. This is why you should always show what code
// you've attempted - you can get better, more precise answers
// instead of complete guesses.
if (category.Children != null)
{
foreach (var child in category.Children)
{
// For each child, recursively branch into them.
node.Children.Add(CreateNode(child));
}
}
return Node;
}
Please note that this is no way tested or researched - it's only to show a tree traversal.

Resources