قطعه برنامه بررسی مشبکه بودن گراف بهمراه سورس

در قطعه برنامه تهیه شده، مشخصات گراف را در قالب یک ماتریس به برنامه داده و برنامه اعلام می‌کند که این گراف مشبکه هست یا خیر.




تعریف مشبکه در ریاضیات گسسته

مجموعه‌ای با ترتیب جزئی (A, R) را یک مشبکه گویند هرگاه هر زیر مجموعه دو عضوی از این مجموعه دارای LUB یا Least Upper Bound و GLB یا Greatest Lower Bound باشد.


کد برنامه

کد اصلی برنامه کلاس Graph می‌باشد که به صورت زیر پیاده سازی شده است:


فایل Graph.cs

using System;
using System.Collections.Generic;
using System.Linq;

namespace LatticeGraph
{
    public class Graph
    {
        private readonly int[,] _matrix;
        private List<List<int>> _lowerPaths;
        private List<List<int>> _upperPaths;
        private List<int> _currentPath;
        private Dictionary<int, int> _nodesLevel;
        private readonly int _nodeCount;

        public Graph(int[,] matrix)
        {
            _matrix = matrix;
            _nodeCount = (int)Math.Sqrt(_matrix.Length);
        }

        public Dictionary<int, int> NodesLevel
        {
            get { return _nodesLevel; }
        }

        public bool IsLattice()
        {
            CalculateNodeLevels();

            for (var i = 0; i < _nodeCount; i++)
            {
                for (var j = 0; j < _nodeCount; j++)
                {
                    if (i == j) continue;
                    var lub = GetLub(i, j);
                    if (!checkLub(lub)) return false;
                    var glb = GetGlb(i, j);
                    if (!checkGlb(glb)) return false;
                }
            }
            return true;
        }

        private bool checkGlb(List<Junction> glb)
        {
            if (glb == null) return false;
            if (glb.Count == 1) return true;

            var glbNodes = glb.Select(x => x.Node).ToList();
            var levels = _nodesLevel.Where(x => glbNodes.Contains(x.Key)).ToList();
            var maxValue = levels.Max(x => x.Value);
            return levels.Count(x => x.Value == maxValue) == 1;
        }

        private bool checkLub(List<Junction> lub)
        {
            if (lub == null) return false;
            if (lub.Count == 1) return true;

            var glbNodes = lub.Select(x => x.Node).ToList();
            var levels = _nodesLevel.Where(x => glbNodes.Contains(x.Key)).ToList();
            var minValue = levels.Min(x => x.Value);
            return levels.Count(x => x.Value == minValue) == 1;
        }

        public void CalculateNodeLevels()
        {
            _nodesLevel = new Dictionary<int, int>();
            for (int i = 0; i < _nodeCount; i++)
            {
                var lowerPaths = LowerPaths(i);
                var maxPath = lowerPaths.Max(x => x.Count);
                _nodesLevel.Add(i, maxPath);
            }
        }

        public List<Junction> GetGlb(int i, int j)
        {
            var iLowerPaths = LowerPaths(i);
            var jLowerPaths = LowerPaths(j);

            var pathJunctions = new List<Junction>();

            foreach (var iPath in iLowerPaths)
            {
                foreach (var jPath in jLowerPaths)
                {
                    for (var x = 0; x < iPath.Count; x++)
                    {
                        var junctionFounded = false;
                        for (var y = 0; y < jPath.Count; y++)
                        {
                            if (iPath[x] != jPath[y]) continue;
                            pathJunctions.Add(new Junction(iPath[x], x));
                            junctionFounded = true;
                            break;
                        }
                        if (junctionFounded)
                        {
                            break;
                        }
                    }
                }
            }

            if (pathJunctions.Count <= 0) return null;
            var minPath = pathJunctions.Min(x => x.PathPartCount);
            return pathJunctions.Where(x => x.PathPartCount == minPath)
                .DistinctBy(d => new { d.Node, d.PathPartCount })
                .ToList();
        }

