プログラムはすべての可能な順列を生成し、その順列が有効かどうかをテストします。テスト自体にネストされたループが含まれます。 Photonが示唆しているように、データ構造を最適化してチェックが効率的になるようにするか、早い段階で検索スペース内の行き詰まりを見つけることができます。
、より効率的なアプローチは、唯一の有効な順列がcreated.Thisになるようにプログラムを設計することであるかもしれない探索空間を減少させ、テストを取り除きます。
あなたは問題記述の例を見ると、wrieネットワークは非循環グラフである:
5
|
1 6
| |
0---2---7
| |
3 8
|
4
あなたはツール0から始まり、スロット0に入れた場合は、次のステップを配置することですツール2およびその「子孫」、すなわちツール1,7および3とそのそれぞれに接続されたツールとの順列が含まれる。ツール0の観点から、これをツリーにすることができます:
[1237]
// | \
1 2 [34] [678]
/| | \ \
3 4 [56] 7 8
| \
5 6
ここで、葉はただ1つのツールに対応しています。支店にはいくつかのツールがあります。支店のすべての切取りは、有効な手配を形成する。もちろん
0 (1 2 (3 4) ((5 6) 7 8))
、[56]
のすべての順列は、他のブランチの全ての順列と組み合わせなければなりません。あなたは、各宇宙で0から9までの数字を通らない種類のオドメーターを実装することによって達成することができますが、枝の可能な順列を通して。
生成されたすべての順列は有効ですが、この手法ではすべての順列がまだ作成されていません。スロット0には工具0が固定されていますが、そうである必要はありません。しかし、有効なレイアウトのトポグラフィを使用して、それを回転させてツール0をスロット1,2に配置するなどして、8つのレイアウトを生成することができます。
この手法では、検索スペースを9から減らすことができます。 〜9· 4! · 2! · 3! · 2!または70倍になります。テストはありませんが、より複雑なデータ構造を犠牲にしています。
(還元が分岐せずに、ワイヤのネットワークはIR本当にただ一直線あなたの12のツールの例に極端である。)
このコードが記載された技術を実装:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
enum {
N = 16 // hardcoded max. size
};
struct tool {
int conn[N - 1]; // wire connections
int nconn;
int desc[N]; // "descendants" of the tree node
int ndesc;
int cost[N]; // row of the cost matrix
int used; // flag for recursive descent
};
struct drill {
int n;
struct tool tool[N];
int root; // root node
int branch[N]; // indices of branch nodes
int nbranch; // permutating branches
int opt; // current optimum
};
void swap(int a[], int i, int j)
{
int s = a[i]; a[i] = a[j]; a[j] = s;
}
void reverse(int a[], int i, int n)
{
while (i < --n) swap(a, i++, n);
}
/*
* Turn an array to the next higher permutation. When the
* permutation is already the highest, return 0 and reset the
* array to the smalles permutation. Otherwise, return 1.
*/
int next_perm(int a[], int n)
{
int i = n - 1;
int k = n - 1;
if (n < 2) return 0;
while (k && a[k] < a[k - 1]) k--;
if (k == 0) {
reverse(a, 0, n);
return 0;
}
k--;
while (i > k && a[i] < a[k]) i--;
swap(a, i, k);
reverse(a, k + 1, n);
return 1;
}
/*
* Insertion sort for sorting the branches at the beginning.
*/
void sort(int a[], int len)
{
for (int i = 1; i < len; i++) {
int k = i;
while (k > 0 && a[k] < a[k - 1]) {
swap(a, k, k - 1);
k--;
}
}
}
/*
* Determine the list of descendants for each node.
*/
void descend(struct drill *dr, int n)
{
struct tool *t = dr->tool + n;
t->ndesc = 1;
t->desc[0] = n;
t->used = 1;
for (int i = 0; i < t->nconn; i++) {
int m = t->conn[i];
if (dr->tool[m].used == 0) {
t->desc[t->ndesc++] = m;
descend(dr, m);
}
}
if (t->ndesc > 1) {
sort(t->desc, t->ndesc);
dr->branch[dr->nbranch++] = n;
}
t->used = 0;
}
/*
* Fill the array a with the current arrangement in the tree.
*/
int evaluate(struct drill *dr, int a[], int n)
{
struct tool *t = dr->tool + n;
int m = 0;
if (n == dr->root) {
a[0] = dr->root;
return 1 + evaluate(dr, a + 1, dr->tool[n].conn[0]);
}
for (int i = 0; i < t->ndesc; i++) {
int d = t->desc[i];
if (d == n) {
a[m++] = d;
} else {
m += evaluate(dr, a + m, d);
}
}
return m;
}
/*
* Evaluate all possible permutations and find the optimum.
*/
void optimize(struct drill *dr)
{
dr->opt = (1u << 31) - 1;
for (;;) {
int i = 0;
struct tool *t = dr->tool + dr->branch[0];
for (int j = 0; j < dr->n; j++) {
int a[2 * N];
int cost = 0;
evaluate(dr, a, dr->root);
for (int i = 0; i < dr->n; i++) {
int k = (i + j) % dr->n;
cost += dr->tool[i].cost[a[k]];
}
if (cost < dr->opt) dr->opt = cost;
}
while (next_perm(t->desc, t->ndesc) == 0) {
i++;
if (i == dr->nbranch) return;
t = dr->tool + dr->branch[i];
}
}
}
/*
* Read and prepare drill data, then optimize.
*/
int main(void)
{
struct drill dr = {0};
fscanf(stdin, "%d", &dr.n);
for (int j = 0; j < dr.n; j++) {
for (int i = 0; i < dr.n; i++) {
scanf("%d", &dr.tool[j].cost[i]);
}
}
for (int i = 1; i < dr.n; i++) {
int a, b;
scanf("%d", &a);
scanf("%d", &b);
dr.tool[a].conn[dr.tool[a].nconn++] = b;
dr.tool[b].conn[dr.tool[b].nconn++] = a;
}
while (dr.tool[dr.root].nconn > 1) dr.root++;
dr.tool[dr.root].used = 1;
descend(&dr, dr.tool[dr.root].conn[0]);
optimize(&dr);
printf("%d\n", dr.opt);
return 0;
}
を記載してくださいあなたの問題はテキストではなく、画像と(リンクを介して) – wildplasser
あなたはすべて12を作成します!順列、これはすでにたくさんある。次に、各並べ替えの設定が最初から可能かどうかをテストします。最初から有効な順列のみを訪問するようにアルゴリズムを設計して、評価の数を減らしてテストを保存する必要があります。 –