C#——Dictionary<TKey, TValue> 計算向量的餘弦值

[0]發表於2015-01-03

說明:三角函式的餘弦值Cos我想,每個學計算機的理工人都知道,但是真的明白它的用途,我也是剛明白。每個人在初中或者高中的時候,都有這麼個疑惑,學三角函式幹什麼用的?很直白的答案就是考試用的。而且當時的老師只管教,只管怎麼解題,至於將學習的知識運用到生活中,沒有這門課堂。最終的結果卻是,我們只知道學,不知道用。說來也慚愧啊,我也是看了吳軍博士的《數學之美》,才領悟到的。這本書真的給我很多的啟發。

Cos的用途:

  1. 考試用。
  2. 通過計算2個向量,可以知道他們的相似度。餘弦值越小,則2個向量越垂直,餘弦值越接近1,則這個向量就越平行(相似)。這樣,我們就可以將向量抽象為事物的特徵集合了。計算向量的餘弦值,就可以判斷事物的相似度。至於詳細的運用領域,還是讀讀這本書吧。

程式碼中的Cosine.cs是我很早從網上搜到的,地址也忘了。

計算程式碼如下:

Cosine.cs類

 

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

namespace ConsoleApplication1
{
    class Cosine
    {
        /// <summary>
        /// 計算向量餘弦值
        /// </summary>
        /// <param name="vector1"></param>
        /// <param name="vector2"></param>
        public static double Calculate(Dictionary<int, double> vector1, Dictionary<int, double> vector2)
        {
            double dotProduct = CalcDotProduct(vector1, vector2);
            double length1 = CalcLength(vector1);
            double length2 = CalcLength(vector2);
            double cosine = dotProduct / (length1 * length2);
            return cosine;
        }
        /// <summary>
        /// 計算向量長度(vector length)
        /// </summary>
        /// <param name="vector"></param>
        /// <returns></returns>
        private static double CalcLength(Dictionary<int, double> vector)
        {
            double length = 0;
            foreach (KeyValuePair<int, double> kvp in vector)
            {
                length += Math.Pow(kvp.Value, 2);
            }
            return Math.Sqrt(length);
        }

        /// <summary>
        /// 計算向量點積(dot product)/內積(inner product)
        /// </summary>
        /// <param name="vector1"></param>
        /// <param name="vector2"></param>
        /// <returns></returns>
        private static double CalcDotProduct(Dictionary<int, double> vector1, Dictionary<int, double> vector2)
        {
            double dotProduct = 0;
            foreach (KeyValuePair<int, double> kvp in vector1)
            {
                if (vector2.ContainsKey(kvp.Key))
                {
                    dotProduct += kvp.Value * vector2[kvp.Key];
                }
            }
            return dotProduct;
        }
    }
}

 

Program類,是我的,嘿嘿。

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

namespace ConsoleApplication1
{
    class Program
    {
        //自定義輸入函式
        static void FunInput(Dictionary<int, double> Vector, int num)
        {
            for (int i = 0; i < num; i++)
            {
                Vector.Add(i, double.Parse(Console.ReadLine()));
            }
        }

        //自定義輸出函式
        static void FunOutput(Dictionary<int, double> Vector)
        {
            //使用KeyValuePair輸出
            foreach (KeyValuePair<int, double> number in Vector)
            {
                Console.WriteLine("{0}---{1}", number.Key, number.Value);
            }
        }

        static void Main(string[] args)
        {
            Dictionary<int, double> Vector1 = new Dictionary<int,double>();
            Dictionary<int, double> Vector2 = new Dictionary<int,double>();

            Console.WriteLine("這2個向量的維度數必須相同,請輸入維度數值:");
            int num = int.Parse(Console.ReadLine());//字串轉化為整形

            Console.WriteLine("請輸入Vector1向量的{0}個數值(每行一個):",num);
            FunInput(Vector1, num);
            //FunOutput(Vector1);

            Console.WriteLine("請輸入Vector2向量的{0}個數值(每行一個):", num);
            FunInput(Vector2, num);
            //FunOutput(Vector2);
            Console.WriteLine("Vector1和Vector2的餘弦值是:{0}",Cosine.Calculate(Vector1,Vector2));            
        }
    }
}

 

相關文章