        public List<List<int>> LowerPaths(int node)
        {
            _lowerPaths = new List<List<int>>();
            _currentPath = new List<int>();
            GetLowerPaths(node);
            return _lowerPaths;
        }

        public void GetLowerPaths(int node)
        {
            if (_currentPath.Count > _nodeCount)
            {
                throw new Exception("به نظر میرسد گراف هاس نمی‌باشد");
            }
            _currentPath.Add(node);

            var childNodes = getChildNodes(node);
            if (childNodes.Count == 0)
            {
                var path = new List<int>(_currentPath);
                _lowerPaths.Add(path);
            }
            else
            {
                foreach (var childNode in childNodes)
                {
                    GetLowerPaths(childNode);
                }
            }
            _currentPath.RemoveAt(_currentPath.Count - 1);
        }

        public List<List<int>> UpperPaths(int node)
        {
            _upperPaths = new List<List<int>>();
            _currentPath = new List<int>();
            GetUpperPaths(node);
            return _upperPaths;
        }

        public void GetUpperPaths(int node)
        {
            if (_currentPath.Count > _nodeCount)
            {
                throw new Exception("به نظر میرسد گراف هاس نمی‌باشد");
            }
            _currentPath.Add(node);

            var parentNodes = getParentNodes(node);
            if (parentNodes.Count == 0)
            {
                var path = new List<int>(_currentPath);
                _upperPaths.Add(path);
            }
            else
            {
                foreach (var parentNode in parentNodes)
                {
                    GetUpperPaths(parentNode);
                }
            }
            _currentPath.RemoveAt(_currentPath.Count - 1);
        }

        private List<int> getChildNodes(int node)
        {
            var result = new List<int>();
            for (var i = node; i < _nodeCount; i++)
            {
                if (i != node && _matrix[i, node] == 1)
                {
                    result.Add(i);
                }
            }
            return result;
        }

        private List<int> getParentNodes(int node)
        {
            var result = new List<int>();
            for (var i = 0; i < _nodeCount; i++)
            {
                if (i != node && _matrix[node, i] == 1)
                {
                    result.Add(i);
                }
            }
            return result;
        }

        public List<Junction> GetLub(int i, int j)
        {
            var iUpperPaths = UpperPaths(i);
            var jUpperPaths = UpperPaths(j);

            var pathJunctions = new List<Junction>();

            foreach (var iPath in iUpperPaths)
            {
                foreach (var jPath in jUpperPaths)
                {
                    for (var x = 0; x < iPath.Count; x++)
                    {
                        var junctionFounded = false;
                        for (var y = 0; y < jPath.Count; y++)
                        {
                            if (iPath[x] != jPath[y]) continue;
                            pathJunctions.Add(new Junction(iPath[x], x));
                            junctionFounded = true;
                            break;
                        }
                        if (junctionFounded)
                        {
                            break;
                        }
                    }
                }
            }

            if (pathJunctions.Count <= 0) return null;
            var minPath = pathJunctions.Min(x => x.PathPartCount);
            return pathJunctions.Where(x => x.PathPartCount == minPath)
                .DistinctBy(d => new { d.Node, d.PathPartCount })
                .ToList();
        }
    }
}


فایل Junction.cs

namespace LatticeGraph
{
    public class Junction
    {
        public Junction(int node, int pathPartCount)
        {
            Node = node;
            PathPartCount = pathPartCount;
        }

        public Junction()
        {
        }

        public int Node { get; set; }
        public int PathPartCount { get; set; }
    }
}


کد آزمون واحد برنامه

using System;
using System.Collections.Generic;
using LatticeGraph;
using NUnit.Framework;

namespace TestProject
{
    [TestFixture]
    public class TestLatticeGraph
    {
        private int[,] _matrix;
        private int[,] _matrix_2;

