質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

保存

保存(save)とは、特定のファイルを、ハードディスク等の外部記憶装置に記録する行為を指します。

Q&A

解決済

2回答

1492閲覧

組み合わせをチェックするプログラム

reina1125

総合スコア21

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

保存

保存(save)とは、特定のファイルを、ハードディスク等の外部記憶装置に記録する行為を指します。

0グッド

0クリップ

投稿2020/07/30 03:29

編集2020/08/03 07:46

全列挙した組み合わせから特定の組み合わせを除去して、残りの組み合わせを全列挙する方法があれば教えていただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yureighost

2020/07/30 06:01

支配関係が例で挙げられているようなわかりやすいパターンなら問題ないのですが、 実際には列挙されているパターンは会社と優先度が重ならないようになっているように見受けられます。 例えば、 3レコード目、A社1位、B社2位、C社2位。 6レコード目、A社2位、B社1位、C社2位。 7レコード目、A社2位、B社2位、C社1位。 はいずれもA、B、C社が3つ列挙されているパターンですが、 3レコード目のA社1位に対して、6、7レコード目はA社は2位ですが、 代わりにB、C社が1位になっていて優先度が高くなっています。 この3レコードは支配関係にあると言えるのでしょうか。
reina1125

2020/07/30 06:17

yureighostさん ご質問ありがとうございます。 A社、B社、C社間の優先順位を考慮していないので、その場合は支配関係にないと判断してそれぞれ出力する形となります。 また、下記のような場合も「A社1位」と「A社の2位+3位」の優先順位が分からないので、この場合も支配関係にないと判断します。 A社1位、B社2位、C社2位 A社2位、A社3位、B社2位、C社2位 私の例の作り方が分かりにくくて申し訳ありません。表の数値を変えても正しく動くようにしたいと考えています。 よろしくお願いいたします。
thkim0111

2020/07/30 07:31

コードを見て疑問に思ったのですが、プロジェクトが2つの組み合わせは考慮しなくていいのですか? 表の数値を変えたときに {1,1,0,0}{0,0,1,1} のようなパターンがあればプロジェクト2つの組み合わせも成り立つような気もするのですが。。
reina1125

2020/07/30 07:41

thkim0111さん 数字を変えたパターンで考えていなかったので、見落としていました。 今、プロジェクト2つの場合も追加しました。 ご指摘ありがとうございます。
reina1125

2020/07/30 07:48

例題を変更しました。 3レコード目、A社1位、B社2位、C社2位 5レコード目、A社2位、B社3位、C社2位 において、3レコード目は1レコード目に支配されているということになります。 3レコード目、A社1位、B社2位、C社2位 9レコード目、A社3位、B社2位、C社2位、C社3位 においては、A社とB社は1レコード目に支配されていますが、 「C社の2位」と「C社の2位+3位」の優先順位が不明なので支配関係にないと判断して出力します。
yureighost

2020/07/30 07:57

この前提だと現在の列挙を書き出すプログラムが プロジェクト二つで成り立つパターンが考慮されていないので割り出せませんね。 まずそこから直す必要があるようです。 それと私も前の例題で挙がられてるパターンのみだと思っていました。 情報を小出しにされると前に回答された方の作業が全て無駄になってしまうので、 考え得る限りの情報を出すようにお願いします。
reina1125

2020/07/30 08:03 編集

yureighostさん プロジェクト二つで成り立つパターンを考慮するプログラムを追加しました。 申し訳ありませんでした。
xebme

2020/08/02 02:38 編集

static int ProjectB[][] = { { 1, 0, 1, 0 }, { 0, 0, 1, 0 }, { 1, 0, 0, 0 } }; b1 = 0x1010 b2 = 0x0010 b3 = 0x1000 ~b1 & b2 = 0 b1がb2を支配 ~b1 & b3 = 0 b1がb3を支配 ~b2 & b3 != 0 b2はb3を支配しない こういうことなら、初めからb2,b3を除外して組み合わせを検討すれば良い (&と|は間違いやすいので要注意です)^でもよかった。
guest

回答2

0

ベストアンサー

質問例の組み合わせ数が変わるパターンだとその都度似た処理をコピーしなければならず効率が悪いので、一覧を作る部分から作り直しました。
ただビット演算を使う方が楽なためint配列をString文字列に置き換えて処理しています。
外部からint配列で引数が渡されるとかいう場合、String文字列に置き換える処理を入れて下さい。

