Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> C++

द्विदिश खोज?

एक द्विदिशात्मक खोज एक खोज तकनीक है जो दो तरह से चलती है। यह उन दो लोगों के साथ काम करता है जो एक साथ चलने वाली खोज करते हैं, पहला स्रोत से लक्ष्य तक और दूसरा लक्ष्य से स्रोत तक पिछड़ी दिशा में। इष्टतम स्थिति में, दोनों खोजें डेटा संरचना के बीच में मिलेंगी।

द्विदिश खोज एल्गोरिथ्म स्रोत (प्रारंभिक नोड) के बीच लक्ष्य नोड के बीच सबसे छोटा रास्ता खोजने के लिए एक निर्देशित ग्राफ पर काम करता है। दो खोजें अपने-अपने स्थानों से शुरू होंगी और जब दो खोजें एक नोड पर मिलती हैं तो एल्गोरिथम रुक जाता है।

द्विपक्षीय दृष्टिकोण का महत्व - यह एक तेज़ तकनीक है, और ग्राफ़ को पार करने के लिए आवश्यक समय में सुधार करती है।

यह दृष्टिकोण उस मामले के लिए कुशल है जब शुरुआती नोड और लक्ष्य नोड अद्वितीय और परिभाषित होते हैं। दोनों दिशाओं के लिए शाखाकरण कारक समान है।

प्रदर्शन के उपाय

  • पूर्णता − यदि दोनों खोजों में BFS का उपयोग किया जाता है, तो द्विदिश खोज पूर्ण हो जाती है।

  • इष्टतमता - यह इष्टतम है यदि BFS का उपयोग खोज के लिए किया जाता है और पथों की लागत एक समान होती है।

  • समय और स्थान की जटिलता − समय और स्थान की जटिलता O(b^{d/2}) . है

उदाहरण

#include <bits/stdc++.h>
using namespace std;
class Graph {
   int V;
   list<int> *adj;
   public:
      Graph(int V);
      int isIntersecting(bool *s_visited, bool *t_visited);
      void addEdge(int u, int v);
      void printPath(int *s_parent, int *t_parent, int s,
      int t, int intersectNode);
      void BFS(list<int> *queue, bool *visited, int *parent);
      int biDirSearch(int s, int t);
};
Graph::Graph(int V) {
   this->V = V;
   adj = new list<int>[V];
};
void Graph::addEdge(int u, int v) {
   this->adj[u].push_back(v);
   this->adj[v].push_back(u);
};
void Graph::BFS(list<int> *queue, bool *visited,
int *parent) {
   int current = queue->front();
   queue->pop_front();
   list<int>::iterator i;
   for (i=adj[current].begin();i != adj[current].end();i++) {
      if (!visited[*i]) {
         parent[*i] = current;
         visited[*i] = true;
         queue->push_back(*i);
      }
   }
};
int Graph::isIntersecting(bool *s_visited, bool *t_visited) {
   int intersectNode = -1;
   for(int i=0;i<V;i++) {
      if(s_visited[i] && t_visited[i])
         return i;
   }
   return -1;
};
void Graph::printPath(int *s_parent, int *t_parent,
int s, int t, int intersectNode) {
   vector<int> path;
   path.push_back(intersectNode);
   int i = intersectNode;
   while (i != s) {
      path.push_back(s_parent[i]);
      i = s_parent[i];
   }
   reverse(path.begin(), path.end());
   i = intersectNode;
   while(i != t) {
      path.push_back(t_parent[i]);
      i = t_parent[i];
   }
   vector<int>::iterator it;
   cout<<"Path Traversed by the algorithm\n";
   for(it = path.begin();it != path.end();it++)
      cout<<*it<<" ";
      cout<<"\n";
};
int Graph::biDirSearch(int s, int t) {
   bool s_visited[V], t_visited[V];
   int s_parent[V], t_parent[V];
   list<int> s_queue, t_queue;
   int intersectNode = -1;
   for(int i=0; i<V; i++) {
      s_visited[i] = false;
      t_visited[i] = false;
   }
   s_queue.push_back(s);
   s_visited[s] = true;
   s_parent[s]=-1;
   t_queue.push_back(t);
   t_visited[t] = true;
   t_parent[t] = -1;
   while (!s_queue.empty() && !t_queue.empty()) {
      BFS(&s_queue, s_visited, s_parent);
      BFS(&t_queue, t_visited, t_parent);
      intersectNode = isIntersecting(s_visited, t_visited);
      if(intersectNode != -1) {
         cout << "Path exist between " << s << " and "
         << t << "\n";
         cout << "Intersection at: " << intersectNode << "\n";
         printPath(s_parent, t_parent, s, t, intersectNode);
         exit(0);
      }
   }
   return -1;
}
int main() {
   int n=15;
   int s=0;
   int t=14;
   Graph g(n);
   g.addEdge(0, 4);
   g.addEdge(1, 4);
   g.addEdge(2, 5);
   g.addEdge(3, 5);
   g.addEdge(4, 6);
   g.addEdge(5, 6);
   g.addEdge(6, 7);
   g.addEdge(7, 8);
   g.addEdge(8, 9);
   g.addEdge(8, 10);
   g.addEdge(9, 11);
   g.addEdge(9, 12);
   g.addEdge(10, 13);
   g.addEdge(10, 14);
   if (g.biDirSearch(s, t) == -1)
      cout << "Path don't exist between "
      << s << " and " << t << "\n";
   return 0;
}

आउटपुट

Path Traversed by the algorithm
0 4 6 7 8 10 14

  1. इष्टतम बाइनरी सर्च ट्री

    पूर्णांकों का एक सेट क्रमबद्ध क्रम में दिया गया है और एक अन्य सरणी freq आवृत्ति गणना के लिए दिया गया है। हमारा काम सभी खोजों के लिए न्यूनतम लागत खोजने के लिए उन डेटा के साथ एक बाइनरी सर्च ट्री बनाना है। उप-समस्याओं के समाधान को हल करने और संग्रहीत करने के लिए एक सहायक सरणी लागत [एन, एन] बनाई गई है।

  1. डेटा संरचनाओं में इष्टतम बाइनरी सर्च ट्री

    पूर्णांकों का एक सेट क्रमबद्ध क्रम में दिया जाता है और आवृत्ति गणना के लिए एक और सरणी फ़्रीक दिया जाता है। हमारा काम सभी खोजों के लिए न्यूनतम लागत खोजने के लिए उन डेटा के साथ एक बाइनरी सर्च ट्री बनाना है। उप समस्याओं के समाधान को हल करने और संग्रहीत करने के लिए एक सहायक सरणी लागत [एन, एन] बनाई गई ह

  1. सी # में बाइनरी सर्च

    द्विआधारी खोज क्रमबद्ध सरणी पर कार्य करता है। मान की तुलना सरणी के मध्य तत्व से की जाती है। यदि समानता नहीं मिलती है, तो आधा भाग समाप्त हो जाता है जिसमें मूल्य नहीं होता है। इसी तरह दूसरे आधे हिस्से की तलाशी ली जाती है। यहाँ हमारे सरणी में मध्य तत्व है। मान लीजिए कि हमें 62 खोजने की जरूरत है, फिर ब