        [SetUp]
        public void Setup()
        {
            _matrix = new[,]
            {
                {0, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0},
                {0, 1, 0, 0, 0, 0},
                {0, 1, 1, 0, 0, 0},
                {0, 0, 0, 1, 1, 0}
            };

            _matrix_2 = new[,]
            {
                {0, 0, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0, 0},
                {0, 1, 0, 1, 0, 0, 0},
                {0, 0, 1, 1, 0, 0, 0},
                {0, 0, 0, 0, 1, 1, 0}
            };
        }

        [Test]
        public void Test_Is_Moshabbakeh()
        {
            var graph = new Graph(_matrix);
            Assert.True(graph.IsLattice());

            _matrix[3, 2] = 1; // Make graph non lattice

            graph = new Graph(_matrix);
            Assert.False(graph.IsLattice());
        }

        [Test]
        public void Test_Get_Lower_Paths()
        {
            var graph = new Graph(_matrix);
            var lowerPaths = graph.LowerPaths(1);
            Assert.AreEqual(2, lowerPaths.Count);
            Assert.AreEqual(3, lowerPaths[0].Count);
            Assert.AreEqual(3, lowerPaths[1].Count);

            Assert.AreEqual(new List<int>() { 1, 3, 5 }, lowerPaths[0]);
            Assert.AreEqual(new List<int>() { 1, 4, 5 }, lowerPaths[1]);

            graph = new Graph(_matrix);
            lowerPaths = graph.LowerPaths(0);
            Assert.AreEqual(3, lowerPaths.Count);

            Assert.AreEqual(new List<int>() { 0, 1, 3, 5 }, lowerPaths[0]);
            Assert.AreEqual(new List<int>() { 0, 1, 4, 5 }, lowerPaths[1]);
            Assert.AreEqual(new List<int>() { 0, 2, 4, 5 }, lowerPaths[2]);
        }