支配関係の除外は現在の処理の場合、
高ランクから順番にしているため、必然的に下位ランクが後になるので、
新しく追加する物が既に一覧にある物の下位になるかどうかをチェックして
一覧に加えない方式で処理しています。

java

1import java.util.ArrayList; 2import java.util.Arrays; 3import java.util.List; 4import java.util.stream.IntStream; 5 6public class NNN { 7 8 static String projectA[] = { "1100", "1010", "0100" }; 9 static String projectB[] = { "1010", "0010", "0100" }; 10 static String projectC[] = { "0101", "0001", "1000" }; 11 12 static String projectALL[][] = { projectA, projectB, projectC }; 13 static String projectList[] = Arrays.stream(projectALL).flatMap(pl -> Arrays.stream(pl)).toArray(String[]::new); 14 15 static int rProjectBin = Integer.parseInt("1111", 2); 16 17 static String company[] = { "A社", "B社", "C社" }; 18 19 public static void main(String[] args) { 20 List<String> indexStrList = createIndexStrList(); 21 sysoutResult(indexStrList); 22 } 23 24 public static List<String> createIndexStrList() { 25 List<String> indexStrList = new ArrayList<>(); 26 for (int i = 0; i < projectList.length; i++) { 27 String result = setIndexStrList(indexStrList, projectList[i], String.valueOf(i), i + 1); 28 excludeDominance(indexStrList, result); 29 } 30 return indexStrList; 31 } 32 33 public static String setIndexStrList(List<String> indexStrList, String pProject, String indexStr, int idx) { 34 int pBin = Integer.parseInt(pProject, 2); 35 for (int i = idx; i < projectList.length; i++) { 36 int cBin = Integer.parseInt(projectList[i], 2); 37 // ビット演算xor 38 int rBin = pBin ^ cBin; 39 // ビット演算xorの結果にandで演算を行い、適用ビットと同じ値であれば適用された(0から1に変わった)ことになる 40 if ((rBin & cBin) == cBin) { 41 String addStr = indexStr + "," + i; 42 // 演算結果が"1111"と同じ場合、結果を返す 43 if (rBin == rProjectBin) { 44 return addStr; 45 } else { 46 // 演算結果が"1111"でない場合、再帰で自己メソッドを呼び出す 47 String result = setIndexStrList(indexStrList, Integer.toBinaryString(rBin), addStr, i); 48 excludeDominance(indexStrList, result); 49 } 50 } 51 } 52 return null; 53 } 54 55 public static void excludeDominance(List<String> indexStrList, String addIndexStr) { 56 // 支配関係にあるプロジェクトを除外する 57 if (addIndexStr == null) { 58 return; 59 } 60 if (indexStrList.isEmpty()) { 61 indexStrList.add(addIndexStr); 62 return; 63 } 64 String[] addIndexesStr = addIndexStr.split(","); 65 // 会社数以上プロジェクトがある場合、複数の同じ会社が指定されているので支配関係不明としてチェックしない 66 if (addIndexesStr.length > projectALL.length) { 67 indexStrList.add(addIndexStr); 68 return; 69 } 70 int[][] indexes = convertIndexesStr(addIndexesStr); 71 // プロジェクトで会社の重複がある場合、複数の同じ会社が指定されているので支配関係不明としてチェックしない 72 if (doubleCheck(indexes, -1)) { 73 indexStrList.add(addIndexStr); 74 return; 75 } 76 for (String listIndexStr : indexStrList) { 77 String[] listIndexesStr = listIndexStr.split(","); 78 int[][] listIndexes = convertIndexesStr(listIndexesStr); 79 // 会社の数が同じ場合 80 if (indexes.length == listIndexes.length) { 81 boolean[][] bolLen = new boolean[indexes.length][2]; 82 for (int i = 0; i < indexes.length; i++) { 83 // 会社が同じ場合 84 if (indexes[i][0] == listIndexes[i][0]) { 85 bolLen[i][0] = true; 86 } 87 // 加えようとしている会社のランクIndexが既に一覧にある会社のランクIndex以上(ランク下位)の場合 88 if (indexes[i][1] >= listIndexes[i][1]) { 89 bolLen[i][1] = true; 90 } 91 } 92 // 会社数によりチェック用の配列を作成 93 boolean[][] chkBol = IntStream.range(0, indexes.length) 94 .mapToObj(i -> new boolean[] {true, true}).toArray(boolean[][]::new); 95 // チェック結果が全てtrue(会社の組み合わせが同じで、ランク下位以下)の場合 96 if (Arrays.deepEquals(bolLen, chkBol)) { 97 // リストに加えず処理を終了(除外扱い) 98 return; 99 } 100 } 101 } 102 indexStrList.add(addIndexStr); 103 } 104 105 public static boolean dominanceCheck(List<String> indexStrList, String indexStr) { 106 // 支配関係のチェックを行う 107 String[] indexesStr = indexStr.split(","); 108 // 会社数以上プロジェクトがある場合、複数の同じ会社が指定されているので支配関係不明としてチェックしない 109 if (indexesStr.length > projectALL.length) { 110 indexStrList.add(indexStr); 111 return false; 112 } 113 int[][] indexes = convertIndexesStr(indexesStr); 114 // プロジェクトで会社の重複がある場合、複数の同じ会社が指定されているので支配関係不明としてチェックしない 115 if (doubleCheck(indexes, -1)) { 116 indexStrList.add(indexStr); 117 return false; 118 } 119 return true; 120 } 121 122 public static boolean doubleCheck(int[][] indexes, int argConpanyIdx) { 123 // 一社で複数のプロジェクトがあるかどうかチェックする 124 for (int[] indexe : indexes) { 125 int conpanyIdx = indexe[0]; 126 boolean result = conpanyIdx == argConpanyIdx; 127 if (!result) { 128 return result; 129 } 130 return doubleCheck(indexes, conpanyIdx); 131 } 132 return false; 133 } 134 135 public static int[][] convertIndexesStr(String[] indexesStr) { 136 // 会社名とランクをIndexに置き換え、会社が複数ある場合まとめる 137 int[][] indexes = new int[indexesStr.length][2]; 138 for (int i = 0; i < indexesStr.length; i++) { 139 String[] idxs = indexesStr[i].split(","); 140 for (String index : idxs) { 141 int projectSize = 0; 142 for (int j = 0; j < projectALL.length; j++) { 143 String[] projects = projectALL[j]; 144 for (int k = 0; k < projects.length; k++) { 145 if (Integer.parseInt(index) == projectSize + k) { 146 indexes[i] = new int[] {j, k}; 147 } 148 } 149 projectSize += projects.length; 150 } 151 } 152 } 153 return indexes; 154 } 155 156 private static void sysoutResult(List<String> indexStrList) { 157 // 結果をコンソールに出力する 158 for (String indexStr : indexStrList) { 159 System.out.println("-------------------------"); 160 String[] indexes = indexStr.split(","); 161 for (String index : indexes) { 162 int projectSize = 0; 163 for (int i = 0; i < projectALL.length; i++) { 164 String[] projects = projectALL[i]; 165 for (int j = 0; j < projects.length; j++) { 166 if (Integer.parseInt(index) == projectSize + j) { 167 System.out.println( 168 company[i] + "の" + (j + 1) + "位のプロジェクト=1"); 169 } 170 } 171 projectSize += projects.length; 172 } 173 } 174 } 175 } 176}

投稿2020/08/03 01:03

編集2020/08/03 01:08
yureighost

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

reina1125

2020/08/03 03:04

yureighost さん できました!本当にありがとうございます!!(ToT)
guest

0

やりたいことは、以下の通りで実現できると思います

私が現状考えている方法としては下記です。

①配列を用意してそこに最初の解の順位を保存
②以降、既存の解と新規の解との順位を比較
----支配関係がある場合 ==>支配されている解を消去、新たな解を保存
----支配関係がない場合 ==>新たな解として保存
③保存されている解を出力

支配関係のチェックは、正直コメントのやりとり見てもあまりわからなかったので
サンプルをうまく修正してくれればと思います。

考え方だけ。

プロジェクトと順位を一意の文字列に変換します。
変換ルール
先頭1文字目は、成り立つプロジェクトの数
2文字目、Aプロジェクトの順位
3文字目、Bプロジェクトの順位
4文字目、Cプロジェクトの順位
※順位は1位:4点、2位:2点、3位:1点の合計

変換した文字列の各桁を見て、どちらか一方にのみ支配関係があれば、そのどちらか
なければないというのを表す関数を作ります。
※ここの評価方法がよくわからないので、直してください。

先頭1文字が一致しない場合、どちらも支配関係にない。
2文字目以降
第一引数(left)が大きい場合、isLeftをtrueに、第二引数が大きい場合、isRightをtrueに
最終的にどちらか”だけ”フラグがたっていたら、そのフラグに準じた値を返却

java

1/* 2 * PRJ評価文字列を作成 3 * 各PRJの評価をABCの順に連結した文字列を返す。 4 */ 5private static String toHyoukaStr(int... prjs) { 6 int[] company = { 0, 0, 0 }; // {A社, B社, C社} 7 int[] rank = { 4, 2, 1 }; // 順位の重みづけ 2位、3位の合計より1位を大きく 8 9 for (int i = 0; i < prjs.length; i++) { 10 company[prjs[i] / 3] += rank[prjs[i] % 3]; 11 } 12 13 // int配列を文字列に変換{1,2,3} -> "123" 14 String ret = "" + prjs.length + java.util.Arrays.stream(company).mapToObj(Integer::toString).collect(Collectors.joining()); 15 return ret; 16} 17 18/* 19 * 支配されているかのチェック. 20 * 21 * @left 評価するprj順位文字列 22 * @right 評価するprj順位文字列 23 * @return 0 支配関係にない 24 * 0より大きい left が right を支配している 25 * 0より小さい left が right に支配されている 26 */ 27private static int controlTo(String left, String right) { 28 // 構成するプロジェクトの数が違う場合 29 if(left.charAt(0) != right.charAt(0)) { 30 return 0; 31 } 32 33 boolean isLeft = false; 34 boolean isRight = false; 35 // 先頭からプロジェクトごとの順位を確認 36 for (int i = 0; i < left.length(); i++) { 37 if (left.charAt(i) > right.charAt(i)) { 38 isLeft = true; 39 } else if (left.charAt(i) < right.charAt(i)) { 40 isRight = true; 41 } else { 42 // same 43 } 44 } 45 46 if (isLeft ^ isRight) { 47 if (isLeft) { 48 return 1; // left が right を支配している 49 } else { 50 return -1; // right が left を支配している 51 } 52 } 53 54 // 支配関係にない 55 return 0; 56} 57

使い方

例えば(1){A社1位,B社1,C社1位}と(2){A社2位,B社1位,C社1位}の組み合わせがあった場合、

B社,C社の順位は同じ1位ですが、A社に関しては(1)が1位,(2)が2位なので
(2)の組み合わせは(1)の組み合わせに含まれている(=支配されている)と言います。

java

1String kakko1 = toHyoukaStr(0, 3, 6); // (1){A社1位,B社1,C社1位} 2String kakko2 = toHyoukaStr(1, 3, 6); // (2){A社2位,B社1位,C社1} 3 4System.out.println("(1)が(2)を支配しているか?" + (controlTo(kakko1, kakko2) > 0)); // true 5

使い方2(配列の場合)

3レコード目、A社1位、B社2位、C社2位

5レコード目、A社2位、B社3位、C社2位
において、3レコード目は1レコード目に支配されているということになります。

※「5レコード目は3レコード目に支配されている」の誤字だと思ってますが・・・

java

1int[] rec3 = {0, 4, 7}; // 3レコード目、A社1位、B社2位、C社2位 2int[] rec5 = {1, 5, 7}; // 5レコード目、A社2位、B社3位、C社2位 3 4System.out.println("3レコード目が5レコード目を支配しているか?" + (controlTo(toHyoukaStr(rec3), toHyoukaStr(rec5)) > 0)); // true 5System.out.println("5レコード目が3レコード目に支配されているか?" + (controlTo(toHyoukaStr(rec5), toHyoukaStr(rec3)) < 0)); // true 6

こんな感じで比較して、ArrayListかなんかに評価文字列か、配列そのものを保存していけばよいかと思います。

が、まずは支配関係のチェックについての単純なif文なので、実装してもらうしかないですね。

投稿2020/07/31 13:30

編集2020/07/31 13:40
momon-ga

総合スコア4820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問