        [Test]
        public void Test_Get_GLB_On_Lattice_Graph()
        {
            var graph = new Graph(_matrix);
            var glb = graph.GetGlb(1, 2);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(4, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            glb = graph.GetGlb(2, 1);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(4, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            glb = graph.GetGlb(2, 3);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(2, glb[0].PathPartCount);

            glb = graph.GetGlb(3, 2);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            glb = graph.GetGlb(0, 5);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(3, glb[0].PathPartCount);
        }

        [Test]
        public void Test_Get_GLB_On_None_Lattice_Graph()
        {
            _matrix[3, 2] = 1; //Make matrix non lattice

            var graph = new Graph(_matrix);
            var glb = graph.GetGlb(1, 2);
            Assert.AreEqual(2, glb.Count);
            Assert.AreEqual(3, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            Assert.AreEqual(4, glb[1].Node);
            Assert.AreEqual(1, glb[1].PathPartCount);
        }

        [Test]
        public void Test_Get_Upper_Paths()
        {
            var graph = new Graph(_matrix);
            var upperPaths = graph.UpperPaths(4);
            Assert.AreEqual(2, upperPaths.Count);
            Assert.AreEqual(3, upperPaths[0].Count);
            Assert.AreEqual(3, upperPaths[1].Count);

            Assert.AreEqual(new List<int>() { 4, 1, 0 }, upperPaths[0]);
            Assert.AreEqual(new List<int>() { 4, 2, 0 }, upperPaths[1]);

            graph = new Graph(_matrix);
            upperPaths = graph.UpperPaths(5);
            Assert.AreEqual(3, upperPaths.Count);

            Assert.AreEqual(new List<int>() { 5, 3, 1, 0 }, upperPaths[0]);
            Assert.AreEqual(new List<int>() { 5, 4, 1, 0 }, upperPaths[1]);
            Assert.AreEqual(new List<int>() { 5, 4, 2, 0 }, upperPaths[2]);
        }

        [Test]
        public void Test_Get_LUB_On_Lattice_Graph()
        {
            var graph = new Graph(_matrix);
            var lub = graph.GetLub(3, 4);
            Assert.AreEqual(1, lub.Count);
            Assert.AreEqual(1, lub[0].Node);
            Assert.AreEqual(1, lub[0].PathPartCount);

            lub = graph.GetLub(4, 3);
            Assert.AreEqual(1, lub.Count);
            Assert.AreEqual(1, lub[0].Node);
            Assert.AreEqual(1, lub[0].PathPartCount);

            lub = graph.GetLub(2, 3);
            Assert.AreEqual(1, lub.Count);
            Assert.AreEqual(0, lub[0].Node);
            Assert.AreEqual(1, lub[0].PathPartCount);

            lub = graph.GetLub(0, 5);
            Assert.AreEqual(1, lub.Count);
            Assert.AreEqual(0, lub[0].Node);
            Assert.AreEqual(0, lub[0].PathPartCount);
        }

        [Test]
        public void Test_Get_LUB_On_None_Lattice_Graph()
        {
            _matrix[3, 2] = 1; //Make matrix non lattice

            var graph = new Graph(_matrix);
            var glb = graph.GetLub(3, 4);
            Assert.AreEqual(2, glb.Count);
            Assert.AreEqual(1, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            Assert.AreEqual(2, glb[1].Node);
            Assert.AreEqual(1, glb[1].PathPartCount);
        }

        [Test]
        public void Test_Is_Moshabbakeh_2()
        {
            var graph = new Graph(_matrix_2);
            Assert.True(graph.IsLattice());
        }

        [Test]
        public void Test_Get_GLB_On_Lattice_Graph_2()
        {

            var graph = new Graph(_matrix_2);
            var glb = graph.GetGlb(0, 5);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(2, glb[0].PathPartCount);

            glb = graph.GetGlb(4, 2);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(6, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            glb = graph.GetGlb(3, 2);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);
        }

        [Test]
        public void Test_Calculate_Node_level()
        {
            var graph = new Graph(_matrix);
            graph.CalculateNodeLevels();
            Assert.AreEqual(6, graph.NodesLevel.Count);
            int i;
            
            graph.NodesLevel.TryGetValue(5, out i);
            Assert.AreEqual(1, i);

            graph.NodesLevel.TryGetValue(4, out i);
            Assert.AreEqual(2, i);

            graph.NodesLevel.TryGetValue(3, out i);
            Assert.AreEqual(2, i);

            graph.NodesLevel.TryGetValue(2, out i);
            Assert.AreEqual(3, i);

            graph.NodesLevel.TryGetValue(1, out i);
            Assert.AreEqual(3, i);

            graph.NodesLevel.TryGetValue(0, out i);
            Assert.AreEqual(4, i);
        }
    }
}


دریافت فایل

فایل اجرایی برنامه بهمراه نمونه گراف مشبکه


سورس کامل برنامه + آزمون واحد

تنظیم IP کارت شبکه از طریق کدنویسی

توسط قطعه کد زیر می‌توانید از طریق کدنویسی IP Address و Default Getway و همچنین DNS Server مربوط به کارت شبکه مورد نظرتان را تغییر دهید.


این برنامه ابتدا مشخصات کارت شبکه مورد نظر را خوانده و با مشخصاتی که در فایل کانفیگ برنامه تعیین شده است تطابق می‌دهد. در صورتی‌که اطلاعات مغایرت داشته باشد، مشخصات داخل فایل کانفیگ را برای کارت شبکه مورد نظر اعمال می‌کند.

این قطعه کد، زمانی مفید است که بعنوان مثال شما یک سرور اختصاصی (VPS) دارید که به صورت Remote به آن دسترسی دارید. اگر به هر علت IP این سرور تغییر کند، سرور به کلی از دسترس خارج می‌شود و باید به شرکت ارائه دهنده سرویس تماس بگیرید تا مجدداً  IP سرور را تنظیم کنند.

 این برنامه را می‌توان در یک Task ویندوزی تنظیم کرد که در بازه‌های معین اجرا شود تا در صورتی که سرور از دسترس خارج شده باشد، با تنظیم مجدد IP سرور در دسترس قرار گیرد.

کد اصلی برنامه


using System;
using System.Collections.Generic;
using System.Configuration;
using System.Threading;

namespace SetIP
{
    class Program
    {
        private const int TryCount = 20;

        static void Main(string[] args)
        {
            try
            {
                var i = 0;
                var isEqual = false;
                while (!isEqual && i < TryCount)
                {
                    Console.WriteLine("Checking number: {0}", i + 1);
                    isEqual = checkAdapter();
                    i++;
                    Thread.Sleep(5000);
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private static bool checkAdapter()
        {
            var networkAdapterHelper = new NetworkAdapterHelper();

            var baseAdapter = new Adapter()
            {
                AdaptorName = ConfigurationManager.AppSettings["EthernetName"],
                Ip = ConfigurationManager.AppSettings["IP"],
                Subnet = ConfigurationManager.AppSettings["SubnetMask"],
                Getway = ConfigurationManager.AppSettings["DefaultGetway"],
                DnsServer = ConfigurationManager.AppSettings["DnsServer"],
                AlternativeDns = ConfigurationManager.AppSettings["AlterNativeDnsServer"]
            };

            networkAdapterHelper.Execute(new List<string>()
            {
                String.Format("netsh interface set interface name=\"{0}\" admin=enabled", baseAdapter.AdaptorName)
            }); 

            var currentAdapter = networkAdapterHelper.GetAdapterInformation(baseAdapter.AdaptorName);
            if (currentAdapter == null)
            {
                Console.WriteLine("Adapter not found!");
                return false;
            }
            if (networkAdapterHelper.IsEqual(currentAdapter, baseAdapter))
                return true;
            networkAdapterHelper.SetEthernetInformation(baseAdapter);
            return false;
        }
    }
}


کلاس Adapter

namespace SetIP
{
    public class Adapter
    {
        public string AdaptorName;
        public string Ip;
        public string Subnet;
        public string Getway;
        public string DnsServer;
        public string AlternativeDns;

        public Adapter()
        {
        }

        public Adapter(string adaptorName, string ip, string subnet, string getway, string dnsServer, string alternativeDns)
        {
            this.AdaptorName = adaptorName;
            this.Ip = ip;
            this.Subnet = subnet;
            this.Getway = getway;
            this.DnsServer = dnsServer;
            this.AlternativeDns = alternativeDns;
        }
    }
}


کلاس کمکی NetworkAdapterHelper

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace SetIP
{
    public class NetworkAdapterHelper
    {
        public Adapter GetAdapterInformation(string adapterName)
        {
            var adapter = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(x => x.Name == adapterName);
            if (adapter == null)
            {
                Console.WriteLine("Adapter {0} not found!", adapterName);
                return null;
            }

            var ip = getIpAddress(adapter);
            if (String.IsNullOrEmpty(ip))
            {
                Console.WriteLine("Cannot grab IP address information!");
                return null;
            }

            //var subnet = unicastIpAddressInformation.IPv4Mask.ToString();
            var subnet = GetSubnetMask(adapter);

            var result = new Adapter()
            {
                AdaptorName = adapter.Name,
                Ip = ip,
                Subnet = subnet,
                Getway = GetDefaultGateway(adapter)
            };

            GetDnsAddresses(adapter, out result.DnsServer, out result.AlternativeDns);
            return result;
        }

        private string getIpAddress(NetworkInterface adapter)
        {
            UnicastIPAddressInformationCollection addresses = adapter.GetIPProperties().UnicastAddresses;
            var ipAddressInformation = addresses.FirstOrDefault(x => x.Address.AddressFamily == AddressFamily.InterNetwork);
            if (ipAddressInformation == null)
            {
                return null;
            }

            return ipAddressInformation.Address.ToString();
        }

        public string GetSubnetMask(NetworkInterface adapter)
        {
            var query =
                from properties in adapter.GetIPProperties().UnicastAddresses
                where properties.Address.AddressFamily == AddressFamily.InterNetwork && properties.IPv4Mask != null
                select properties.IPv4Mask;

            var firstOrDefault = query.FirstOrDefault();
            return firstOrDefault != null ? firstOrDefault.ToString() : "";
        }

        /// The Default Gateway's IP address as a string. 
        public string GetDefaultGateway(NetworkInterface adapter)
        {
            var defaultGateway =
            from props in adapter.GetIPProperties().GatewayAddresses
            select props.Address.ToString();

            return defaultGateway.First();
        }

        public void GetDnsAddresses(NetworkInterface adapter, out string dnsServer, out string alternative)
        {
            dnsServer = "";
            alternative = "";

            var dnsServers = adapter.GetIPProperties().DnsAddresses;

            if (dnsServers.Count <= 0) return;

            dnsServer = dnsServers[0].ToString();

            if (dnsServers.Count == 2)
            {
                alternative = dnsServers[1].ToString();
            }
        }

        public void SetEthernetInformation(Adapter adapter)
        {
            var commands = new List<string>
            {
                String.Format("netsh interface set interface name=\"{0}\" admin=enabled", adapter.AdaptorName),
                String.Format("netsh interface ip set address \"{0}\" static {1} {2} {3} 1", adapter.AdaptorName,
                    adapter.Ip, adapter.Subnet, adapter.Getway),
                String.Format("netsh interface ipv4 delete dnsservers \"{0}\" all", adapter.AdaptorName)
            };
            if (!String.IsNullOrEmpty(adapter.DnsServer))
            {
                commands.Add(String.Format("netsh interface ipv4 add dnsserver \"{0}\" address={1}", adapter.AdaptorName, adapter.DnsServer));
            }
            if (!String.IsNullOrEmpty(adapter.AlternativeDns))
            {
                
                commands.Add(String.Format("netsh interface ipv4 add dnsserver \"{0}\" address={1} index=2", adapter.AdaptorName, adapter.AlternativeDns));
            }
            Execute(commands);
        }

        public bool IsEqual(Adapter currentAdapter, Adapter baseAdapter)
        {
            return currentAdapter.Ip == baseAdapter.Ip
                   && currentAdapter.Subnet == baseAdapter.Subnet
                   && currentAdapter.Getway == baseAdapter.Getway
                   && currentAdapter.DnsServer == baseAdapter.DnsServer
                   && currentAdapter.AlternativeDns == baseAdapter.AlternativeDns;
        }

        public void Execute(List<string> commands)
        {
            var p = new Process();
            var info = new ProcessStartInfo
            {
                FileName = "cmd.exe",
                WindowStyle = ProcessWindowStyle.Hidden,
                RedirectStandardInput = true,
                UseShellExecute = false
            };

            p.StartInfo = info;
            p.Start();

            using (StreamWriter sw = p.StandardInput)
            {
                foreach (var command in commands)
                {
                    if (sw.BaseStream.CanWrite)
                    {
                        sw.WriteLine(command);
                    }
                }
            }
        }
    }
}


نمونه‌ای از فایل پیکربندی (کانفیگ) برنامه

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="EthernetName" value="Ethernet" />
    <add key="IP" value="192.168.1.2" />
    <add key="SubnetMask" value="255.255.255.0" />
    <add key="DefaultGetway" value="192.168.1.1" />
    <add key="DnsServer" value="8.8.8.8" />
    <add key="AlterNativeDnsServer" value="8.8.4.4" />
  </appSettings>
</configuration>


دریافت سورس کامل برنامه